Exclude PFObject Sublclass' Attribute to Get Persisted - ios

I'm working on an iOS app using the native Objective-C Parse API, and I have a subclass of PFObject called MRPlace which has a number of attributes that will be stored in the parse back-end. However, there is an attribute (Say the attribute is called isFavorite) that I would only like to be kept locally (client-side) and thus excluded from being persisted in the database.
I've looked through the documentation and the web with no luck. How can this be accomplished?

As mentioned in knshn's comment, using #synthesize isFavorite = _isFavorite for example will work.

Since they won't be stored on Parse, and really won't even be persisted locally (with no Local Data Store,) you should store these values elsewhere. There's no way to specify local-only keys on a PFObject.

I found a way to accomplish this in swift so I thought I'd share. Say there's an attribute called streetName. This is how you'd declare it normally:
#NSManaged var streetName: String
However, if you omit the #NSManaged it works as desired!
var streetName: String

Related

Should I use NSUserDefault, dictionaries, core data - or something else?

I'm having some issues with the app, that I'm making, which I thought would be a lot easier to explain with some photos, so ... :
Ofcourse the "Create New Person-button" in nr. 1 leads you to number two.
Now, I'm having issues figuring out how to save this data about the person in the "People Diary". The goal is, that when you enter a person's name, add a photo (an enable-camera feature, I will struggle with at a later time...) and add an answer to the question - then you only need to press "Save this person", and then you will be redirected to the AllPersonsInYourDiaryViewController, where there is now a new tableViewCell with this new person's name (maybe with a subtitle containing the answer and the photo shown in miniature in the cell too).
(Naturally you can then enter this cell with the data about the person too - but that comes next.)
So far in the app, I have used NSUserDefault, when allowing the user to create this specifik Diary by the Name "Antons Diary" with the specifik question and so on. But now it came to my attention, that maybe it is smarter to use something else? I tried with dictionaries, but couldn't get this to work properly.
So...: Before I spend hours and hours playing around with one of these ways, will someone smarter than me, tell me what the best approach would be?
If I can give my two cents, the first thing you have to do is to “design” how to represent a person programmatically. You can create a struct or class to do so, even though a struct is more suitable:
struct Person {
var name: String?
var answer: String?
var photo: String?
}
Then you can decide how to save the data of such an object persistently. If you want to use a database, then I would recommend using SQLite with FMDB library. It’s really easy and fast to learn how to use it, and it's also quite handy. I've used it big projects and it works smoothly. I find CoreData too complicated and an overkill based on what you need.
If you don’t want to use a database, your only other way is to save to files, but still, you’ve got options here too. If you encode (see Codable protocol in Swift), you can use NSKeyedArchiver to convert to Data object and write then to disk. If you like using dictionaries, and since the properties you’re going to have for a person are not going to be too many, you could create a dictionary by assigning the properties and their values, and then convert and save as JSON data, or even Plist files. Without any intension to do promotion here, but just to provide some additional help, if you want take a look to a library that I’ve written and that can do all these automatically for you. It’s a protocol that you have to adopt, and then you can instantly convert your struct to a dictionary, JSON or plist and save to files.
No matter which way you’re going to select, save the images as single files to documents directory, and keep their file names only stored to database/file. Based on them, you can build the path to each image (or the URL) easily when needed. Warning: Do not save the full path to the documents directory, especially if you’re testing on Simulator; paths are changing on each build. Save the file name only.
Additionally, if you’re going to use a struct like the one shown above, you could implement small but super convenient functions that will be responsible for saving, loading, or updating your data to the solution (database/file) you’ll eventually select. That way, you’ll have related stuff gathered in one place, and easily accessible (i.e., person.save()).
struct Person {
var name: String?
var answer: String?
var photo: String?
func save() {
…
}
func load() {
…
}
// More functions…
}
Lastly, avoid using UserDefaults, or at least keep just a few non-critical data there. UserDefaults are not meant to keep all data produced by your app. Most importantly, do not use it for saving sensitive data, especially passwords or other stuff like that.
I hope the above will help you make your mind.
I can give you the logic behind coreData and NSUserDefaults, but you will decide which one should be used.
CoreData is usually used as a database. you can create entities and attributes for every entity. Moreover, you can create relations between these entities.
When extracting data from coreData, you can arrange this data using NSSortDescriptor or select a specific record using NSPredicate.
So as you can see CoreData is a database.
While NSUserDefaults is usually used to save a password, username, userID... and such issues that you will regularly use in the app. NSUserDefaults gives you a direct access to the saved variables at any time. However, CoreData will take more time and lines of code to access the entity and make the query.
Now, check which method suits your case more.

Having trouble understanding when to use int or string in Coredata

