Error occurs when I convert NSMutableArray to NSArray - nsmutablearray

I want to convert NSMutableArray to NSArray to it gives error following is code
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
tempPeoples=[[NSMutableArray alloc]init];
for(int i=0;i<nPeople;i++){
ABRecordRef i1=CFArrayGetValueAtIndex(allPeople, i);
[tempPeoples addObject:i1];
//[peoples addObject:i1];
}// end of the for loop
// Peoples is NSArray
// peoples=[[NSArray alloc] initWithArray: tempPeoples];
peoples=[NSArray arrayWithArray:tempPeoples];
Please help

I found the solution using following code
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *allPeople = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
tempPeoples= [NSMutableArray arrayWithCapacity:0];
for(int i=0;i<nPeople;i++){
ABRecordRef i1=CFArrayGetValueAtIndex(allPeople, i);
NSString* name = (NSString *)ABRecordCopyValue(i1,kABPersonFirstNameProperty);
[tempPeoples addObject:name];
// [peoples addObject:i1];
}// end of the for loop
peoples=[NSArray arrayWithArray:tempPeoples];

Related

nsstring to nsmutable array

I'm making an app in which i want to access the contact's first name and store them in to nsmutable array so that i can get the values of that array like array[0] up to array[i-1] and print them in table view.Here is my code:
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
contacts_Image_List=[[NSMutableArray alloc]init];
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
person.firstName = firstName;
person.lastName = lastName;
person.fullName = fullName;
// person.userThumb[i]=firstName;
//[person.userThumb[i] addObject:#"firstName"];
//above line gives null
NSLog(#"%#",person.userThumb[i]);
my mutable array is in Person.h class.
On each iteration just do:
[person.yourMutableArray addObject:fullName]
Just ensure that your MutableArray has already been allocated, and that you only allocate it once.

Init NSManagedObject subclass

I would like to know if it's possible to init a subclass of NSManagedObject ?
I have a class "Actualite" which is a subclass of NSManagedObject and when I want to initialize this class, I get this error :
"CoreData: error: Failed to call designated initializer on NSManagedObject class Actualite", and the app crashes after this message "-[Actualite setTitre:]: unrecognized selector sent to instance 0x8433be0"
Here is my code :
-(void) recupererActualites {
listeNouvellesActualites = [[NSMutableArray alloc] init];
// Convert the supplied URL string into a usable URL object
NSURL *url = [NSURL URLWithString:FACE06_RSS];
// Create a new rssParser object based on the TouchXML "CXMLDocument" class, this is the
// object that actually grabs and processes the RSS data
CXMLDocument *rssParser = [[CXMLDocument alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding options:0 error:nil];
// Create a new Array object to be used with the looping of the results from the rssParser
NSArray *resultNodes = NULL;
// Set the resultNodes Array to contain an object for every instance of an node in our RSS feed
resultNodes = [rssParser nodesForXPath:#"//item" error:nil];
NSMutableArray* tmp = [[NSMutableArray alloc] init];
for (CXMLElement* resultElement in resultNodes) {
// Create a temporary MutableDictionary to store the items fields in, which will eventually end up in blogEntries
NSMutableDictionary *blogItem = [[NSMutableDictionary alloc] init];
NSMutableArray* categories = [[NSMutableArray alloc] init];
// Create a counter variable as type "int"
int counter;
// Loop through the children of the current node
for(counter = 0; counter < [resultElement childCount]; counter++) {
// Add each field to the blogItem Dictionary with the node name as key and node value as the value
if([[[resultElement childAtIndex:counter] name] isEqual:#"category"])
[categories addObject:[[resultElement childAtIndex:counter] stringValue]];
else {
if ([[resultElement childAtIndex:counter] stringValue] != nil)
[blogItem setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
else
[blogItem setObject:#"" forKey:[[resultElement childAtIndex:counter] name]];
}
}
Actualite* actu = [[Actualite alloc] init];
[blogItem setObject:categories forKey:#"categories"];
[actu initWithDictionnary:blogItem];
[tmp addObject:actu];
//[actu release];
[categories release];
[blogItem release];
}
listeNouvellesActualites = tmp;
[rssParser release];
resultNodes = nil;
// Stockage des actualités en local
[self stockerActualites];
}
And the initWithDictionary method set all the attributes of the Actualite class.
I also tried
Actualite* actu = [[Actualite alloc] initWithEntity:[NSEntityDescription entityForName:#"Actualite" inManagedObjectContext:managedObjectContext] insertIntoManagedObjectContext:managedObjectContext];
and
Actualite* actu = (Actualite*)[NSEntityDescription entityForName:#"Actualite" inManagedObjectContext:managedObjectContext];
instead of
Actualite* actu = [[Actualite alloc] init];
The errors disappear but the app stops at this point. I don't know what can I do...
Is someone already had this problem ?
Thanks a lot !
The idea is that you ask for a new object to be created inside a context and then you use it:
Actualite* actu = [NSEntityDescription insertNewObjectForEntityForName:#"Actualite" inManagedObjectContext:managedObjectContext];

Selecting TableView cell returns incorrect object

I followed a tutorial I found online to create a tableview with sections and an index from an array of custom objects. This code works with the exception that when I select a row in the table I the index path for that section and not for the entire array. I can see why it doesn't work but I can't figure out how to address the fix, this is my cell for tableview code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"NameCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int displayOrder = [defaults integerForKey:#"displayOrder"];
int sortOrder = [defaults integerForKey:#"sortOrder"];
NSString *alphabet = [listIndex objectAtIndex:[indexPath section]];
NSPredicate *sectionPredicate = [[NSPredicate alloc] init];
if (sortOrder == 1) {
//NSLog(#"fName is predicate at cell level");
sectionPredicate = [NSPredicate predicateWithFormat:#"fName beginswith[c] %#", alphabet];
} else {
//NSLog(#"lName is predicate at cell level");
sectionPredicate = [NSPredicate predicateWithFormat:#"lName beginswith[c] %#", alphabet];
}
NSArray *sectionContacts = [filteredList filteredArrayUsingPredicate:sectionPredicate];
if (isSearching) {
current = [filteredList objectAtIndex:indexPath.row];
} else{
current = [sectionContacts objectAtIndex:indexPath.row];
}
if (displayOrder == 1) {
NSString *fullName = [NSString stringWithFormat:#"%# %#",[current valueForKey:#"fName"],[current valueForKey:#"lName"]];
[cell.textLabel setText:fullName];
//NSLog(#"FirstNameFirst");
} else {
NSString *fullName = [NSString stringWithFormat:#"%# %#",[current valueForKey:#"lName"],[current valueForKey:#"fName"]];
[cell.textLabel setText:fullName];
//NSLog(#"LastNameFirst");
}
[cell.detailTextLabel setText:[current valueForKey:#"extension"]];
return cell; }
THen I call the segue with this code.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showContact"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSDictionary *c = [filteredList objectAtIndex:path.row];
[dvc setCurrentContact:c];
[searchBar resignFirstResponder];
} }
The problem is that the objectAtIndex:path.row returns the index for that section but it isn't modified for the entire array, so if a name in the "B" section that is at index 4 of that section is tapped it returns the object at index 4 of the primary array. I have been scratching my head to figure out how to get the index for the full array and not for the one that is only local to that section.
I'll buy you a 6 pack of your favorite beverage if you can help!
Thanks!
You do it the same way that they do it in the first function, so change your prepareForSegue to this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showContact"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSDictionary *c;
NSString *alphabet = [listIndex objectAtIndex:[path section]];
NSPredicate *sectionPredicate = [[NSPredicate alloc] init];
if (sortOrder == 1) {
sectionPredicate = [NSPredicate predicateWithFormat:#"fName beginswith[c] %#", alphabet];
} else {
sectionPredicate = [NSPredicate predicateWithFormat:#"lName beginswith[c] %#", alphabet];
}
NSArray *sectionContacts = [filteredList filteredArrayUsingPredicate:sectionPredicate];
if (isSearching) {
c = [filteredList objectAtIndex:path.row];
} else{
c = [sectionContacts objectAtIndex:path.row];
}
[dvc setCurrentContact:c];
[searchBar resignFirstResponder];
}
}
Note that it would probably be best to pull the common code out and make a separate function instead of using it twice like this.

Find assets in library - add to a AVMutableComposition - export = crash

I've been struggling with adding assets from the iPhone Photo Library to a AVMutableComposition and then export them. Here is what I got:
Finding the assets: (here I grab the AVURLAsset)
-(void) findAssets {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop){
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Do something interesting with the AV asset.
[thumbs addObject:alAsset];
[assets addObject:avAsset];
}else if(alAsset == nil){
[self createScroll];
}
}];
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No groups");
}];
[library release];
}
Here I add a asset to my composition (I use the first object in the array for testing only.
-(void) addToCompositionWithAsset:(AVURLAsset*)_asset{
NSError *editError = nil;
composition = [AVMutableComposition composition];
AVURLAsset* sourceAsset = [assets objectAtIndex:0];
Float64 inSeconds = 1.0;
Float64 outSeconds = 2.0;
// calculate time
CMTime inTime = CMTimeMakeWithSeconds(inSeconds, 600);
CMTime outTime = CMTimeMakeWithSeconds(outSeconds, 600);
CMTime duration = CMTimeSubtract(outTime, inTime);
CMTimeRange editRange = CMTimeRangeMake(inTime, duration);
[composition insertTimeRange:editRange ofAsset:sourceAsset atTime:composition.duration error:&editError];
if (!editError) {
CMTimeGetSeconds (composition.duration);
}
}
And finally I export the comp and here it crashes
-(void)exportComposition {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
NSLog (#"can export: %#", exportSession.supportedFileTypes);
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME];
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = exportURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;//#"com.apple.quicktime-movie";
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (#"i is in your block, exportin. status is %d",
exportSession.status);
switch (exportSession.status) {
case AVAssetExportSessionStatusFailed:
case AVAssetExportSessionStatusCompleted: {
[self performSelectorOnMainThread:#selector (exportDone:)
withObject:nil
waitUntilDone:NO];
break;
}
};
}];
}
Does anyone have an idea of what it might be? It crashes on
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
And I tried different presets and outputFileTypes.
Thanks
* SOLVED *
I have to answer my own question now when I have solved. It's amazing that I've been struggling with this for a whole day and then I fix it right after posting a question :)
I changed and moved:
composition = [AVMutableComposition
composition];
to:
composition = [[AVMutableComposition
alloc] init];
I think I was too tired when I was working on this yesterday. Thanks guys!

Is it possible to open addContactScreen from native app?

I want to replicate add contact like screen iPhone has. But I don't want to add contact in default phonebook instead I want to use the details in my app. Is it possible to open default add new contact screen and get all the data? If yes then how? A simple code snippet will be very helpful. Here is an image of add contact screen to better understand my question
You can try to add the contact to the address book, pull the data and then delete it from the address book. this is a fairly simple process.
I use this function to save all the person data to core data in my app. and then to delete the person from the addressBook.
+(void)savePersonDetails:(Person*)person{
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef ref = ABAddressBookGetPersonWithRecordID(addressBook,[person.ID intValue]);
ABMutableMultiValueRef multiPhones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multiPhones); i++) {
NSString *phoneNumber = (NSString*)ABMultiValueCopyValueAtIndex(multiPhones, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multiPhones, i);
NSString *phoneNumberLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
CFRelease(locLabel);
Phone *phone =(Phone*)[NSEntityDescription insertNewObjectForEntityForName:#"Phone" inManagedObjectContext:person.managedObjectContext];
phone.number = phoneNumber;
phone.label = phoneNumberLabel;
phone.person = person;
[person addPhonesObject:phone];
[person release];
CFRelease(phoneNumber);
CFRelease(phoneNumberLabel);
}
CFRelease(multiPhones);
ABMutableMultiValueRef multiEmail = ABRecordCopyValue(ref, kABPersonEmailProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multiEmail); i++) {
NSString *mail = (NSString*)ABMultiValueCopyValueAtIndex(multiEmail, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multiEmail, i);
NSString *mailLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
Mail *mailEntity =(Mail*)[NSEntityDescription insertNewObjectForEntityForName:#"Mail" inManagedObjectContext:person.managedObjectContext];
mailEntity.mail = mail;
mailEntity.label = mailLabel;
mailEntity.person = person;
[person addMailsObject:mailEntity];
CFRelease(locLabel);
[mail release];
[mailLabel release];
}
CFRelease(multiEmail);
ABMultiValueRef streets = ABRecordCopyValue(ref, kABPersonAddressProperty);
for (CFIndex j = 0; j<ABMultiValueGetCount(streets);j++){
CFDictionaryRef dict = ABMultiValueCopyValueAtIndex(streets, j);
CFStringRef typeTmp = ABMultiValueCopyLabelAtIndex(streets, j);
CFStringRef lbl = ABAddressBookCopyLocalizedLabel(typeTmp);
NSString *street = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressStreetKey) copy];
NSString *city = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressCityKey) copy];
NSString *state = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressStateKey) copy];
NSString *zip = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressZIPKey) copy];
NSString *country = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressCountryKey) copy];
Address *addressEntity =(Address*)[NSEntityDescription insertNewObjectForEntityForName:#"Address" inManagedObjectContext:person.managedObjectContext];
addressEntity.label = (NSString*)lbl;
addressEntity.street = street;
addressEntity.city = city;
addressEntity.state = state;
addressEntity.zip = zip;
addressEntity.country = country;
[street release];
[city release];
[state release];
[zip release];
[country release];
CFRelease(dict);
CFRelease(lbl);
CFRelease(typeTmp);
addressEntity.person = person;
[person addAddressesObject:addressEntity];
}
CFRelease(streets);
ABMutableMultiValueRef multiURL = ABRecordCopyValue(ref, kABPersonURLProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multiURL); i++) {
NSString *url = (NSString*)ABMultiValueCopyValueAtIndex(multiURL, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multiPhones, i);
NSString *urlLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
Url *urlEntity =(Url*)[NSEntityDescription insertNewObjectForEntityForName:#"Url" inManagedObjectContext:person.managedObjectContext];
urlEntity.url = url;
urlEntity.label = urlLabel;
urlEntity.person = person;
[person addUrlsObject:urlEntity];
CFRelease(locLabel);
[urlLabel release];
[url release];
}
CFRelease(multiURL);
ABAddressBookRemoveRecord(addressBook, ref, nil);
ABAddressBookSave(addressBook, nil);
CFRelease(addressBook);
if (![person.managedObjectContext save:&error]) {
// Update to handle the error appropriately.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1); // Fail
}
}

Resources