I am writing an iOS app with Swift using Parse.
In my User table, I have a pointer field called UserAddress which is pointing to an Address table record. I would like to pull this Address data for current user. I did a bit of research and figured out fetching in background is an option but I would like to avoid it. Is there an alternative to pull this data without running extra fetch work?
What I can imagine is:
Fetching pointer data in AppDelegate before the app gets ready to use for users.
Somehow, force to set includeKey when loading a currentUser
Any of the above is feasible? Please advise me.
You correctly understand the two options, and they are the only two options. For non-user objects, usually includeKey() on a query is the way to go.
For the current user, since you have the user already, it would seem a little strange to query the user, including the pointer, just to avoid fetching the pointer, but that would work. You might be better off working on whatever's making you hesitant to do the fetch().
Related
I have a built in QR Code scanner in my iOS app. My backend runs on Parse, and I want the user to be able to pick certain objects on the app and encode their id's into a QR Code and share it around so that users can later scan a QR code, receive the object id's, and query them on the database to later fetch and display them somewhere.
However, what is stopping someone from using a QR scanner outside my app, looking at the object id's encoded into the QR, and messing something up? How bad is it to somehow allow users to see the object id of an entry in your Parse database? Will this heavily compromise security?
I thought about encrypting the object id's but am afraid my app will be rejected by Apple because of not following proper standards. What do you guys suggest?
Short answer: No.
There is no major security risk in giving away object IDs. Unless the 3rd parties had access to your app keys, then there is no way for them to access your data, even if they already knew everything about it. As long as you keep your app keys well hidden, there is no way your users can change anything outwith what you've de
Remember that your object ID's are only unique in the scope of your app (perhaps only even in the scope of that particular class), so when they find the object ID, they don't know if it's your app, my app, or anyone else's app - to them, it is as useful as holding a random set of digits.
The bigger issue I would say is that you cannot set the object IDs, so if for whatever reason that line is deleted, you can reinstate every part of it, but they'll all have different object IDs. This would mean your users running around with meaningless QR codes. Sure you can restore from a backup, but you'll lose any other changes since then. This is why I would never recommend indexing using Object IDs, rather that you create a new column "ID" that can then be changed by you, and then scripting a piece of cloud code logic in the side to ensure it is unique.
Sharing the object ID is not an issue, so long as your app has proper security. Hopefully your app's security does not rely on keeping the object ID secret.
Encryption is fine in iOS apps, so long as you file the proper paperwork. One of my apps uses a very high level of encryption and is available in every country, except France. You just need to file the correct paperwork and it's not that hard to do.
I am trying to figure out what the basic steps are for getting data passed between users. For example, say I, a user of the app, want to send another user of my app a message or a geopoint or some other form of data. I know the first step would be posting the data to Parse, which I don't have a problem with. But then, how would the other user know there is data to retrieve and also how would they go about retrieving it. Are push notifications the proper and only way of letting the recipient's app know its being sent something? When the recipient app knows there is data posted intended for it to retrieve, how does it go about locating it with a PFQuery? Does the posting app need to supply the receiving app with a UID of some form that the receiving app can then use in its query to locate the data? This is kind of the last puzzle piece for my app and unfortunately it's the only thing Parse didn't make clear to me. It is more than likely user error on my part not finding the correct documentation but, app to app communication is key in most apps and so I need to figure out the defacto way that Parse accomplishes this. Thanks in advance for any help!
You can have a relational table lets say "Messages" table in Parse,
with properties, sender (Pointer to a User), recipient (Pointer to a User) and message (String). and maybe a 'read' Boolean.
You could then query the messages table, With something like:
PSEUDO:
get all messages where recipient is equal to logged in user.
and display these messages on the UI.
Its pretty straightforward, I have done simple messaging service with Parse before
Thanks guys! In the end, I think it is best for a device to not have to be querying for changes but rather to be notified when it has new data to retrieve. Thus, for my uses, I think a combination of your answers, especially with the "onSave" hook function mentioned by Bruno, is the best solution.
I'm trying to keep the phone's contacts in my app up to date, in a persistent way. For that I'm thinking of using Core Data.
My plan right now seems highly suboptimal :
Browse the address book and every ABPerson in it
Store every field in a CoreData persistent store
Store the image in a separate file with an unique name and a reference in another "Contact" field.
And I do this every time the app comes in foreground in case the user would change one of his contact's name or picture, etc.
Some of my users have more than 2500 contacts, sometimes the operation lasts up to 10 seconds.
My question is :
Is there a way to keep some kind of reference to my ABPerson in coredata, so I can always load my ABPerson properties everywhere instead of Contact properties? (which would then always be up to date).
And I'm not even sure it's the right decision :
Should I always use the ABRecord that I find with a reference?
Should I always use my own copied data that I update regularly (from the ABAddressBook)?
If not, do you guys think I'm doing this in a decent way or would you suggest something else?
EDIT:
As asked in the comments:
I need to keep the contacts up to date simply to use their firstname, lastname and picture properties. If I notice the ABRecord changes, I'll update the related custom objects accordingly and that's it. I won't really need anything else afterwards (until they're edited again)
Thanks
Obtain and store only the ABRecord's unique identifier value. This is the one persistent way to reliably refer to the same person repeatedly and consistently.
You can always get all the other info out of the contacts database by using this unique identifier.
In iOS, call ABRecordGetRecordID to obtain the person's unique ID. Store that. When you later want to obtain the corresponding person, call ABAddressBookGetPersonWithRecordID.
Using Parse for iOS, I modified the _User's table to have a field called "Friends" which is an array of pointers to other _Users (by the way, I also have other additional fields).
When I call PFUser.currentUser(), I don't see this friends field in the user object. So I call PFUser.currentUser().fetch() (because refresh method doesn't seem to exist anymore) and I finally have the friends field in my currentUser object.
However, as soon as I exit the app, this field is lost. It doesn't seem to be saved locally unlike all the other fields of the current user.
How am I supposed to force a refresh of the cached current user ?
According to parse.com itself and one of their posts, there is no other way to keep your user up-to-date:
saveEventually does not write through any caches at this time,
including the currentUser, if the app has been restarted. You'll need
to regularly call fetch to keep it up-to-date. We are aware that this
is inconvenient, and are looking into ways to make it work better for
you.
Are you sure that you want your user objects to contain a value that's an array like that? I obviously don't know your use application, but I would recommend using a PFRelation instead. It works just like an array, but the Parse Framework provides a bunch of additional functionality along with it.
As for your specific question it might have to deal with Parse. Maybe they don't automatically retrieve and save arrays that are on an object. That would be my guess because an array could contain who knows how much data in it. I still don't know why they wouldn't locally save that data after it's fetched.
My suggestion is probably a little over the top, but would most likely be the best outcome. Utilize a local database such as CoreData or even the ParseLocalDatastore. Then encapsulate the Parse framework to have your own User object where you can store the information, which can also maintain persistence via your database.
I have a problem.
I have iOS client app that has to allow multiple users to log in and store their data locally.
Data is synchronized with RESTful service, and the latest snapshot along with user's changes should be stored locally for all users.
Previously this app was implemented with SQLlite as data storage engine.
Now I would like to migrate to CoreData.
What do I have:
server returns me entities for current user. User ID is not sent, as the user authorizes and gets their session;
I know who is logged in an should store all data for this particular user. In order to do that I need to say CoreData to store the object for the user with ID=12345.
The problem is:
I have to tell CoreData to store the particular object associated with particular user's ID.
I need a way to somehow alter the object mapped with RESTkit - setting proper ID field for it.
This task was straight and simple with SQLlite but looks problematic with CoreData.
I am still thinking that I don't know something about CoreData asking you to help me with clarifications or useful links.
There isn't a good way to do it.
Hacky, you could add the id as a parameter in the request so you can map it back again (requires RestKit dev branch at time of writing).
Non-hacky is to update and re-save the objects returned in the mapping result.
Alternatively you could use one operation to download the JSON, then mutate it, then run another operation to map it.