How to serialize a custom object with JSONModel ?
#property(nonatomic,strong) NSString<Optional> * tag_post_type;
#property(nonatomic,strong) NSString<Optional> * tag_users_type;
#property(nonatomic,strong) NSArray<Optional> * tags;
#property(nonatomic,strong) NSMutableArray<TagMediaModel*>* tag_posts;
#property(nonatomic,strong) NSMutableArray<TagLocationModel*>* locations;
I try to create a JSON file out of my custom Object with the JSONModel framework for iOS. I get the Error:
EXCEPTION: Invalid type in JSON write (TagMediaModel)
When I call toJSONString Method, I got this issue.
[tagAutomaticModel toJSONString];
This is the model data:
locations = (
"<TagLocationModel> \n [id]: 780307344\n [name]: Hotel Central Park, india\n</TagLocationModel>",
"<TagLocationModel> \n [id]: 463004401\n [name]: Miraj Cinema new year\n</TagLocationModel>",
"<TagLocationModel> \n [id]: 246187965\n [name]: Surya Treasure Island asia\n</TagLocationModel>",
);
"tag_posts" = (
"<TagMediaModel> \n [media_code]: BS0tQeFhU_Z\n [media_id]: 1492016420475981785\n [media_url]: https://scontent.cdninstagram.com/t51.2885-15/e15/17881459_...\n [media_type]: I\n</TagMediaModel>"
);
#property(nonatomic,strong) NSMutableArray<TagMediaModel>* tag_posts;
made few change as above, just removed the star in TagMediaModel.
The angle brackets after NSMutableArray contain a protocol. As #R.Mohan said, you need to remove * pointer and use without pointer.
The protocol must be in place. So add #protocol tag_posts and #protocol locations at top in respective class.
EXCEPTION: Invalid type in JSON write (TagMediaModel) I guess you are converting json to your custom class one or more times. Do it only once. It will resolve your problem.
Related
Project is mixed with oc and swift.
#import "myProjectName-Swift.h" in the AppDelegate.m,:
Project is Objective-c language created by me, and using almost swift language to write. and In the Appdelegate.m I want to use swift's class, and so
But unfortunate, my project occurs some error in myProjectName-Swift.h:
The code is below:
SWIFT_CLASS_PROPERTY(#property (nonatomic, class, readonly, copy)
NSString * _Nonnull ;)
+ (NSString * _Nonnull);
SWIFT_CLASS_PROPERTY(#property (nonatomic, class, readonly, copy)
NSString * _Nonnull ;)
+ (NSString * _Nonnull);
SWIFT_CLASS_PROPERTY(#property (nonatomic, class, readonly, strong) UIColor * _Nonnull APP_COLOR;)
+ (UIColor * _Nonnull)APP_COLOR;
The error are:
Expected ';' at end of declaration list.
cannot declare variable inside #interface or #protocal
Expected member name or ';' after declaration specifiers
Expected ']'
Property requires fields to be named
Missing '[' at start of message send expression
And so on...
Attension
And In the global swift, I set Chinese characters variable like this:
class Global: NSObject {
}
EDIT - 1
Because I think a error point out the static let "'s ,so I annotation this line, project will not show this error. Or I delete the ,`, will not show the error too.
Objective-C doesn't support Unicode in identifiers (variable names, class names, method names etc), only in string literals ("🏋"). Only a subset of ASCII is allowed (start with _[a-zA-Z], +[0-9] afterwards).
Example:
class MyClass : NSObject {
func 😞() { }
}
This will break when you compile it in a mixed project. Instead you need to give it a valid Objective-C name, like so:
class MyClass : NSObject {
#objc(unhappyFace)
func 😞() { }
}
which will compile (and you need to access it as unhappyFace on the ObjC side).
Or in your example you need to modify your Global object:
class Global: NSObject {
#objc(emptyNumberNotAllowed)
static let 手机号码不能为空 = "手机号码不能为空"
... etc ...
}
I want to write a method by the Objective-C that can be exported to JavaScript, so that I can get the JavaScript Object into the native code. For example in the following code: someObject is a native implemented object, and fun is its method.
someObject.fun({ k : 'value1', k2 : 'value2'})
I know that using JSExport can export the native method to JavaScript. and successfully pass the JavaScript String to the native code (NSString*). But when I want to pass the JavaScript Object to native, it fails.
How to solve this?
Thanks a lot
In addition to the conversion of javascript strings to NSString* as you have already observed, Javascript objects are copied to a KVC-compliant objective-C object (essentially, an NSDictionary instance) before being passed to your objective-c method.
For example, with the following definitions:
#protocol MyJSAPI
- (void)fun:(id)param;
#end
#interface MyObject: NSObject<MyJSAPI>
- (void)fun:(id)param;
#end
and the initialization of your JSContext as follows:
myjscontext[#"someObject"] = [[MyObject alloc] init];
[myjscontext evaluateScript:#"someObject.fun({ k : 'value1', k2 : 'value2'});
then your fun:(id)param method can access the k and k2 fields of the objects like this:
#implementation MyObject
- (void)fun:(id)param {
NSString* k = [param valueForKey:#"k"];
NSString* k2 = [param valueForKey:#"k2"];
NSLog(#"k = %#, k2 = %#", k, k2);
}
#end
In addition to ste3veh answer.
You can use JSExportAs macro in following way to export Objective-C method as JavaScript one:
#interface MyObject: NSObject <JSExport>
JSExportAs(fun,
- (void)fun:(id)param
);
#end
#implementation MyObject
- (void)fun:(id)param {
NSString* k = [param objectForKey:#"k"];
NSString* k2 = [param objectForKey:#"k2"];
NSLog(#"k = %#, k2 = %#", k, k2);
}
#end
In this case param would be implicitly converted to corresponding Objective-C oblect, using -[JSValue toObject]. In your case it will be converted in NSDictionary. To avoid implicit conversion, you may specify parameter as JSValue:
#interface MyObject: NSObject <JSExport>
JSExportAs(fun,
- (void)fun:(JSValue*)param
);
#end
#implementation MyObject
- (void)fun:(JSValue*)param {
NSString* k = [[param valueForProperty:#"k"] toString];
NSString* k2 = [[param valueForProperty:#"k2"] toString];
NSLog(#"k = %#, k2 = %#", k, k2);
}
#end
Note that big JavaScript objects, i.e. window or document, are very expensive to convert into corresponding Objective-C ones, so second way is preferred. Also, you can use JSValue parameter to call back JavaScript methods of this object from Objective-C, using callWithArguments:.
I don't think you can. See the JSExport.h header: It defines what the arguments can be, and it doesn't appear that generic JavaScript objects can be passed.
Given
#protocol Response <NSObject>
#end
#protocol DataResponse <Response>
#end
#interface ListUsersResponse : NSObject <DataResponse>
#end
#interface RequestExecutor : NSObject
+(id<Response>) execute: (id<Request>) request receptor: (Class) model;
#end
ListUsersRequest * request = [self buildListUsersRequest];
ListUsersResponse * result = [RequestExecutor execute:request receptor:[ListUsersResponse class]];
I get an Initializing 'ListUsersResponse *__strong' with an expression of incompatible type 'id<Response>' error. Why is that? Cant the compiler detect protocol conformance? How to solve it?
These warning is because your RequestExecutor's execute: method returns an object of a general id<Response> type. The variables, however, are declared as ListUsersResponse * so the compiler expects a more specific type (and it isn't sure if that type cast is correct or not, it has no way of knowing).
You can get rid of the warning by either:
a) Declaring your variables with id<Response> type instead of ListUsersRequest * type like:
id<Response> result = [RequestExecutor execute:request receptor:[ListUsersResponse class]];
Or
b) Casting them on the fly (if you are sure that at that point they will be of the appropriate class):
ListUsersResponse *result = (ListUsersRequest *)[RequestExecutor execute:request receptor:[ListUsersResponse class]];
I have a mapped object which have this property:
#interface SynchObj : NSObject
#property (nonatomic, copy) NSDictionary *fields;
#end
mapped as
mappingDict = #{ #"fields" :#"fields",};
responseMapping = [RKObjectMapping mappingForClass:[SynchObj class]];
[responseMapping addAttributeMappingsFromDictionary:mappingDict];
But when the server send a dictionary like this
{
name:null
surname:null
}
the mapping produces a dictionary with these values:
name : "<null>"
surname : "<null>"
I would like to have "" instead of "". Is it possible?
You should be able to use KVC validation which RestKit supports to verify / edit the value before it is set. If you implement validateValue:forKey:error: on your destination class (SynchObj) you can verify and edit the value being set for any key (you would need to iterate the keys and values of the dictionary).
Is it possible to parse json to an array of JSONModel objects using JSONModel? Like parse json below:
[{"id" : 1}, {"id" : 2}]
to two JSONModel objects having property of "id".
You should use arrayOfModelsFromDictionaries: on your model class like so:
NSArray* models = [YourModelClass arrayOfModelsFromDictionaries: objects];
This will go over "objects" and convert each dictionary to a model and you get the result in models. If any item in objects fail to convert to model "models" will be nil.
Here's the class docs for this method:
http://jsonmodel.com/docs/Classes/JSONModel.html#//api/name/arrayOfModelsFromDictionaries:
Why not trying BWJSONMatcher?
First you should declare your own data model:
#interface MyDataModel : NSObject
#property (nonatomic, assign) NSInteger id;
#end
Then you can easily get your array with BWJSONMatcher within one line:
NSArray *jsonArray = [BWJSONMatcher matchJSON:jsonString withClass:[MyDataModel class]];
Hope this could help you.