Exporting iOS vCards without resizing images - resize

My iPhone app is currently backing up users' contacts to .vcf files using the method ABPersonCreateVCardRepresentationWithPeople of AddressBook framework.
But this method shrinks the images of the contacts, and I would like to have the option to keep them in original size.
What better way to do this?

Still keep on getting all the vcards through ABPersonCreateVCardRepresentationWithPeople and keep them in an NSDictionary where the key is the person's ID and the value is the vCard
Go through all the people in the address book and get the image data using ABPersonCopyImageData and save that in an NSDictionary where the key is the person's ID and the value is the base64 string representation of the image data.
Go through the first NSDictionary and replace the base64 encoding (that long series of characters in the PHOTO tag) with the value for that person's ID in the second dictionary.
Use the first dictionary's values in whatever you want, because now, the values should contain vCards with original sized pictures.

Related

MCNearbyServiceAdvertiser Multi-Object DiscoveryInfo

I do not understand how this makes sense. I put two objects in the discoveryinfo dictionary inside the MCNearbyServiceAdvertiser object that I create and the browser doesn't see the advertiser, yet when I move the second object out of the dictionary and comment it out at the end of the line, the browser sees the advertiser. Does the discoveryinfo dictionary only accept one object to work? I have a string as the first object and an array as the second. Here is what it looks like:
advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:myPeerID discoveryInfo:#{#"Name": [[NSString alloc] initWithString:myUniqueID], #"Peers": [[NSArray alloc] initWithArray:connectedPeersAry]} serviceType:#"Blahblah"];
And before that line, I tried this simpler format (but went to the above just in case the syntax was the problem):
advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:myPeerID discoveryInfo:#{#"Name": myUniqueID, #"Peers": connectedPeersAry} serviceType:#"FRCSCOUT"];
I guess I can put a dictionary or array inside the discoveryinfo dictionary, but I feel it's a pretty dumb way of doing things because a dictionary shouldn't ever be limited to one object for any case.
I'll go ahead and put my objects in another layer to "conserve space" inside the discoveryinfo dictionary, but if any of you find a better way of doing things or if you are seeing the same problem, please let me know.
You can have multiple objects in the discoveryInfo dictionary, but keep in mind that the dictionary will be encoded in a Bonjour TXT record. This imposes a few restrictions on what can be put into that dictionary.
As stated in the documentation for [MCNearbyServiceAdvertiser initWithPeer:discoveryInfo:serviceType:]:
This data is advertised using a Bonjour TXT record, encoded according to RFC 6763 (section 6). As a result:
The key-value pair must be no longer than 255 bytes (total) when encoded in UTF-8 format with an equals sign (=) between the key and the value.
Keys cannot contain an equals sign.
For optimal performance, the total size of the keys and values in this dictionary should be no more than about 400 bytes so that the entire advertisement can fit within a single Bluetooth data packet.
Well, found my problem. As quoted by Apple in their class reference for MCNearbyServiceAdvertiser:
"The content of discoveryInfo will be advertised within Bonjour TXT records, so you should keep the dictionary small for better discovery performance."
So, looks like I'll have to use a comma separated string of some sort...
EDIT
I misunderstood the Multipeer Connectivity API. I thought the roles were reversed and the Advertiser was basically the public host for a Multipeer Session, but it should be the Browser that invites Advertisers. I now just have the Unique ID generated as the discovery info.
Thank you all for your help and sorry for the API confusion on my part.

Comparing items using number codes (JSON)

