How to retrieve a users contacts and present them in a UITableView? - xcode

Forgive my ignorance, but I'v mainly done game programming and not much Utiliy like apps. What I'm trying to do is Retrieve a Users contacts and present them in a table view on app launch. I'm not a complete noob I know my way around the Address Book API. I'm just unsure how to complete the task of getting the users contacts into my own custom UITableView. Any help is greatly appreciated!

I am not sure how good my response is going to be, because I haven't use the Address Book API, but a little bit of searching + my own knowledge suggest the following:
Create the Address Book
One way to do this (based on my searches) seems to be the following:
ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
...
}
Display the Address Book
Using the code from above, you now need to display it inside your table. I don't know how familiar you are with using UITableView, so I am going to be more verbose than what I probably need. You are going to have populate the following methods of your tableView class:
- (NSInteger)numberOfSections
{
//You can also return 26 here, but you'll need to split your addressBook array, so each section contains the people starting with a single letter of the alphabet
return 1;
}
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [addressBook count];
}
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//do standard cell instantiation
//get the contact at index indexPath.row
//set the cell's textLabel.text to that contact's name (or whatever you want)
}
I don't know how helpful my response was, but if you want me to clarify something (or tell me that I am being silly assuming your problem is so simple), feel free to let me know.

Related

Can't setup bindings in Swift Storyboard?

I've got some code that runs a fairly complex algorithm. I want to put together a fairly simple UI that will allow me to monitor the values of the various variables in the algorithm in some graphical ways -- think of it like a dashboard of sorts.
So, for simplicity's sake, let's say I have an algorithm like what follows. It searches a vector of values for the two values that most closely sum to a target value:
import Foundation
class algorithm {
var numbers = [Double]()
let numberOfRandoms = 1000
dynamic var a: String
dynamic var b: String
init () {
// Load initial vector with some random numbers between 0 and 1
for _ in 1...numberOfRandoms {
numbers.append(Double(arc4random()) / Double(UINT32_MAX))
}
a = " "
b = " "
}
func findTheTwoNumbersThatAddUpTheClosestToTarget(target: Double) {
//Initializing this to a very large value
var currentBestSum = 1000.0
//Begin brute force search for the optimal solution
for i in 0...numbers.count-2 {
for j in i+1...numbers.count-1 {
//Check to see if the current candidate exceeds the best solution
if abs(numbers[i] + numbers[j] - target) < currentBestSum {
//If it does, store the new champion
a = String(i)
b = String(j)
//And reset the current top score to match
currentBestSum = abs(numbers[i] + numbers[j]-target)
}
}
}
}
}
Now, this is just a simple (and silly) example, but it suits these purposes. I basically want to create a simple UI that displays the important values in the process as it runs (dynamically).
In this example, let's say that I just want to display two labels that contain the index values of the two leaders as the algorithm executes.
I created the labels in the storyboard.
Then, I created IBOutlets in the ViewController (Actually, storyboards did it for me when I Ctrl-dragged):
class ViewController: NSViewController {
#IBOutlet weak var a: NSTextField!
#IBOutlet weak var b: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
Then, I ctrl-dragged the labels to the a and b in the algorithm class to create the bindings.
Finally, I create an class variable in the view controller and instantiate it in the viewDidLoad method. This doesn't seem like the right thing to do -- maybe it is. Seems like you would want to keep separate your interface and data...
The labels do, in fact, show up -- but they never show any values of a and b. They just show the default text.
Not sure what I'm doing wrong.
Help!?
P.S., in response to Anthony Kong, I do recognize that I could manually synchronize all the view elements in the code, but I thought the whole point of using bindings was to avoid having to do this manual synchronization. I just can't figure out how to set it up.
Without commenting on your specific code I think I have experienced (and solved) the problem you describe. I was able to write an app that had two targets, one NIB-based and one Storyboard-based. As much as I was able I duplicated the code in each and shared the common data instance that I was trying to display in a TableView. The NIB-based app worked using the stock Cocoa Bindings that I set in IB. But the Storyboard-based app did not, the array controller did not see the data.
My solution was simply to add the binding for contentArray programmatically in viewDidLoad. The one line that fixed it for me is:
ac.bind("contentArray", toObject: cd, withKeyPath: "people", options: nil)
ac is the IBOutlet for the ArrayController in the Storyboard. cd is the class instance that contains the people array.
This is using XCode 6.2 (6C107a) which is Beta 3 I think.
This was the only binding that I had to set myself, the TableView to ArrayController (arrangedObjects) and TableViewCell to TableView (objectValue) didn't need any tweaking.
There are several problems with your code
1) In your code,
func applicationDidFinishLaunching(aNotification: NSNotification?) {
// Insert code here to initialize your application
var test = algorithm()
test.findTheTwoNumbersThatAddUpTheClosestToTarget(0.5)
}
The variable test goes out of scope when the function exits. Based on the wording of your question, you are expecting it to be a long running process. So this will not do what you want.
You should
a) Add test as class variable to the ViewController class
b) instantiate the variable in viewDidLoad method.
2) In your algorithm it does not actually provide any feedback to the labels. Maybe you think because the class has the ivar a and b so they are hooked to the IBOutlet by the same names. But of course it is not the case. And you do not need the keyword dynamic too.
What you should do is:
a) provide a method in the View Controller class to update the labels. It will serve as a callback function to be used by algorithm class to feedback the calculation result.
It may look like this:
func update_value_callback(vala: String, valb: String) {
a.text = vala; // updating the label here
b.text = valb;
}
b) make the algorithm class calls the callback function e.g.
func findTheTwoNumbersThatAddUpTheClosestToTarget(target: Double, viewController: ViewController) {
// do your stuff
...
// execute the callback
viewController.update_value_callback(a, b)
}

