For my iPhone app, I'm consuming a RESTful service and getting JSON. I've found libraries to deserialize this into an NSDictionary. However, I'm wondering if there are any libraries to deserialize the JSON/NSDictionary/Property List into my object (an arbitrary one on my side).
The java equivalent would be the object-relational mappers although the sort of object mapping I'm looking for is relatively straightforward (simple data types, no complex relationships, etc.).
I noticed that Objective-C does have introspection so it seems theoretically possible but I haven't found a library to do it.
Or is there a simple way to load an object from an NSDictionary/Property List object that doesn't require modification every time the object changes?
For example:
{ "id" : "user1",
"name" : "mister foobar"
"age" : 20 }
gets loaded into object
#interface User : NSObject {
NSString *id;
NSString *name;
int *age;
}
Take a look at the NSKeyValueCoding protocol. In particular, the methods setValuesForKeysWithDictionary: and dictionaryWithValuesForKeys:
I've made a framework to do this automatically. Check out.
https://github.com/dchohfi/KeyValueObjectMapping
Take a look at the Loid project on Sourceforge. My intent is to provide what you are talking about.
Right now the framework can reverse engineer a Meta description about an Object (such as your "User" object) and can serialize to and from a LoidTypeData object. My intent is to create a LoidTypeData instance from an incoming JSON block and then bind it to the Object. Of course, the reverse will also be there.
It is open source and GPL. You will need to access the code from SVN at the moment, don't quite know how to build distro for Mac.
-- Frank
Related
I'm looking for a way of condensing some of my AS3 code to avoid almost duplicate commands.
The issue is that I have multiple variables with almost the same name e.g. frenchLanguage, englishLanguage, germanLanguage, spanishLanguage
My Controller class contains public static variables (these are accessed across multiple classes) and I need a way to be able to call a few of these variables dynamically. If the variables are in the class you are calling them from you can do this to access them dynamically:
this["spanish"+"Language"]
In AS3 it's not possible to write something like:
Controller.this["spanish"+"Language"]
Is there any way to achieve this? Although everything is working I want to be able to keep my code as minimal as possible.
It is possible to access public static properties of a class this way (assuming the class name is Controller as in your example:
Controller['propertyName']
I'm not sure how this helps to have "minimal code", but this would be a different topic/question, which might need some more details on what you want to achive.
Having said that, I like the approach DodgerThud suggests in the comments of grouping similar values in a (dynamic) Object or Dictonary and give it a proper name.
Keep in mind, that if the string you pass in as the key to the class or dynamic object is created from (textual) user input you should have some checks for the validity of that data, otherwise your programm might crash or expose other fields to the user.
It would make sense to utilize a Dictionary object for a set of variables inherited: it provides a solid logic and it happens to work...
I do not think this is what you are trying to accomplish. I may be wrong.
Classes in AS3 are always wrapped within a package - this is true whether you have compiled from Flash, Flex, Air, or any other...
Don't let Adobe confuse you. This was only done in AS3 to use Java-Based conventions. Regardless, a loosely typed language is often misunderstood, unfortunately. So:
this["SuperObject"]["SubObject"]["ObjectsMethod"][ObjectsMethodsVariable"](args..);
... is technically reliable because the compiler avoids dot notation but at runtime it will collect a lot of unnecessary data to maintain those types of calls.
If efficiency becomes an issue..
Use:
package packages {
import flash.*.*:
class This implements ISpecialInterface {
// Data Objects and Function Model
// for This Class
}
package packages {
import...
class ISpecialInterface extends IEventDispatcher
I have been really deep thinking about a general way of creating "data model", and been jiggling with best practices and MVC pattern. Currently I am using a singleton pattern to get my httprequest and json parser (which comes as NSDictionary). Now rather than accessing this parser directly, I was hoping to make a Data model that can be binded through this.
However, I have been struggling if there is an easy way to do that rather than assigning manually "[myObj setValue:[jsonDict objectForKey:#"name"]];" where myObj tends to be a simple NSString object.
Since NSDictionary is a nice KVC concept, how can I utilize this to enrich a better style of data model in which I can generally access myObj.name or myObj.address entity than "[myObj setValue:[jsonDict objectForKey:#"name"]];" behavior.
I have looked into "Core Data" model, however the current design doesn't require to store anything locally, but just within memory for security reasons.
Any good ideas or best practices solution here will be really helpful.
Just create your classes. Then crate an class that will serialize the data from your dictionaries to your object.
Let say you create an class Person that has properties firstName and lastName. Then you crate a Class like PresonController, that will do manage the person objects, and in it create class methods like
+(Preson *)personFromDictionary:(NSDictionary)peseonDictionary;
And every time you need to create an person from an dictionary you will do
Person *newPerson = [PersonController personFromDictionary:yourPersonDictionary];
And then in the code you just access the properties of the Person object
NSLog(#"Person first name:%#",newPerson.firstName);
Hope I was clear enough for you.
NSManagedObject *entryObj = [self.fetchedResultsController
objectAtIndexPath:indexPath];
entryObj consists of four String attributes.
If I NSLog entryObj, I get the information I want. I cannot figure out how to access each of these properties individually. I read a similar post where the solution was to call "entity." I cannot figure out how to use "entity" to access a specific attribute.
Any ideas? References? Tutorials?
Thanks in advance.
Properties on managed objects are KVC/KVO compliant so you can access them via:
[entryObj valueForKey:#"name"]
Alternatively you can generate a custom Core Data class with real properties to access these values. See this documentation for more information. The Xcode core data modelling tool can generate these classes for you. While you have the model open, choose "File->New File" and you should see a "Managed Object Class" item. Choose this and select the entities you wish to generate classes for.
Once you have done this and the core data entities have their class name set appropriately, you just cast the NSManagedObject to an instance of your new class and access its properties, i.e.
MyObject *entryObj = (MyObject *) [self.fetchedResultsController
objectAtIndexPath:indexPath];
NSLog(#"Property is %#", entryObj.whatever);
If you build your NSManaged objects with the designer then you can export model classes. From the xcdatamodel do File/New File then pick CocoaTouch Class/Managed Object Class. Next then Next then tick each of your classes. Leave generate accessors and generate obj-c 2.0 properties ticked and click finished.
Now you can include the generated files in your projects and use dot accessor syntax.
Alternatively use [entryObject valueForKey:#"keyname"]; but I prefer to stick to the dot accessor syntax where possible.
For generating real classes with properties to call from your object model, I highly recommend using mogenerator:
http://github.com/rentzsch/mogenerator
That's the main project, but the easy to download installer is here:
http://rentzsch.github.com/mogenerator/
You also get primitive value accessors for numeric types, for free.
I'd like to know if it is possible to hide library implementation from consumers of a static library.
This great thread spawned a few questions in regards to a licensing system for static libraries: Licensing system for static library. The scheme I'd like to use is:
Give consumer a license key they put into a plist
plist is deployed
strong key is generated off of bundle identifier and matched against key in plist
Here is why that system is flawed: I need to run an algorithm (for strong key generation on the fly) that then outputs some string. The problem is I must include header files for the library to be used. At this point, anyone using the library can step into implementations. If I have a method named checkLicense(), a consumer of the library can step into that method and see how the strong key is being generated.
Also, for static methods, am I to run the key generation every time since there isn't any state? I could probably use a singleton and call it in each static method call?
My main problem is that implementation can be seen within a static library if you have the header files. Is there some way of hiding implementation?
Assuming this static library you are creating is written in Objective-C, one method you could use is to create an anonymous category of your class in your implementation file (not your header). In that category, declare your sensitive methods and then just implement them in your class like normal. This makes it so you don't have to expose those methods in your public headers.
For example, in SomeClass.m:
#interface SomeClass (/*Secret stuff*/)
- (BOOL)validateRegistration:(NSData *)key;
#end
#implementation SomeClass
// Other methods....
- (BOOL)validateRegistration:(NSData *)key { /* ... */ }
#end
Notice that this is an anonymous category because I haven't given the category a name (that's just a comment inside the parentheses). This makes it so you don't have to declare a separate implementation block specifically for that category's implementation, which helps hide those methods a little further.
I'm writing an iphone application with JSON and am trying to turn JSON strings into objects (NOT Dictionaries or Arrays).
In Java, thanks to Reflection, I can easily turn JSON into javabean instances like this:
import net.sf.json.JSONObject;
class MyBean {
private String property;
public String getProperty() { return property; }
public void setProperty(String property) { this.property=property; }
}
// turn JSON string into a MyBean instance
String str = "{\"property\":\"some value\"}";
JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( str );
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setRootClass( MyBean.class );
MyBean instance = (MyBean) JSONSerializer.toJava( jsonObject, jsonConfig );
I was wondering if this was possible in objective-c. I am currently using this JSON framework but am willing to switch if necessary.
Thanks,
There is an open source project called objectiveresource and objectivesupport. They are partial Objective-C implementations of a what is called ActiveResource and ActiveSupport in the Ruby and RESTful development world. Part of what objectivesupport does is serializing and deserializing JSON (as well as XML) object. If you don't want to use the full frameworks as is, you can take a look at the source code for objectivesupport and there you will see their implementation of serializing to/from an NSObject. The specific code you want to look at are listed below: (Basically implemented as a category on the NSObject, NSArray and NSDictionary types)
http://github.com/yfactorial/objectivesupport/tree/d08b5be6c0f7a2b0196b6ec17e4441bb146c4e23/Classes/lib/Serialization/JSON
BTW, they seem to be using a fork of the same JSON framework that you are using.
Maybe looking at the Objective-C Runtime Reference could help you !
There are some functions (like class_createInstance and object_setInstanceVariable) that could help you.
You might want to checkout my implementation for serializing and deseriazling JSON to NSObjects and vice versa. - https://github.com/mahadevans87/OBJC_JSONSerializer
Just in case anyone else gets here when looking for an answer to this question, there's another project that has exactly what you're looking for: JSON for iPhone, and nothing else.
Have a look at here