I am looking to create / instantiate the levels and level enemies of a game I'm creating from an xml file at runtime that I will initially edit by hand until I have time to create a level editor. Once I have time to make the editor, I wish to automatically serialize and save my levels to disk. My enemy class uses CGPoints, floats and enums, along with basic datatypes like NSString.
Being new to objective-c, I am having trouble working out the most efficient way of doing this. NSPropertyListSerialization appears to only support basic data types and from reading the docs, it looks as though NSCoder serialises / deserializes using its own format.
Any advice is appreciated.
This library enables you to save any object to a property list and this one to JSON without making any additional effort. If you're wondering how they work, have a look at the Archives and Serialization Programming Guide.
Related
I'm currently struggling with the experimental KXS-properties serialization backend, mainly because of two reasons:
I can't find any documentation for it (I think there is none)
KXS-properties only includes a serializer / deserializer, but no encoder / decoder
The endpoint provided by the framework is essentially Map<String, Any>, but the map is flat and the keys already have the usual dot-separated properties syntax. So the step that I have to take is to encode the map to a single string that is printable to a .properties file AND decode a single string from a .properties file into the map. I'm generally following the Properties Format Spec from https://docs.oracle.com/javase/10/docs/api/java/util/Properties.html#load(java.io.Reader), it's not as easy as one might think.
The problem is that I can't use java.util.Properties right away because KXS is multiplatform and it would kinda kill the purpose of it when I'd restrict it to JVM because I use java.util.Properties. If I were to use it, the solution would be pretty simple, like this: https://gist.github.com/RaphaelTarita/748e02c06574b20c25ab96c87235096d
So I'm trying to implement my own encoder / decoder, following the rough structure of kotlinx.serialization.json.Json.kt. Although it's pretty tedious, it went well so far, but now I've stumbled upon a new problem:
As far as I know (I am not sure because there is no documentation), the map only contains primitives (or primitive-equivalents, as Kotlin does not really have primitives). I suspect this because when you write your own KSerializers for the KXS frontend, you can specify to encode to any primitive by invoking the encodeXXX() functions of the Encoder interface. Now the problem is: When I try to decode to the map that should contain primitives, how do I even know which primitives are expected by the model class?
I've once written my own serializer / deserializer in Java to learn about the topic, but in that implementation, the backend was a lot more tightly coupled to the frontend, so that I could query the expected primitive type from the model class in the backend. But in my situation, I don't have access to the model class and I have no clue how to retrieve the expected types.
As you can see, I've tried multiple approaches, but none of them worked right away. If you can help me to get any of these to work, that would be very much appreciated
Thank you!
The way it works in kotlinx.serialization is that there are serializers that describe classes and structures etc. as well as code that writes/read properties as well as the struct. It is then the job of the format to map those operations to/from a data format.
The intended purpose of kotlinx.serialization.Properties is to support serializing a Kotlin class to/from a java.util.Properties like structure. It is fairly simple in setup in that every nested property is serialized by prepending the property name to the name (the dotted properties syntax).
Unfortunately it is indeed the case that this deserializing from this format requires knowing the types expected. It doesn't just read from string. However, it is possible to determine the structure. You can use the descriptor property of the serializer to introspect the expectations.
From my perspective this format is a bit more simple than it should be. It is a good example of a custom format though. A key distinction between formats is whether they are intended to just provide a storage format, or whether the output is intended (be able to) to represent a well designed api. The latter ones need to be more complex.
I need to convert json to objective-c object. I mean not parse it in code, but generate the code of the object by some json. Are there some tools for it? I know how to do it in java(jsonpojo).
Also i wonder if there is a certain way to automatically store data from json to a real objective-c Object without manual parsing.
In Java its done by Gson library.
It looks like you are describing exactly what ROAD iOS Framework. Take a look: https://github.com/epam/road-ios-framework
The tool for generating plain model classes from JSON is ROADClassesGenerator and if you will use ROAD for networking then serialization into generated classes comes for free.
One note, it's not actively supported now, due to pervasiveness of Swift and the fact if its tight reliance on macros which are still poorly supported in Swift, but it's still work and do the job nevertheless.
I was talking to several developers which approach is best in objective C according to latest trends?
For example: if i am populating data from server in json form, which approach should i use?
I have seen my friends populating data into json objects in past as well as fewer of them in NSdictiory,NSMututable Dictionary, what apple recommends data structure wise?
any help would be appreciated.
I personally greatly prefer custom objects (or Structs for Swift) because it lets me more easily tell what properties the objects have. If you are just passing around dictionaries it makes it much harder (in my opinion) to remember what object you have, what keys it has, and maybe what nested objects it has too. Whereas if you have named classes (again, these ought to be Structs in Swift), then you (and the compiler) can easily know what properties they have. Plus you can easily create instance methods for your objects.
And if you don't want the pain of parsing them yourself there are frameworks that will manage parsing the server response into objects (e.g. RestKit https://github.com/RestKit/RestKit).
If you consider example code from Apple as a "recommendation" from Apple, you can see the way they make a data model in their "Start Developing iOS Apps" here: https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson6.html. Yes the example is for Swift but most concepts are comparable.
Apple also has "Cocoa Core Competencies" (https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ModelObject.html) where they define a modal object as "typically a subclass of NSObject or...a subclass of NSManagedObject."
I'm trying to write/read a class object from/to a file.
I'm new to D and I just want to play a little bit around with it.
Is there a Class/Function to write/read an object to/from a file?
I'm looking for something similar to the ObjectOutputStream сlass in Java.
Or do I have to serialize (concatenate) the object's variables as strings in the file?
I have a Movie class and a MovieManager class, which contains a dynamic movie-array.
A Movie object contains just a few strings and integer values.
Extending answer, provided in comment, it is worth explicitly stating, that D does not provide "one true way" of reading/writing objects to/from files, as there can't be a single optimal one. Different considerations about speed, resulting file format, handling references and similar corner cases may results in different serialization strategies.
That being said, most likely proper serialization library is needed, and, by lucky chance, one of most mature D solutions ("Orange" by Jacob Carlborg https://github.com/jacob-carlborg/orange) is being reviewed right now as a candidate for inclusion into standard library as a std.serialization: newsgroup thread. It may be your best bet.
The library Unmanaged provides a serialization system. You also have Orange
which is less restrictive, as Unmanaged serialization only works if the object to serialize is an ancestor of one of the framework base class.But...Unmanaged works on the "accessor" principle. The data serialized are get via a method and the data deserialized are set via a method, which allows to update some stuffs when the deserializer recall for example...
I have a large MKOverlay that I would like to be saved in Core Data so that I don't have to create it later. Since this isn't one of the types that you can choose in Core Data, how do I go about saving it?
Do I need to somehow encode it first?
Do I then need to decode it when using?
What kind of object do I select in core data when creating a new property?
Thanks guys.
If you do not need to query for different overlays and you're not using core data elsewhere in your project, then you're probably better off caching the overlay on disk as an encoded NSArray.
However, if you're already using Core Data or you're caching multiple overlays then you can encode/decode the overlay in a field of type NSData. Add additional fields to the entity so you can query for the specific overlay you're looking for.
In iOS 5, you can enable optional storage of NSData fields in an external file by selecting the "Allows External Storage" option. Core Data will apply a size-based heuristic to determine if a blob or external file will result in better performance.
MKOverlay conforms to NSCoding, so you can encode and decode an entire array of MKOverlay objects using an encode method of NSKeyedArchiver and store the result in a binary field in your entity. You'll likely want + (NSData *)archivedDataWithRootObject:(id)rootObject on NSKeyedArchiver and + (id)unarchiveObjectWithData:(NSData *)data on NSKeyedUnarchiver
See the Archives section in the Archives and Serializations Programming guide for details of creating a keyed archive at: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Archiving/Articles/archives.html
You can write a custom accessor for the entity's binary field that encodes and decodes the overlay array for you. Another option is to create a value transformer that encapsulates the encoding and decoding operations. The end result would be an overlays array property that you can set and read via entity.overlays.
I believe you can use Apple's NSCoding libraries to convert the object to and from a serialized state. However, Core Data may support saving objects, but NSCoding lets you save any class that implements it anywhere, including a string sent to a server, a file written to disk, or if you're as bad a programmer as me, an NSUserDefaults entry.
edit- You may have to implement NSCoding into your own class based on MKOverlay by adding read and write methods, I'm uncertain.
Why not instead save the properties (size, color, coordinates, etc can all be described with NSNumbers and those can be stored in Core Data natively) and recreate the MKOverlay when needed. I think that's a much more efficient approach to be honest. I'm not sure how much of an impact creating an object has, so prove me wrong if I'm wrong.
You need to take the large dataset that composes the overlay and turn those individual data nodes into NSManagedObjects to be stored in CoreData.
I mean, you probably COULD just NSCoder the entire thing into one giant datablob, but at that point, you might as well just write the thing to a flat file (which frankly might be better if all you want to do is read/write it without changing it).
Don't use Core Data unless you're going to be doing legit querying or piecemeal changes to the dataset.