iOS 10, Swift3
I am making an application where user fetches their daily agenda from server, and I wanna save their schedule in Coredata. A simple json from API comes like
{
"id": 11639002,
"subject": "Coffeee",
"startUTC": "2017-05-03T15:00:00+00:00",
"endUTC": "2017-05-03T16:00:00+00:00"
}
If a change is made on server side I wanna update the appointment also I dont wanna save duplicate entries. Also I wanna be able to sort this row by startDate I wanna pass around this appointment row by its id
I thought a good solution for this would be like this
#NSManaged public var id: Int32
#NSManaged public var subject: String?
#NSManaged public var startUTC: NSDate?
#NSManaged public var endUTC: NSDate?
Every single post I read here says that Coredata is not ORM or relational database , so developer should get away from that mind state.
I dont understand how and why would I need to get away from relational database mindset when I am trying to replicate unique_id approach like in server side.
This tutorial http://dorianroy.com/blog/2015/09/how-to-implement-unique-constraints-in-core-data-with-ios-9/
says that
No more fetch/if/else
Until now, when you wanted to import data objects into Core Data from
a file or network request, you had to create a fetch request for each
incoming object with a predicate that matches the id and then execute
it to look for an existing version of that object. If you found one,
you would update it, otherwise create a new object. With Unique
Constraints, you don’t have to do this fetch/if/else anymore and save
lots of DB requests while parsing the data.
and Unique Constraints must be strings
So all I want to do is to not have duplicate rows and update the row by it's id.
What approach should I use? Do I have to make ids string like in that blog post or old regular 32 bit integer approach would work too?
The bottom line is you should write code you understand and in a way that others seeing it for the first time can understand.
It's true that core data isn't a relational database, and yet it's a wrapper around one. So if it you can solve your problems using that paradigm, it is simple and understandable, I say go for it. Be prepared to revisit your implementation somewhere down the road. But you'll understand your issues better by then.

What are ways to store complex dynamic objects locally (iOS, swift)?

I have iOS app that takes data from the server as json and then serializes them into objects of different types. Types can be complicated, can contain subtypes, can inherit, so there is no any limitations. Another thing that makes everything even more complicated is some of types are stored as AnyObject? and only in run time they are being serialized into real types accordingly to the specific rules. Something like that:
class A {
var typeName: String?
var b: AnyObject?
}
Then when it's serialized it can be done something like that:
if let someClass = NSClassFromString(typeName) as? SomeGenericType.Type{
b = someClass.init()
}
Also querying should be done on all the data. Currently I'm trying to store all of them locally, then load into memory and query there from the code. I'm using User defaults, but they have some limitations, also I needed to provide custom coding to make it work, and each time when I add a new field it turned out that I missed something in coding and nothing works. So it's pain.
Ideally I would just do some magic command and all the objects are sent to local storage no matter how complicated they are. The same to extract them from this storage. Also, user change data so I can't just store primary Json. And I don't want to covert objects back to Jason as for it's pain too.
Any suggestions?
If you want to use sqlite then You can store whole object in one row! I means you can create table with 2 columns one is id and second is your dataobject(it's data type should be blob). Then convert your whole object into data. Then store in sqlite table and retrieve it as data then convert it to object when want to use. By this way your object will remains in same format as you asked
Firebase while meant for online synching and storage can also cache everything locally in case you are offline and perform query's against the local cache. It uses JSON.
CouchDB also has a mobile version for iOS.
Both of those are over kill if your dataset is small; you can just store it as a text file and read the JSON back in. See performance characteristics here. The graph is for a 7MB file so if you are significantly less than that your load time may be minimal.
NSKeyedArchiver.archivedData(withRootObject:) is great for storing custom objects as Data objects. The only thing you need to do to be able to use this is to make your custom objects conform to NSCoding. A great example can be found here:
Save custom objects into NSUserDefaults
Once you have the Data version of the object, it can easily be stored in UserDefaults, as a property in CoreData, or even in the app's keychain entries. Depending on your use case, sensitivity of data, and how much data you intend to store, you might want to use any number of storage methods. NSKeyedArchiver.archivedData(withRootObject:) allows you to pretty much use any of them.

Are ivars of PFObject subclasses stored in local datastore?

I have a subclass of PFObject called Session. This object stores an array of objects as an instance variable. The array contains objects of type Event, which is also a subclass of PFObject. When I call the pinInBackground on the Session object to cache it locally, will this array instance var also get cached? I understand that caching standard PFObjects stores the data dictionary, but what about subclasses?
Based on the comment from #lightice11 above, I realized that this can be achieved by marking instance vars as #NSManaged, and they will be saved in the Parse Local Datastore.
Make sure you've added the #NSManaged tag to the variable.
Parse will then automatically save changes to the variable, but it does not have a default value. This can be solved in many ways, some of which I outlined here.

Storing an ABRecordRef into Core Data Object [duplicate]

I'm new in iPhone development, can you advice me how to serialize AdressBook records?
I have read stackoverflow - How do I serialize a simple object in iPhone sdk, but I still have questions:
should I extend ABRecordRef? Is it possible? Or should I implement own class NSObject?
(similar question was on Mac forums and was left without answer)
Thank you!
ABRecord is an opaque C type. It is not an object in the sense of Objective-C. That means you can not extend it, you can not add a category on it, you can not message it. The only thing you can do is call functions described in ABRecord Reference with the ABRecord as a parameter.
You could do two things to be able to keep the information referenced by the ABRecord arround:
Get the ABRecords id by ABRecordGetRecordID(). The ABRecordID is defined as int32_t so you can cast it to an NSInteger and store it wherever you like. You can later get the record back from ABAddressBookGetPersonWithRecordID () or ABAddressBookGetGroupWithRecordID(). But aware, the record could be changed or even deleted by the user or another app meanwhile.
Copy all values inside the record to a standard NSObject subclass and use NSCoding or other techniques to store it. You will then of cause not benefit from changes or additions to the record the user could have made.
Of cause you can combine both approaches.

Resources