in my app, the users can create groups. When a user creates a group, a new folder is uploaded on dropbox, and inside there is a JSON file like this:
{"group":"0864798478"}
The code you see is generated randomly in the following way:
NSString *randomKey = [NSString stringWithFormat:#"%0.10u", arc4random()];
Then I have a table view which displays all the folders (groups). But I would like the UITableView to display only the groups which mach with the codes the iPad has saved on.
So if I have:
{"group a":"0864797073"}
{"group b":"0764898478"}
{"group c":"2864758479"}
And on the iPad there is a file containing the code:
0864797073 (group a)
The table View displays only that group, not all.
How can I do this??
Thanks in advance for the help!!
You can use JSONKit or SBJson for parse JSON files and obtain NSDictionaries with the data. Then you can create a NSDictionary in wich you could save the result of comparing previous dictionaries, an then show the result in the table with method tableView:cellForRowAtIndexPath. OR, make the comparison in the method tableView:cellForRowAtIndexPath. Good Luck!
EDIT:
If the file reads:
{"group a":"0864797073"}
You parse it and get a dictionary like in wich "group a" will be the KEY and the NSString "0864797073" will be the value. So to compare the dictionary wich holds group a with wich holds group b you have to do:
if([[firstParsedJson objectForKey:#"group a"] isEqualToString:[secondParsedJson objectForKey:#"group b"]])
{
//Do some stuff...
}
Where firstParsedJson and secondParsedJason are NSDictionaries that represent parsed json with, for example, SBJson.
As Luis has mentioned, SBJson is the easiest framework that you allows you to parse JSON using objective-C. You can parse the JSON and go through the CellForRowAtIndexPath delegate method of the UITableView to show all the values.
If you have having any troubles with visulizing the JSON then this link will help you to get a better idea of how your JSON is being created.

Allow User to Save Generated Array String for Later Viewing

I'm creating a small app that generates baby names from 2 separate NSArrays. I have 1 setup for first name and 1 setup for middle name. When the button is pushed it concatenates 2 NSStrings at random as seen with this code:
int a = arc4random() % 2;
int b = arc4random() % 2;
// populate the array for the names
NSArray *firstNameArray = [NSArray arrayWithObjects: #"Anna",
#"Amy",
#"Amber", nil];
NSArray *middleNameArray = [NSArray arrayWithObjects: #"Brenda", #"Beatrix", nil];
// concatenate strings at index of array
NSString *fullName = [NSString stringWithFormat:#"%# %#", [firstNameArray objectAtIndex:a], [middleNameArray objectAtIndex:b]];
// display the newly created first & middle names
babyname.text = fullName;
I'm kind of at a loss for how to allow a user to 'favorite' a particular name and save it to a new view (probably table view). Can anyone point me in the right direction here?
What you would probably want to do is store the names selected so that you could refer to them later. You may wish to create a Person class or something of the like and have a property in it called favorite which is a BOOL value. Then you would just have to set the favorite property to YES for the ones the user wants to favorite.
A good mechanism to store a custom class and have it persist is Core Data, but it really depends on how many Person instances you will/could have. Core Data is really easy to implement once you get the hang of it and there are many tuorials online of how to use it. I would check out the iTunesU videos from Stanford on CoreData using UIDocument and UIManagedDocument. I found them very helpful.
Good Luck.
You have given a snippet of your code from which the exact flow of your logic in your program is incomprehensible , assuming that u have a textfield for user to input and a button to mark it as favorite then in the action of button you can get the text from textfield and store it in some array .Moreover you don't store data in tableview but you display it there.You can then use the Favorited array to display the names in a tableview .
You can use NSUserDefaults,plist,sqlite,coredata for persistent storage.
NSUserDefaults and plist can handle only low amount data efficiently.
Please See My Link on
persistent storage
Tutorial on TableView

How does one save a list of images in Objective-C

In my code I have an item that is a list of alternating strings and images that I wish to save. I know how to save individual images in their JPEG representations, but is there a simple and efficient way I don't know of in Objective-C to save all these items (or at least the images since I can handle the strings myself) while maintaining their order?
ex: item 1 ("hi", image, "how", image, "are", image), item2("this", image, "is", image)
maintaining item order is not important to me, but the order in the list is. The first thing that comes to mind is simply to save every single image, and have an algorithm to create then remember their imagename and then save and load the text list. Is there an easier way to do this? Can I literally just save the array itself as a plist and be on my merry way? (i've only seen examples of these with strings)
I believe I understand what you're going for. You'd like to save an array of items, each of which contains an array of Objects that contain an image and a string. If this is accurate then you're idea of saving the array to a plist is correct.
In short you would create NSDictionaries of your Objects and save the array of them. Like so:
In your object you'll have a method similar to this:
- (NSDictionary *)dictionaryOfItemData;
{
NSMutableDictionary * mutableDictionary = [[NSMutableDictionary alloc] init];
[mutableDictionary setObject:imageName
forKey:#"imageName"];
[mutableDictionary setObject:UIImagePNGRepresentation([self image])
forKey:#"imageData"];
return mutableDictionary;
}
Then you would save an array of these (or array of arrays, or whatever your desire based on file size concerns, need to load, etc.) like so in the proper place:
[[arrayOfDictionaries description] writeToFile:path
atomically:YES
encoding:NSUTF8StringEncoding
error:NULL];
Which gives you the plist, that you can load and hydrate by creating your image with data and setting the image name from the dictionary.
~Good Luck

NSDictionary with specific property of plist

I have a plist with key values.
Each key represent a language, let's say 'it' 'en' ....ecc
The value of each key is another key/value(=array) set. At startup I would like to create a dictionary by reading only a specific key. Let's say the locale of my iphone is 'it', then the init method would only parse it key, because the only way I found by now is to make a dictionary from the whole plist file and then another dictionary.
But I can imagine this can become quite cpu consuming if I add more language in the future.
thanks
Leonardo
Why not localize the plist file, thus having multiple plists?