-1

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?

mimic
  • 4,897
  • 7
  • 54
  • 93
  • You can store it in sqlite or coredata! – Ketan Parmar Jan 08 '17 at 20:26
  • You can also use Realm. It is popular nowadays, and much easier than CoreData. – Axel Jan 08 '17 at 20:30
  • @Lion, I thought about sqlite but it's relational database and my data are not relational, and can't fit any schema. Would it work with sqlite? – mimic Jan 08 '17 at 20:37
  • @Axel, realm is relational storage, will it work for schemaless data? – mimic Jan 08 '17 at 20:38
  • @mimic schemaless data? The only way I know to save it is as JSON String/Dictionary or something similar. Don't do it. This is bad approach. – Axel Jan 08 '17 at 20:45

3 Answers3

0

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

Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
0

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.

Josh Homann
  • 15,933
  • 3
  • 30
  • 33
  • Thanks. The problem with your approach is I have to store objects, not Json - see update. – mimic Jan 08 '17 at 22:15
  • You can convert the object back to JSON with one line in many of the libraries I gave you. For instance in ObjectMapper: Mapper< MyObject >.toJSONString(user, prettyPrint: false). Thats way less coding than individually serializing the properties to a database, relational or not. Incidentally if you ant to do it the long way with firebase and couchDB you can write the key value pairs, just like a relational DB; you are not passing in JSON. it so happens that they use JSON as their internal storage; its irrelevant how your objects are stored in so far as they are correctly reconstructed. – Josh Homann Jan 08 '17 at 23:57
  • I don't know what you mean saying you "gave me many libraries". I saw only one for now - the link you provided - and it required to work with object field by field what I don't want. – mimic Jan 09 '17 at 02:51
0

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.

Community
  • 1
  • 1
Jake
  • 13,097
  • 9
  • 44
  • 73
  • Why did you completely ignore the part related with user defaults in my post? I told that it's pain, when the object is complicated. I've already spent 2 days implementing this logic fixing all the problems on the way and now I'm just to tired to fix it again just because I added some new field that maybe null or so and can't be handled by KeyedArchive without additional efforts. – mimic Jan 09 '17 at 02:48
  • My apologies. I didn't realize you were looking for the silver bullet that solved all our problems as developers. Let me know when you find that so I can look for another job. Cheers :) – Jake Jan 09 '17 at 02:54
  • You are wrong again. You tend to miss and change the sense of what others are writing. It's not very smart imho. – mimic Jan 09 '17 at 04:26
  • And you tend to throw a hissy fit when you don't like people's answers...btw I've done what you're asking using NSKeyedArchiver and CoreData. Just because you don't know how to version your models and handle transitioning from versions doesn't mean my solution wouldn't work. Also if you want "magic", you should look into reflection, specifically for Objective-C, not Swift. It won't be trivial and you'll still have versioning issues in certain situations but that's as close as you will ever get to "magic"...because there is no magic in programming! – Jake Jan 09 '17 at 04:41