Objective C class model generator from JSON - ios

I need an app or an online converter like JSON Accelerator that generates Objective C classes from JSON strings. I had some issues with this app, some JSON's are converted OK others are not. There are a lot of properties, it would take ages to write them down manually and use tools like JSON Model or similar. Thanks in advance.

You are much better off creating a class that can be initialized from an NSDictionary and that way you can parse the JSON to an NSDictionary, in the traditional way, and then create your class from that dictionary. You can also create arbitrary instances of the custom class and initialize the properties piece-meal.
#interface MyClass : NSObject
#property NSString *name;
#property NSUInteger age;
- (instancetype)initWithDictionary:(NSDictionary *)dict;
#end
#implementation MyClass
- (instancetype)initWithDictionary:(NSDictionary *)dict
{
self = [super init];
if (self) {
_name = dict[#"name"];
_age = [dict[#"age"] unsignedInteger];
}
return self;
}
#end

you can use thus toll to get objc object from json
http://www.realmgenerator.eu/
and also you can use these mapper to get our result
https://github.com/aryaxt/OCMapper

Related

Custom object to NSMutableDictionary

I would like to add a custom object to NSDictionary. It should store three variables: two strings and a boolean.
I read around the net and found NSCoder to be the way but I dislike the result. By using [dictionary setObject:[NSKeyedArchiver archivedDataWithRootObject:customObject]] I end up with NSData information instead of human readable text. My target is to make it readable for human eyes. I do not want to encode the object into binary data.
To make it a little bit more complicated I would like to add my objects inside NSArray. For testing purposes I tried to add NSStrings to NSArray and to invoke [NSDictionary dictionaryWithObject:array forKey:#"myKey"]. The result is perfect. It is readable for human. I would like to add my custom object instead of the NSString.
Desired result should look something like this:
{
TextStrokeColor = "UIDeviceWhiteColorSpace 0.5 1";
TextStrokeWidth = 0;
MyObjects = (
MyCustomObject = {
name = "name";
boooool = 0;
description = "";
}
, ... other objects );
}
What should I use? I do not really get the difference and the use for NSCoder, NSCoding, NSCopying.
I need to be able to edit the text file later on the disk. By having binary representation I cannot. But seems there is no straightforward method.
You can simply use arrays, dictionaries, strings, numbers, dates (anything which can be written into a plist or JSON).
The question is wether this is done solely during 'archiving', or whether your in-memory representation is also arrays and dictionaries. You can also create a custom class which either uses a dictionary internally to store the data and archives / reloads from that dictionary, or the custom class is a standard class with properties and creates a dictionary on-the-fly when archiving or reloading.
Note that when using a keyed archiver, it can support setting the outputFormat to NSPropertyListXMLFormat_v1_0 for some use cases, so once your custom class implements archiving to plist data types you can easily archive the container to a plist (JSON will require more leg work from you to collate the data into true containers).
Have you tried actually creating a custom object by just making a class?
#interface MyCustomClass : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) BOOL boolValue;
#property (nonatomic, strong) NSString *description;
#end
#implementation MyCustomClass
// put any implementation methods here
#end
Then you can add it to an NSArray or an NSDictionary as you would with any other class.
MyCustomClass *myObject = [MyCustomClass new];
myObject.name = #"name";
myObject.boolValue = YES;
myObject.description #"a description";
[myMutableArray addObject:myObject];
myMutableDictionary[#"some key"] = myObject;

How to Pass Parameter to external class method?

I am trying to do very simple operation.
in "TestFile.h" file i've declare property:
#property (nonatomic) NSDictionary *justTest;
and in implementation file "TestFile.m":
-(NSDictionary *)justTest:(NSString *) mystring {
NSLog(#"Here is my string: %#", mystring);
return nil;
}
Now i am trying to call "justTest" from another file. What i am doing:
#import "TestFile.h"
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSDictionary *testFile = [[TestFile alloc] init];
[testFile justTest:#"Hello World!"]
}
This works fine until i'm trying to pass parameter.
if i just execute
[testFile justTest];
it works, but when i try to pass parameter
[testFile justTest:#"Hello World!"];
does not work and the debug message is:
no visible #interface for 'TestFile' declares the selector 'justTest':
What is wrong with me?
You need to make this method public by adding method name to TestFile.h file before #end:
-(NSDictionary *)justTest:(NSString *) mystring;
Just to let you know when you add #property compiler synthesise it (create) two method getter, exactly the same name as your property and setter compiler add 'set' prefix, for example, you declare:
#property (nonatomic) NSDictionary *justTest;
compiler will create two methods:
-(NSDictionary *)justTest {...}
-(void)setJustTest {...}
You need to know that in your code you override the getter method.
Declare your method in TestFile.h file before calling from an external class.
-(NSDictionary *)justTest:(NSString *) mystring;

Objective C: allow properties in category via custom root class

There are many questions concerning the category-properties problem.
I know some possibilities to address this:
use a singleton registry
objc_setAssociatedObject and objc_getAssociatedObject
From my point of view both is not clean since the memory allocated is never cleared when the object that created such properties is deallocated.
Categories are a good way to keep code clean and dynamically add functionality to already existing classes. They help to group functionality and to distributed implementation work among more developers.
The bad about categories is the missing storage.
I came across this problem several times now and I'm wondering whether the following would address this problem in an clean way that also takes care about the memory and if there are any problems that I can't see right now.
There is one restriction, that I can ignore since I'm working as a framework developer: I'm able to create my own root class that all my other classes can inherit from.
First of all declare the new root object:
#interface RootObject : NSObject
- (void)setRuntimeProperty:(id)runtimeProperty forKey:(id<NSCopying>)key;
- (id)runtimePropertyForKey:(id)key;
#end
With the corresponding implementation:
#import "RootObject.h"
#interface RootObject ()
#property (readwrite) NSMutableDictionary *runtimeProperties;
#end
#implementation RootObject
#synthesize runtimeProperties = _runtimeProperties;
- (id)init {
self = [super init];
if (self)
{
_runtimeProperties = [[NSMutableDictionary alloc] initWithCapacity:1];
}
return self;
}
- (void)dealloc {
[_runtimeProperties release];
_runtimeProperties = nil;
[super dealloc];
}
- (id)runtimePropertyForKey:(id)key {
return [self.runtimeProperties objectForKey:key];
}
- (void)setRuntimeProperty:(id)runtimeProperty forKey:(id<NSCopying>)key {
if (key)
{
if (runtimeProperty)
{
[self.runtimeProperties setObject:runtimeProperty forKey:key];
}
else
{
[self.runtimeProperties removeObjectForKey:key];
}
}
}
#end
By using this RootObject instead of NSObject it should be very easy to add a "property" to a category on a class. Consider having some class MyClass
#interface MyClass : RootObject
// some interface here
#end
When implementing a special behavior on top of this class you are now able to add a property like this:
#interface MyClass (specialBehavior)
#property (nonatomic, retain) NSString *name;
#property (nonatomic, copy) NSDate *birthday;
#end
With corresponding implementation:
#implementation MyClass (specialBehavior)
#dynamic name;
- (NSString *)name {
return [self runtimePropertyForKey:#"name"];
}
- (void)setName:(NSString *)name {
[self setRuntimeProperty:name forKey:#"name"];
}
#dynamic birthday;
- (NSDate *)birthday {
return [self runtimePropertyForKey:#"birthday"];
}
- (void)setBirthday:(NSDate *)birthday {
[self setRuntimeProperty:[birthday copy] forKey:#"birthday"];
}
#end
Such an implementation could KVO compatible as well by just adding the necessary calls in the setter method.
Very straight forward, but I'm wondering whether I missed something important? (E.g. very very bad runtime performance having many such declared properties or using many of these objects)
This is effectively the same as objc_setAssociatedObject and objc_getAssociatedObject, which do release memory when the object is deallocated (depending on the association type). I would guess they also have much lower overhead than your suggested code.

object sharing among view controllers

I was wondering how can I share a NSDictionary objects among several view controllers which basically are tabs in my application.
I tried using a protocol, like in Java, so that I can cast to the protocol and access the property. That doesn't seem to work.
Also I had a look at similar question at
How to share data globally among multiple view controllers
But I observed that the appDelegate method is not safe and may lead to memory leak.
Similarly injection on class A into class B will create the same problem.
So can anyone suggest me any method which i should study or implement in my code?
If you wants to share only Dictionary, why don't you go for class method using from helper class.
+(NSDictionary *)shareMethod
{
return dict;
}
You can use singleton class for sharing the data
Check this Singleton class
MyManger.h
#import <foundation/Foundation.h>
#interface MyManager : NSObject {
NSMutableDictionary *_dict
}
#property (nonatomic, retain) NSMutableDictionary *dict;
+ (id)sharedManager;
#end
MyManger.m
#import "MyManager.h"
static MyManager *sharedMyManager = nil;
#implementation MyManager
#synthesize dict = _dict;
#pragma mark Singleton Methods
+ (id)sharedManager {
#synchronized(self) {
if(sharedMyManager == nil)
sharedMyManager = [[super allocWithZone:NULL] init];
}
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
dict = [[NSMutableDictionary alloc] init];
}
return self;
}
You can access your dictionary from everywhere like this
[MyManager sharedManager].dict
I found a way out. Since I want a dictionary to be shared across, I declared a method in my protocol
- (void) setSingleHouse:(NSDictionary*) singleHouse;
In each of my controller I implemented the method in a appropriate manner. Hence I was able to share across them for now.
Also I figured out that I was casting in a wrong way earlier i.e (#protocol(protocol name)). Now changed it into NSObject .
Sorry for the fuss.
I advise you not to use a property in your appDelegate instance. This pattern doesn't improve code reusability.
Basicly your shared NSDictionnary is your model. So, if you want your code to follow the MVC design parttern, you should create a class with a shared instance that would contain your NDDictionnary in a public property.
This is well explained in this post
This way, you will access your shared NSDictionnary this way
:
NSDictionary* sharedDictionnary = [MyModel sharedInstance].sharedDictionary;

How to access public instance variable in Objective-C?

I am having following condition:
#interface MyClass:NSObject
#public NSString *str;
#end
#implementation
-(id)init{
}
#end
Now I want to access str variable outside MyClass in Other Class, (1) Using MyClass Object (2) without using MyClass Object, How can I achieve that?
You can call using this:
MyClass *a;
a.str;
Without the object, you cannot call an instance variable. However, you can call static method with this declaration:
#interface MyClass:NSObject
+ (void)doX;
#end
#implementation
+ (void)doX {
// do whatever
}
then in another class you just need to call:
[MyClass doX];
However, let a public instance variable is not a good practice. The reason is that it will let any class, methods change that instance variable without your control. For example, they can set the NSString *str to nil and then nobody can call anything, or they may forget to do memory management when they call.
A better practice for public variable is using #property
For example, your string should be declared like:
#property (nonatomic, retain) NSString * str;
and then in the implementation:
#implementation MyClass
#synthesize str;
The good thing about property is that compiler will generate gettter and setter methods for you and those setters will handle memory correctly for you.
More about properties here
Sigh, i realise this post is LONG dead but I believe The above answer is incorrect.
well the first bit.
Please see the link below.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW1
for the above interface to work, you NEED to declare a property for use outside of its class
Because the instance variable it is not visible outside its class.
well; You don't NEED to. Doing something like MyClass->str is valid.
Please see this example
#interface Foo : NSObject {
#public NSInteger publicMember;
#private NSInteger aproperty;
}
#property (assign) NSInteger aproperty;`
then the calling class
Foo *f = [Foo new];
f.aproperty = 90;
//f.publicMember = 100; property 'publicMember' not found of type Foo *
f->publicMember = 100;
But as the above post said, you should always use #properties because if var public was a string, you are not retaining the string in any way.

Resources