There are a number of questions and answers on SO that ask how do I serialise an object to in objective c.
Serialize and Deserialize Objective-C objects into JSON
Objective C serialize list of complex objects
Serialize custom object to JSON which contains NSMutableArray
How to serialize a class in IOS sdk (Objective-c)?
The following 3 methods are all mentioned in the above links.
1) Use NSJSONSerialization to serialise the object to JSON. Seems good but this requires the object in question to be either an array or dictionary at its top level. Common solution is to declare custom toDictionary or serialise method that loops over the properties and sets the relevant key and values.
2) Conform to the NSCoder protocol, a little like the approach above but there seems to be some confusion around whether or not this can serialise to JSON or just to NSData.
3) Third party library.
I'm getting slightly confused as to what approach to take. I want to serialise to JSON, there are contradictory answers some stating you can use NSCoder some saying not. I know that a third party app will work however I'd rather implement something simple like options 1 or 2.
Thoughts?
With 1, you'd basically be writing a JSON-based implementation of NSCoder from scratch. Certainly doable, though.
With 2, I believe it might be possible, since I think the output of NSCoder is some variant of XML (though compressed into a binary blob). However, I don't know if this is a great approach, since the format is proprietary and not really meant to be human-editable. There might also be a mismatch between what's allowed in JSON vs. the NSCoder format in terms of keys and leaf nodes, forcing you to do a messy conversion.
I've been trying to do something similar, and based on my research, I actually suggest 3. Using something like Mantle — a stable, polished framework that gets frequent updates — you can specify exactly how your model objects will be serialized to and deserialized from JSON. It even supports the NSCoder protocol as an option! (This is effectively solution 1, but vetted and maintained by a 3rd party.)
Related
I'm just integrating Siesta and I love it, it solves a lot of issues we have when using frameworks like RestKit.
What I can't get my head around is how to use the content transformers? I've looked at the docs and examples and I can't quite understand how it works, I'm also fairly new to Swift.
Looking at this example taken from another SO reply:
private let SwiftyJSONTransformer = ResponseContentTransformer(skipWhenEntityMatchesOutputType: false) {
JSON($0.content as AnyObject)
}
I can't quite understand what's going on here, there is no return value so I don't understand how content is being transformed. This might be my due to a lack of deep Swift knowledge.
I've understand how NSValueTransformer objects work in Obj-C but I can't work out how to map a response abit JSON or just a simple response body like a single string, number of boolean value to a object or type using Siesta.
We have some API responses that return just a single BOOL value in the response body while most of the other API responses are complex JSON object graphs.
How would I go about mapping these responses to more primitive types and or more complex objects.
Thanks.
Some of your confusion is basic Swift stuff. Where a closure uses $0 and contains only a single statement, the input types are inferred and the return is implicit. Thus the code in your question is equivalent to:
ResponseContentTransformer(skipWhenEntityMatchesOutputType: false) {
(content: AnyObject, entity: Entity) in
return JSON(content)
}
(Using $0.content instead of just $0 is a workaround for a maybe-bug-maybe-feature in Swift where $0 becomes a tuple of all arguments instead of just the first one. Don’t worry too much about it; $0.content is just a magic incantation you can use in your Siesta transformers.)
The other half of your confusion is Siesta itself. The general approach is as follows:
Configure a generic transformer that turns the raw NSData into a decoded but unstructured type such as String or Dictionary.
You’ll usually configure this based on content type.
Siesta includes parsing for strings, JSON, and images unless you turn it off with useDefaultTransformers: false.
Optionally configure a second transformer that turns the unstructured type into a model.
You’ll usually configure this based on API path.
Siesta doesn’t include any of this by default; it’s all per app.
For responses that are just a bare boolean, you’d probably do only #1 — depending on exactly what kind of response the server is sending, and depending on how you know it's just a boolean.
I recommend looking at the example project included with Siesta, which gives a good example of how all this plays out. You’ll see examples of both transformers that conditionally operate on the content based on its type (#1) and model-specific tranformers (#2) in that code.
I was wondering if I can I use encode/decode with an NSManagedObject. Can I use that or I need a NSObject?
It does't make a lot of sense to do so. Technically you can implement the methods, but you need to think carefully about what they do. You could use them to create a binary representation of the object, but it might not be meaningful for what you want to use it for. And, when reading that data back in, you could implement it to search some context and return an existing object or insert a new one if it's missing. You have the problem of supplying the context to be used to deal with...
So, while you might be able to do it, it probably isn't the correct approach to be taking.
I'm working on writing my own Objective C wrapper around a minimal set of OpenAL functionality. One use case I'm trying to enable is transport controls after telling a sound to play like pause/stop/resume operations. I'm interested in trying to do this using what has been described to me as an "opaque type" or an id that conforms to a protocol in Objective C lingo. Does returning one of these make sense in this case, or would it be easier to just directly return an object and tie myself to that implementation?
And assuming the opaque type is the right approach, what would be a good name for the protocol? Right now I'm following this paradigm and calling the protocol OpenALPlaybackDelegate. I feel as if delegate doesn't really quite fit the model since the communication is happening the other way around.
An opaque type in this case is basically just a pointer that's used in Apple's C APIs in place of an object. Unlike a normal pointer to a struct full of stuff in C, the opacity in 'opaque types' comes from the fact that the header files don't expose the struct definition. The only way to deal with them is through the C functions that are exported. You see this in two places:
C APIs: Core Graphics, Core Audio, Core Foundation, Grand Central Dispatch. C has no objects. Apple has a bunch of types like CGFoobarRef that represent pointers to some sort of thing made with a function like CFFoobarMake();
Bridged APIs. Cocoa functionality is made available to C code through "the toll-free bridge", so you can generally get a handle on a say an instance of a Cocoa class in C world as an opaque type. Again, these generally end with Ref. All the Cocoa container classes, for instance, are available to C consumers through the Core Foundation toll-free bridge.
Relevant Apple documentation
If the consumers of your protocol are Objective-C libraries, which I'm going to assume they are, because that's the only way to use protocols, then no, it doesn't really make sense to expose access to any of your stuff as an pointer to a C struct filled with data and function pointers that are hidden from client code and exposed through a set of C functions.
Also, the reason to do this, for Apple, is encapsulation, data-hiding, etc. All it does is keep people from being able to muck about directly with the internal state of an object from C land, or write code that depends on it, because C lacks features like classes and ivars (well, Objective-C doesn't really have private ivars either but it at least has secret ones).
I would think writing an Objective-C wrapper around OpenAL, exactly what you would not want to do is return opaque types. You should return Objective-C objects that hold opaque type references with accessors/mutators that call the relevant functions on those references.
The problem is whether an instance method should in anyway alter the object that contains the method or should it return a new instance? I'm new to F# and the concept of full mmutability that is suggested for F#.
Just using psuedo code for now unless I need to be more specific.
First thought is just add the message to the message list on the object:
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
_messages.Add(message)
Second is to construct a new list that joins the old list and the new message. Then I would create a new instance altogther and send back.
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
newMessageList = _messages.Join(message)
return new Something(newMessageList)
Am I overthinking immutability?
In my opinion, the answer depends on your requirements. The immutable style is probably more idiomatic, and would be a sensible default. However, one nice thing about F# is that you can choose what to do based on your needs; there's nothing inherently wrong with code that uses mutation. Here are some things to consider:
Sometimes the mutable approach leads to better performance, particularly when used in a single-threaded context (but make sure to measure realistic scenarios to be sure!)
Sometimes the immutable approach lends itself better to use in multi-threaded scenarios
Sometimes you want to interface with libraries that are easier to use with imperitave code (e.g. an API taking a System.Action<_>).
Are you working on a team? If so, are they experienced C# developers? Experienced F# developers? What kind of code would they find easiest to read (perhaps the mutable style)? What kind of code will you find easiest to maintain (probably the immutable style)?
Are you just doing this as an exercise? Then practicing the immutable style may be worthwhile.
Stepping back even further, there are a few other points to consider:
Do you really even need an instance method? Often, using a let-bound function in a module is more idiomatic.
Do you really even need a new nominal type for what you're doing? If it's just a thin wrapper around a list, you might consider just using lists directly.
As you are doing "class based" programming which is one of the way (rather unfortunate) to do object oriented programming, you would be doing in place state modification rather than returning a new state (as that's what would be expected when you are doing OO).
In case you really want to go towards immutability then I would suggest you need to use more FP concepts like Modules, Functions (not methods which have you have in class based programming), recursive data types etc.
My answer is way too general and the appropriate answer lies in the fact that how this class of your will fit in the big picture of your application design.
Is it possible to serialize a hierarchy of objects in Flex, send the binary data to a URL for storage/retrieval on/from a server, and deserialize the data to restore the objects' original state?
I know it's possible to convert the objects into an XML format (haven't tried it yet), but I'm hoping to avoid parsing XML and rebuilding the objects manually. It would be nice to have functionality which can serialize/deserialize objects to a simple binary format (I did something similar in the past in Java, though not quite as easily as I would have liked). The 'eval' function in Perl is similar to what I'm looking for, sans saving code, of course.
In pseudo-code, here's what I would like to do:
private var contentToSave:HBox = new HBox();
private function saveState(event:Event):void {
var toSave:HBox = this.contentToSave;
var data:? = /* serialize 'toSave' ActionScript classes to binary data*/;
sendDataToServer(data, filename);
}
private function restoreState(filename):void {
var data:? = getDataFromServer(filename);
var savedData:HBox = /* deserialize binary 'data' to ActionScript classes */;
this.contentToSave = savedData;
}
Take a look at ByteArray.writeObject(). which saves the passed object in AMF format into the byte array. I have not used this function too much, I don't exactly know what kind of objects it can serialize, but definitely not all.
Try the JSON based serialization package in ascorelib.
[...]but I'm hoping to avoid parsing XML and rebuilding the objects manually
AS handles XML just like any other native type. Rest assured. XML is the preferred way of dealing with data you will be pulling off and putting back on a server. Of course, the ascorelib gives you a JSON class -- so you may want to look at that as well.
The 'eval' function in Perl is similar to what I'm looking for, sans saving code, of course.
IIRC, eval is part of the ECMAScript specification (and you will find it in Javascript). But not in AS3.0. It was there to a certain extent in some previous version(s?) but is no longer supported.