ListBox is Not Automatically Expanding with Dynamic Data Adding through 'PhoneTextBox' wp7

I would like to perform something's like fb comment Layout.
and I am Using Following Code To perform this task :
// Constructor
string []content;
public MainPage()
{
InitializeComponent();
content = new string[11] { "Great stories produce the ideas which help children to know how the cleverness and wise decisions take the people out of the dangerous and most tricky situations.",
"No virtue is as noble as kindness. The stories “Prince Frog”, “Dove and the ant” and others teaches them the importance of being kind to even to the small god made creatures of this earth.",
"Honesty is a key to success and honest people are duly rewarded. These stories show honesty is a most beautiful quality to be possessed, liked and appreciated.",
"Humbleness makes us kind hearted and soft spoken- the virtues which will always be deemed and valued in the eyes of the others.",
"Realize the importance of hard work through these evergreen stories. These popular stories are the inroads to the very roots of the concept “Hard work is a road to success.",
"If you speak the truth, your children will speak too. This would help them built the trust and reputation in their society and around them.",
"Courageous child can easily cross each milestones of life with ease, then why not we too help our children to be strong for the others too to follow.",
"True Friendship is a God’s precious gift and a commitment for togetherness, and sharing and caring.",
"Understand the value of being united, to overcome any difficult situation and understand the meaning of working in a team and grow as a virtuous and a strong human being.",
"Obeying the elders will ultimately be good for you. Stories like \"Three goats and the Wolf\" can help your children understand the value of being obedient.",
"Greediness leads to destruction. It causes obsession which is more harmful. Let us know how through these great stories." };
populate_list();
}
private void populate_list()
{
for (int i = 0; i < content.Length; i++)
{
//mainlist.Items.Add(content[i]);
var maintext = new TextBlock();
maintext.Text = content[i];
maintext.TextWrapping = TextWrapping.Wrap;
StackPanel stkpanel = new StackPanel();
stkpanel.Width = 480;
stkpanel.Height = 124;
stkpanel.Children.Add(maintext);
var expander = new ExpanderView();
var phonetextbox = new PhoneTextBox();
phonetextbox.Hint = "Add a Comment";
phonetextbox.ActionIcon = new System.Windows.Media.Imaging.BitmapImage(new Uri("/search.png", UriKind.RelativeOrAbsolute));
StackPanel stkpanel_new = new StackPanel();
stkpanel_new.Width = 480;
phonetextbox.ActionIconTapped += (s, e) =>
{
if (!string.IsNullOrEmpty(phonetextbox.Text))
{
expander.Items.Add(phonetextbox.Text);
expander.IsExpanded = true;
//stkpanel_new.Height = stkpanel_new.Height + 20;
}
};
stkpanel_new.Children.Add(phonetextbox);
stkpanel_new.Children.Add(expander);
mainlist.Items.Add(stkpanel);
mainlist.Items.Add(stkpanel_new);
}
}
But i Got problem on Dynamic Comment insertion when user entered text in phonetextbox and press on its Icon the comment just added behind the listbox 2nd element (means ExpanderView will be expanded but listbox further elements are not adjusting it dynamically ).
Am i Doing Something wrong or it is a Framework limitation ?? Help .
Regards
Pardeep Sharma
for this type of dynamic height I recommend the longlistselector control, which is useful in both orientation and for main container use Grid that will set it self as per content's size because its height is by default "Auto"
Replacing you action handler by this one should fix your problem:
phonetextbox.ActionIconTapped += (s, e) =>
{
if (!string.IsNullOrEmpty(phonetextbox.Text))
{
expander.Items.Add(phonetextbox.Text);
this.Dispatcher.BeginInvoke(() => {
expander.IsExpanded = true;
});
//stkpanel_new.Height = stkpanel_new.Height + 20;
}
};
but you should really look into using mvvm. One of the big downside of your implementation (among a lot of others architectural benefit) is that you are going to lost the benefit of UI virtualisation (A ListBox don't build all the ui element of all the items just the one into view and a little more but since you are creating them all your self you lost that benefit).

How to display Images in a wxListCtrl (multicolumn report style)

I already managed to create wxListCtrls with either icons or multicolumn text like this
Picture of two wxListCtrls
Now I'd like to add an icon to each line of the text list on the left. I thought this should be possible as typical wxWidgets applications like code::blocks and wxSmith often diplay icons in list/tree views (resource browser window) and even in tabs of notebooks (compiler log window).
So how can I create something like this? (Everybody knows Windows Explorer)
Picture of Explorer Window with icons
I tried this...
SetImageList (ToolImages, wxIMAGE_LIST_NORMAL);
InsertColumn (0, "Icon");
SetColumnWidth (0, 40);
...
for (int i=0; i<5; i++)
{
InsertItem (i, i);
SetItemColumnImage (i, 0, i);
SetItem (i, 1, IntToStr (i+1));
...
But as you can see, only the text gets displayd, the image column is blank. Is it possible at all to mix text and images in report mode? If not, what other wxControl class can I use to get the desired result?
Many Thanks in advance.
Yes, it is possible, and the listctrl sample shows how to do it, in particular see MyFrame::InitWithReportItems() function. The only difference with your code seems to be that you use a different InsertItem() overload, so perhaps you should use InsertItem(i, "") instead.
Also check that your image list does have the 5 icons in it.
More generally, trying to reduce the differences between your code and the (working) sample will almost always quickly find the problem.
Thanks, VZ, but I found out that it's not the InsertItem() but the SetImageList(). My image list was correct, but the "which" parameter wasn't. Replacing wxIMAGE_LIST_NORMAL by wxIMAGE_LIST_SMALL fixes the problem! I thought "SMALL" was only meant for the SMALL_ICON mode and that "NORMAL" should be the default. But yes, that makes sense, normal icons are big and don't fit in the text display. Would be nice if the documentation had told us that before long trial and error...
This is a simple example for SMALL ICONIC VIEW USING WXLISTCTRL .Please place this code inside the class declaration.I did it in Frame based Windows Application using CODE BLOCKS.It will be useful to you.
wxImageList *il=new wxImageList(32,32,false,0);
wxImageList *i2=new wxImageList(32,32,false,0);
wxDir dir(wxGetCwd());
wxDir dir1(wxGetCwd());
if ( !dir.IsOpened() )
{
// deal with the error here - wxDir would already log an error message
// explaining the exact reason of the failure
return;
}
if ( !dir1.IsOpened() )
{
// deal with the error here - wxDir would already log an error message
// explaining the exact reason of the failure
return;
}
puts("Enumerating object files in current directory:");
wxString path, filename, dirstring,filename1, dirstring1, img,imgPath,path1,img1,imgPath1;
int i=0;
path=wxT("C:\\testing\\splitterwindow\\set\\devices");
path1=wxT("C:\\testing\\splitterwindow\\set\\actions");
img=wxT("C:\\testing\\splitterwindow\\set\\devices\\");
img1=wxT("C:\\testing\\splitterwindow\\set\\actions\\");
bool cont=dir.Open(path);
bool cont1=dir1.Open(path1);
cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_DEFAULT);
dirstring.Append(filename.c_str());
cont1 = dir1.GetFirst(&filename1, wxEmptyString, wxDIR_DEFAULT);
dirstring1.Append(filename1.c_str());
while ( cont )
{
imgPath.clear();
cont = dir.GetNext(&filename);
dirstring.Append(filename.c_str());
// Consturct the imagepath
imgPath.Append(img.c_str());
imgPath.Append(filename.c_str());
//Now, add the images to the imagelist
il->Add(wxBitmap(wxImage(imgPath.c_str())));
i++;
}
while ( cont1 )
{
imgPath1.clear();
cont1 = dir1.GetNext(&filename1);
dirstring1.Append(filename1.c_str());
// Consturct the imagepath
imgPath1.Append(img1.c_str());
imgPath1.Append(filename1.c_str());
//Now, add the images to the imagelist
i2->Add(wxBitmap(wxImage(imgPath1.c_str())));
i++;
}
//assigning the imagelist to listctrl
ListCtrl1->AssignImageList(il, wxIMAGE_LIST_SMALL);
ListCtrl3->AssignImageList(i2, wxIMAGE_LIST_SMALL);
for(int j=0;j < il->GetImageCount()-1;j++)
{
wxListItem itemCol;
itemCol.SetId(j);
itemCol.SetImage(j);
itemCol.SetAlign(wxLIST_FORMAT_LEFT);
ListCtrl1->InsertItem(itemCol);
}
for(int k=0;k < i2->GetImageCount()-1;k++)
{
wxListItem itemCol1;
itemCol1.SetId(k);
itemCol1.SetImage(k);
itemCol1.SetAlign(wxLIST_FORMAT_LEFT);
ListCtrl3->InsertItem(itemCol1);
}
`

how to implemet database logic in tableview to controll rows information?

My meaning is i want to implement the table from where i will get data from the database.I store all the data into database now the problem is i am not able to show this data in tableView as describe below.Also you can see the example that i want to develop table like chipottle Chipottle app. There is a bag for created order list information.If you do not get my question then please see the chipottle app just create order it will store into bag in main view click on bag button you will see one table with all your created order information and in last subtitle.Please See the app it's totally free i really stuck into this problem so please try to help me.
I stored 10 fields in database
Ordername ={Order1,Order2}
category = {category1,category2}
submenu1 = {{sub00,sub01,sub02},{sub11,sub12}}
price1 = {{$2,$3.1,$4.2},{$7.85,$2.3}}
submenu2 = {{sub21,sub22,sub23,sub24},{sub31,sub32}}
price2 = {{$2.2,$4.5,$7.7,$3.2},{$4.4,$1.3}}
drinkmenu = {pepsi,pepsi1,soda,lemon,pinaplesoda}
dirnkprice = {$4.4,$8.5,$3.7,$2.8,$3.4}
I count the no. of section like = [Ordername count] .also able to display the section title as per the Ordername.
Now i want to display category ,submenu1,price1,submenu2,price2 all at Zero(0) index means (at indexpath.row = 0) all value as per the Ordername.
and for drinkmenu it is display on different different indexpath.row but after at zero index.
Thank You.
Please it is very urgent.
go through following link you will have your work done.
http://blog.webscale.co.in/?p=284
It is customization of UITableViewCell.
Hope it helps.
All you've got to do, is create a special order tableViewCell and put in your data, show it for indexPath.row == 0 only. Here is some example code:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)anIndexPath
{
// sectioning logic here...
if(anIndexPath.row == 0) {
// Helper to create a fresh cell, implements dequeueing
OrderTableViewCell *cell = [TableViewCellFactory orderTableViewCell:aTableView];
// pass on the cell to do fill in data
[self configureOrderCellWithCell:cell andIndexPath:anIndexPath];
return cell;
} else {
// process other cells
}
}
- (void)configureVideoClipCellWithCell:(VideoClipTableViewCell *)aCell andIndexPath:(NSIndexPath *)anIndexPath
{
// get model at current indexPath
Order *order = [orders objectAtIndex:anIndexPath.row];
// publish data in cell
aCell.category.text = order.category;
aCell.submenu1.text = order.submenu1;
aCell.price1.text = order.seprice1rie;
aCell.submenu2.text = order.submenu2;
aCell.price2.text = order.price2;
}

How do I copy or move an NSManagedObject from one context to another?

I have what I assume is a fairly standard setup, with one scratchpad MOC which is never saved (containing a bunch of objects downloaded from the web) and another permanent MOC which persists objects. When the user selects an object from scratchMOC to add to her library, I want to either 1) remove the object from scratchMOC and insert into permanentMOC, or 2) copy the object into permanentMOC. The Core Data FAQ says I can copy an object like this:
NSManagedObjectID *objectID = [managedObject objectID];
NSManagedObject *copy = [context2 objectWithID:objectID];
(In this case, context2 would be permanentMOC.) However, when I do this, the copied object is faulted; the data is initially unresolved. When it does get resolved, later, all of the values are nil; none of the data (attributes or relationships) from the original managedObject are actually copied or referenced. Therefore I can't see any difference between using this objectWithID: method and just inserting an entirely new object into permanentMOC using insertNewObjectForEntityForName:.
I realize I can create a new object in permanentMOC and manually copy each key-value pair from the old object, but I'm not very happy with that solution. (I have a number of different managed objects for which I have this problem, so I don't want to have to write and update copy: methods for all of them as I continue developing.) Is there a better way?
First, having more than one NSManagedObjectContext on a single thread is not a standard configuration. 99% of the time you only need one context and that will solve this situation for you.
Why do you feel you need more than one NSManagedObjectContext?
Update
That is actually one of the few use cases that I have seen where that makes sense. To do this, you need to do a recursive copy of the object from one context to the other. The workflow would be as follows:
Create new object in persistent context
get a dictionary of the attributes from the source object (use -dictionaryWithValuesForKeys and -[NSEntityDescription attributesByName] to do this.
set the dictionary of values onto the target object (using -setValuesForKeysWithDictionary)
If you have relationships, you will need to do this copy recursively and walk the relationships either hard coded (to avoid some circular logic) or by using the -[NSEntityDescription relationshipsByName]
As mentioned by another, you can download the sample code from my book from The Pragmatic Programmers Core Data Book and see one solution to this problem. Of course in the book I discuss it more in depth :)
The documentation is misleading and incomplete. The objectID methods do not themselves copy objects they simply guarantee that you've gotten the specific object you wanted.
The context2 in the example is in fact the source context and not the destination. You're getting a nil because the destination context has no object with that ID.
Copying managed objects is fairly involved owing to the complexity of the object graph and the way that the context manage the graph. You do have to recreate the copied object in detail in the new context.
Here is some example code that I snipped from the example code for The Pragmatic Programmer's Core Data: Apple's API for Persisting Data on Mac OS X. (You might be able to download the entire project code without buying the book at the Pragmatic site.) It should provide you with a rough idea of how to go about copying an object between context.
You can create some base code that copies objects but the particulars of each object graph's relationships usually mean that you have to customize for each data model.
Had the same problem myself and found this article on created disconnected entities that could later be added to the context: http://locassa.com/temporary-storage-in-apples-coredata/
The idea is that you have an NSManagedObject because you're going to be storing objects in the database. My hurdle was that many of these objects are downloaded via HTTP API and I want to throw out most of them at the end of the session. Think of a stream of user posts, and I only want to save the ones that were favorited or saved as a draft.
I create all of my posts using
+ (id)newPost {
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Post" inManagedObjectContext:self.managedObjectContext];
Post *post = [[Post alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil];
return post;
}
and then the posts are inserted to the local managed object context when they are favorited
+ (BOOL)favoritePost:(Post *)post isFavorite:(BOOL)isFavorite
{
// Set the post's isFavorite flag
post.isFavorite = [NSNumber numberWithBool:isFavorite];
// If the post is being favorited and not yet in the local database, add it
NSError *error;
if (isFavorite && [self.managedObjectContext existingObjectWithID:post.objectID error:&error] == nil) {
[self.managedObjectContext insertObject:post];
}
// Else if the post is being un-favorited and is in the local database, delete it
else if (!isFavorite && [self.managedObjectContext existingObjectWithID:post.objectID error:&error] != nil) {
[self.managedObjectContext deleteObject:post];
}
// If there was an error, output and return NO to indicate a failure
if (error) {
NSLog(#"error: %#", error);
return NO;
}
return YES;
}
Hope that helps.
You need to make sure that you're saving the context that managedObject lives in. In order to fetch the same object in a different context, it needs to be present in the persistent store.
According to the documentation, objectWithID: always returns an object. So the fact that the fault resolves to an object will all nil values implies that it's not finding your object in the persistent store.
Swift 5
If you're wondering how to copy NSManagedObjects in 2020, the code below works for me:
// `Restaurant` is the name of my managed object subclass.
// I like to have Xcode auto generate my subclasses (Codegen
// set to "Class Definition") & then just extend them with
// whatever functionality I need.
extension Restaurant {
public func copy() -> Restaurant? {
let attributes = entity.attributesByName.map { $0.key }
let dictionary = dictionaryWithValues(forKeys: attributes)
guard let context = AppDelegate.shared?.persistentContainer.viewContext,
let restaurantCopy = NSEntityDescription.insertNewObject(forEntityName: Restaurant.entityName, into: context) as? Restaurant
else
{
return nil
}
restaurantCopy.setValuesForKeys(dictionary)
return restaurantCopy
}
}

Resources