Is there a way to get Address Book contact ID's from Sync Services contact ID's? - objective-c

When getting the modified contacts from Sync Services, through the applyChange:forEntityName:remappedRecordIdentifier:formattedRecord:error method. The IDs in the address book are of the form 2C13E20E-6B24-4090-81FA-7A1E8B28119B, and even though some IDs of this kind are present in the ISyncChange * object, those are not actual contact ID's that can be found in the address book...
Is there a way to find out from Sync Services what a certain contact's ID is in the Address Book?
The reason for asking is that when saving large pictures for contacts in the Address Book, Sync Services does not save those pictures in their internal data storage. Therefore, contacts that have been modified or added with a large picture will be returned by Sync Services without the picture, basically offering incomplete information.
I need to get the Address Book ID, so that I can look up the contact's picture in ~/Library/Application Support/Address Book/Images/
Thanks!

It's a bad idea to rely on the Address Book id relating to an image in ~/Library/Application Support/Address Book/Images/ - you'd be better off finding an API that provides you the data you want to work with, because you aren't guaranteed that the image will be there then, or later (after an upgrade, this could all change!).
After a small amount of research, it appears that the api you want is documented here : http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AddressBook/Tasks/AccessingData.html#//apple_ref/doc/uid/20001023-103617
It's a little unwieldy because you necessarily need to understand their ABImageClient protocol and provide a callback, but I don't think it's that bad. This approach is much better than what you were doing - it's the Apple sanctioned way of getting this data and you won't have to worry about it breaking in the future.

Related

How can I save or get data about places near me without breaking policies

This is more of a general programming question.
I'm trying to create an app, think of it as a Yelp clone. I have most of it working but I'm missing one important feature. The data of the places around me. For now I'm only focused on food, so I'd like it if I search something like "Pizza", it'd show me all the pizza joints near me.
I was originally planning to use Google Places API. However if you havent heard, they're changing their pricing and lowering the free tier and upping the cost by a huge margin.
There's also the problem of saving the data. One workaround I saw a user suggest was to just keep using Google's API, but every time you make the query, store the data in your own DB as well (I only need address and name and latitude and longitude) so eventually, you'd have what you need in a sense. However I also want to have something like a simple rating system for each place like Yelp, but Google (and all other places like MapBox, Here Maps, etc) states something along the lines of "info from their API should not be stored or cached for more than 24hrs" but it's very broad and not specific.
So what I was planning to do was, call the Google API, grab the 3 info I need (Address, Name, Lat/Lng), add more fields to store the rating, likes, whatever else the user will add. Then store it in my database, but that doesn't seem like a solution now.
So does anyone have any ideas or advice? Or know of a service where I can get the details of all the food places? And if possible, can anyone confirm that storing the Name, Address, Lat&Lng is a violation of their policy since in my eyes, it's public data, but something like the rating that Google provides, or the pictures that Google provides, now that's Google property.
For obtaining places you can use OpenStreetMap, e.g. using Overpass API. Since larger traffic can be expected you should run your own database(s) instead of using the public APIs.
However OSM doesn't contain ratings. So you have to combine this data with some other publicly available rating system.

How do you get the ID of a row in a Core Data entity, such that you can reference it later?

Small question!
With Ruby on Rails (which I appreciate talks to a "real" database), with each record I add to a table, I can extract the ID of that record, send it somewhere, do something with it, and return data which can be associated with the original record.
I can't (for the life of me) seem to find the way to do it in Core Data.
If I have a Messages Entity with rows of messages. I want to be able to extract the ID of the message (row ID?), and send it to my server, and have a response change the same record by looking up it's ID.
The closest I can get is [message objectID]. However, I have no idea what this really returns, and I can't seem to encode it in a JSON request anyway.
Sigh.
Any help would be appreciated as I really don't know where to start with this one.
Edit:
Looking at other websites, and finally drilling it down, I've decided to use my own Unique ID. Apple can change the structure of URIRepresentation and, objectID can change if you change the structure of core data. So, it's best to stick with what I know.
objectID is a unique id for an object in CoreData. Quoted from Apple
An NSManagedObjectID object is a compact, universal identifier for a
managed object. This forms the basis for uniquing in the Core Data
Framework. A managed object ID uniquely identifies the same managed
object both between managed object contexts in a single application,
and in multiple applications (as in distributed systems). Identifiers
contain the information needed to exactly describe an object in a
persistent store (like the primary key in the database), although the
detailed information is not exposed. The framework completely
encapsulates the “external” information and presents a clean object
oriented interface.
you might consider reading the documentation here and here
You can get an URIRepresentation which might help you with JSON representation.
Looking at other websites, and finally drilling it down, I've decided to use my own Unique ID. Apple can change the structure of URIRepresentation and, objectID can change if you change the structure of core data. So, it's best to stick with what I know.

REST best practices: should a store also return metadata?

I'm building my first REST API (at least trying) for a personal project.
In this project there are resources called players which hold can be in a team. According to REST API design rulebook a resource should be made either to be a document or a store and one should keeps these roles as segregated as possible.
Yet I would like to append some metadata to the team resource, eg the date the team was founded. Is it okay then for GET /teams/atlanta to return this metadata (making it a document) alongside the list of players in the team (making it a store).
Is this a good idea? If so why? If not why not and how to solve this better?
I know there are no rules to developing a REST API, but there are good practices and I would like to adhere to those. Please also not that this is really my first REST API so pardon my ignorance if there is any.
I would recommend having GET /teams/atlanta return just the information about the team, such as the founding date that you mention, and then having GET /teams/atlanta/players return the list of players for that team. These distinctions become more important when you are presenting an API that uses HTTP methods other than GET.
For example, if you wanted to add a player to a team - this would be a lot easier if you could just POST a player object to /teams/atlanta/players than if you had to PUT the whole team object to /teams/atlanta every time you wanted to add one individual player.
If your API only allows retrieval of data, and if it is for a specific client application, there is an argument for combining all the team data into one object to save the client having to make additional requests for the data, but bear in mind that it is less flexible.
Your application may want to display a list of teams by calling GET /teams but you probably wouldn't want all of the player information included in each object in the list as this is quite a lot of data, but if GET /teams/atlanta returns player information then it would be inconsistent not to include it in the list version too.
I would personally favour splitting up the resources as I've suggested, and live with the fact the client may need to make an extra request or two.

Custom iOS address book. Need advices about data structures and performance

I am currently developing a voIP app and I am really stuck with the address book.
Because of the custom design, the native address book does not fit in my app. Besides, I want to add some extra data not present in the native address book. But this is leading into some problems which I've separated into two sections:
1. Data structures:
In a section of my app I need to show to the user all his address book contacts with additional information (if the user has the same app and it's online, for example).
Right now I'm getting all the info from the Address Book api and loading it in an array directly (which is accessed by the tableView:cellForRowAtIndexPath:), but not displaying the custom information I was talking about. I don't know if its worthwhile to store all the address book info in a sqlite data base (where I'd be able to add the extra information easily) or if I should store only that extra information in a file or something.
The biggest problem of storing it in a data base is that the contact's picture is heavy enough to get a wasting-memory data base. I thought to store only a reference (the ABRecordID) and then to gather the related info from the address book instead of the data base, but the Apple documentation of the Address Book api says the ABRecordID is not guaranteed to remain the same, so it could cause my data to appear next to wrong contact data.
Any idea?
2. Performance:
The second big problem with this custom address book is that... the iOS table views are too 'manual' compared to the Android ones, for example. You need to have the data stored somewhere so that when the tableView:cellForRowAtIndexPath: method gets called you return that data. You can also load that data inside this method, but this makes it very slow.
The problem here is that preloading all the data in memory is dangerous, because a person may have 40 contacts or 2000 (and maybe he/she has taken a picture for each of them, which will be much more memory-consuming). If the iOS device runs out of memory the system will kill the app. The data base approach has no memory problems, but making queries for each cell to appear is so slow that it becomes unacceptable.
Again, I need ideas for this. Can't find a tradeoff between performance and memory consumption.
Please, don't ask for code because I'm not allowed to post it. I'd really appreciate your advices. Thank you in advance!
Data structures:
Along with the recordref you should store the name phone number and email address. Nothing else in your data store. If one of the three vales change and the other two remain the same update the changed value. The recordref can change during a restore of a device for many users at once but the name email and phone won't. If the user changes a name or email or phone they won do it across many users at once. Once in a while you end up with a recordref that does not match up with email and phone say, the contact may have changed employers so then show a list of close matches and ask the user to select one.
As far as some one having 1000s of contact I would use paging. Load 100 or 200 at a time in to an array with current row displayed in the table view as middle of your array index. Once the user scrolls 20-30 records update the records in your array from address book. Your going to be spending a lot time resaving data just to go through the collection comparing and trying to keep it up to date. You should be able to store quite a few records long as your not keeping the user images in memory, for that you should let the table view handle it. Get image and assign to cell when you get the notification about the cell about to become visible. Even then I would put a short wait before loading the image, because if the user is scrolling fast the cell will just fly by and you'll get notified that the cell scrolled out and you can release the image data. If the user is scrolling slowly then the short wait/sleep will pass and the image should show up for each cell.
I don't know how much meta your planning on storing in your app wrapping the contacts but if you should create two tables for the contact object, one with 3-4 indexed columns that will allow for faster querying and a second to hold the rest that loaded only when users viewing the contact in a detail view. Can't get too much into a tableviescell, unless your on the iPad.
Hope that helps.

Address Book contacts in Core Data

What’s considered ‘best practice’ when saving Address Book contacts in Core Data?
I’m writing an iPhone App, based on Core Data, where I need to save and recall Address Book contacts as part of the data model.
In the UI I plan to present a screen where the user can pick a contact from the current Address Book, create a new contact to store in the Address Book, or just create a ‘one-off’ contact with no saved record, local to the App only. These contacts are tracked in the context of the orders they have made, and not all contacts will require saving outside the App itself.
It feels ‘wrong’ to copy the data from the Address Book if using an existing entry, but not sure what to do if an Address Book record is edited or deleted.
I only need to track name and photo for the purposes of the App, so gut-reaction is to store the ABRecordID, and—because these can apparently change(!)—the first and last name, and only update local record if it’s updated (how to track that?).
Or can you store a ABRecordRef directly? (I imagine they aren’t persistent?)
I’ve done some searching on Google, and here, but can’t find any code samples or discussion on the integration of Core Data and Address Book in this manner; just lots of stuff on each in isolation.
Any one with some experience/gotchas on this subject point them out, or point me in the direction of some more reading?
Thanks.
Andy W
I would store the ABRecordID and then handle the situation for when they change although I have not personally seen a case where they change except when the user deletes all data and restores it from another source (moving from MobileMe to Google for example).
See Apples online Documentation on how to handle changing ids and what to store.