I write an application for iphone in objective-c and wanna get data from json. but I get null from url, but url is correct and when I pass url to browser I see the json data. this is my IBAction method:
- (IBAction)checkMobileNumber:(id)sender {
NSString *prefix = self.prefixTextField.text;
NSString *number = self.numberTextField.text;
NSString *url =[NSString stringWithFormat:#"http://data.e-gov.az/api/v1/IEGOVService.svc/CheckMobileProvider/%#/%#", prefix, number];
NSURL *jsonURL = [NSURL URLWithString:url];
#try {
[[[NSURLSession sharedSession] dataTaskWithURL:jsonURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString* rawJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *err;
self.checkMobile = [[CheckMobileProviderModel alloc] initWithString:rawJSON error:nil];
if (err) {
NSLog(#"Unable to initialize PublicPhotosModel, %#", err.localizedDescription);
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"%#", self.checkMobile.response);
//NSLog(#"%#", self.checkMobile.fault[#"faultString"]);
});
}] resume];
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
}
what is wrong here? any help?
EDIT:
my CheckMobileProviderModel.h
#import "JSONModel.h"
#import "FaultModel.h"
#protocol FaultModel
#end
#interface CheckMobileProviderModel : JSONModel
#property (strong, nonatomic) NSString *response;
#property (strong, nonatomic) NSArray<FaultModel, Optional>* fault;
#end
and FaultModel.h
#import "JSONModel.h"
#interface FaultModel : JSONModel
#property (strong, nonatomic) NSString* faultCode;
#property (strong, nonatomic) NSString* faultString;
#end
Do not convert the JSON to a string:
NSString* rawJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
convert it is an object, in this case a NSDictionary
NSError = *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (dict) {
NSLog(#"dict: %#", dict);
}
else {
NSLog(#"error: %#", error);
}
The JSON in the comment nicely formatted:
{
"fault":{
"faultCode":1,
"faultString":"Məlumat yoxdur"
},
response":"Cari nömrə üçün mobil daşınma xidmətindən istifadə edilməmişdir"
}
Translated:
{
"fault":{
"faultCode":1,
"faultString":"there is no information"
},
response":"The current number is not used for a mobile carriage service"
}
Related
Hello I would like to know how it's possible to have responseString and responseObject with the new version of AFNetworking.
When I made GET operation I have success response with NSURLSessionDataTask and id responseData.
And I would like to have responseString and responseObject.
Thanks for your help.
there is my code not the full code but it's like that
void(^wsFailure)(NSURLSessionDataTask *, NSError *) = ^(NSURLSessionDataTask *failedOperation, NSError *error) {
NSLog(#"failed %#",failedOperation);
[self failedWithOperation:failedOperation error:error];
};
void (^wsSuccess)(NSURLSessionDataTask *, id) = ^(NSURLSessionDataTask * _Nonnull succeedOperation, id _Nullable responseObject) {
NSLog(#"responseData: %#", responseObject);
NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"responseData: %#", str);
}}
AFHTTPResponseSerializer *responseSerializer = [self responseSerializerFromResponseType];
AFHTTPRequestSerializer *requestSerializer = [self requestSerializerFromRequestType];
operationManager.requestSerializer = requestSerializer;
operationManager.responseSerializer = responseSerializer;
- (AFHTTPResponseSerializer *)responseSerializerFromResponseType{
if ([self.request.parameters[#"responseType"] isEqualToString:#"xml"]) {
return [AFXMLParserResponseSerializer serializer];
}
else if ([self.request.parameters[#"responseType"] isEqualToString:#"html"]) {
return [AFHTTPResponseSerializer serializer];
}}
Quickly done, I implemented my own ResponseSerializer, which is just a way to encapsulate a AFNetworkingSerializer (~AFHTTPResponseSerializer which is the superclass of the other ones, and respects the AFURLResponseSerialization protocol) which will return a custom serialized object, which will have the 2 properties you want in addition to the NSDictionary/NSArray serialized object: a NSData and a NSString.
.h
#interface CustomResponseSerializer : NSObject <AFURLResponseSerialization>
-(id)initWithResponseSerializer:(id<AFURLResponseSerialization>)serializer;
#end
.m
#interface CustomResponseSerializer()
#property (nonatomic, strong) id<AFURLResponseSerialization> serializer;
#end
#implementation CustomResponseSerializer
-(id)initWithResponseSerializer:(id<AFURLResponseSerialization>)serializer {
self = [super init];
if (self)
{
_serializer = serializer;
}
return self;
}
- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response data:(nullable NSData *)data error:(NSError * _Nullable __autoreleasing * _Nullable)error {
id serialized = nil;
if ([_serializer respondsToSelector:#selector(responseObjectForResponse:data:error:)]) {
NSError *serializationError = nil;
serialized = [_serializer responseObjectForResponse:response data:data error:&serializationError];
}
//You could put NSError *serializationError = nil; before, and set it into the `CustomSerializedObject` `error` property, I didn't check more about AFNetworking and how they handle a parsing error
return [[CustomSerializedObject alloc] initWithData:data
string:[[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding]
object:serialized];
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
[coder encodeObject:self.serializer forKey:NSStringFromSelector(#selector(serializer))];
}
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
self = [self init];
if (!self) {
return nil;
}
self.serializer = [coder decodeObjectForKey:NSStringFromSelector(#selector(serializer))];
return self;
}
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
CustomResponseSerializer *serializer = [[CustomResponseSerializer allocWithZone:zone] init];
serializer.serializer = [self.serializer copyWithZone:zone];
return serializer;
}
#end
And the object:
#interface CustomSerializedObject: NSObject
#property (nonatomic, strong) NSData *rawData;
#property (nonatomic, strong) NSString *string;
#property (nonatomic, strong) id object;
#property (nonatomic, strong) NSError *error; //If needed
-(id)initWithData:(NSData *)data string:(NSString *)string object:(id)object;
#end
#implementation CustomSerializedObject
-(id)initWithData:(NSData *)data string:(NSString *)string object:(id)object {
self = [super init];
if (self)
{
_rawData = data;
_string = string;
_object = object;
}
return self;
}
#end
How to use:
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:#"https://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
CustomResponseSerializer *responseSerializer = [[CustomResponseSerializer alloc] initWithResponseSerializer:[AFJSONResponseSerializer serializer]];
[manager setResponseSerializer: responseSerializer];
NSURLSessionDataTask *task = [manager dataTaskWithRequest:request
uploadProgress:nil
downloadProgress:nil
completionHandler:^(NSURLResponse * _Nonnull response, CustomSerializedObject * _Nullable responseObject, NSError * _Nullable error) {
NSLog(#"Response: %#", response);
NSLog(#"ResponseObject data: %#", responseObject.rawData); //If you want hex string ouptut see https://stackoverflow.com/questions/1305225/best-way-to-serialize-an-nsdata-into-a-hexadeximal-string
NSLog(#"ResponseObject str: %#", responseObject.string);
NSLog(#"ResponseObject object: %#", responseObject.object);
NSLog(#"error: %#", error);
}];
[task resume];
Hi i am getting the response from my server successfully.i need to access the user_id send by the server in my app.
check my code:
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSURL * url = [NSURL URLWithString:#"my url"];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
NSString * params=[[NSString alloc]initWithFormat:#"mobile=%#",[self.reqnum text ]];
NSLog(#"%#",params);
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
if(error == nil)
{
NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"Data = %#",text);
[[NSUserDefaults standardUserDefaults]setObject:#"Y" forKey:#"login"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}];
[dataTask resume];
for this code i am getting the response like:
here i need to access the user_id in my app .so can i get that particular user_id.
Thank You.
Since original solutions have already been posted, I will focus on longer & more tedious way which I think is the proper way to handle the elephant in the room. This will help you in the longer run.
Create a Singleton class since there can be only one user logged in at one time.
SharedUser.h
#import <Foundation/Foundation.h>
#interface SharedUser : NSObject
#property (strong, nonatomic) NSString* userId;
#property (strong, nonatomic) NSString* userName;
#property (strong, nonatomic) NSString* subscriptionStatus;
#property (strong, nonatomic) NSString* registerDate;
#property (strong, nonatomic) NSString* expiryDate;
+(SharedUser*) getInstance;
#end
SharedUser.m
#import "SharedUser.h"
#implementation SharedUser
static SharedUser * sharedInstance;
+(SharedUser*) getInstance
{
#synchronized(self)
{
if(sharedInstance == nil)
{
sharedInstance = [[SharedUser alloc] init];
sharedInstance.userName = #"";
sharedInstance.userId = #"";
sharedInstance.subscriptionStatus = #"";
sharedInstance.registerDate = #"";
sharedInstance.expiryDate = #"";
return sharedInstance;
}
else
{
return sharedInstance;
}
}
}
Convert your response into NSDictionary.
NSDictionary *json_dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];;//From Santosh Reddy's Answer
Populate your sharedInstance with the result attributes:
[SharedUser getInstance].userId = [json_dict objectForKey:#"user_id"];
[SharedUser getInstance].userName = [json_dict objectForKey:#"username"];
[SharedUser getInstance].subscriptionStatus = [json_dict objectForKey:#"subscription_status"];
[SharedUser getInstance].registryDate = [json_dict objectForKey:#"register_date"];//Better to use NSDate type instead of NSString
[SharedUser getInstance].expiryDate = [json_dict objectForKey:#"expiry_date"];
Now your user's attributes will be available anywhere in the App. You just need to import SharedUser.h to desired UIView, UIViewController & type following to access your data:
NSString *userId = [SharedUser getInstance].userId;
Also Note that I am using singleton pattern because I am assuming that you only need to handle one user's attributes which will be used in multiple viewcontrollers over the span of time. If you need multiple users saved, create a similar user model class and populate them in a similar way. (Just don't make them singleton).
Also I would suggest that you should read Ray Wenderlich's series tutorials on:
1. Object Oriented Design
2. Design Patterns
3. Intro to iOS design patterns
If you want to use the value in other classes then :
First create a data Model Class, parse the data dictionary/JSON and store it.
Using the completion block you can return the specific/received user_id to the caller.
Here you are getting in JSON, you can parse it and get the desired data:
NSDictionary *respDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSString *userID = respDict[#"user_id"];
The response is a JSON object. If what you are asking is how to parse it, then there is an inbuilt JSON parser in iOS.
NSDictionary *json_dict = [text JSONValue];
NSString *userID = [result objectForKey:#"user_id"];
Create a NSDictionary to get json data.
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
if(error == nil)
{
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSString *userID = [dictionary objectForKey:#"user_id"];
}
}];
Yes, its upto you how to store data and if you want to parse it, then try
NSDictionary *jsonDict = [responseString JSONValue];
NSString *user_id = [jsonDict objectForKey:#"user_id"];
Parse the data that you're getting in block as below.
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
if(error == nil)
{
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSDictionary *response = JSON[#"user_id"];
}
}];
You can make a NSDictionary, save JSON data in it and fetch user_id from it. Like this:
NSDictionary *dictionaryName=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSString *user_id= [dictionaryName valueForKey:#"user_id"];
I have hobbled together one of my first objects. The goal of the object is to send a text message, which is does. However I'm calling it from the 2nd UIViewController within ViewDidLoad, and its still hanging within the Segue transition. So I know I need to get it asynchronously, but reading some other threads they implied that the proper way to go around it is to make it an "AppDelegate Object", so I would assume I would need to call the object from the AppDelegate, but I'm not really sure about how to go about that as I have not really worked with that in some tutorials I'm doing, and on top of that, is that the correct way to go about using my object?
initializing the object from my view controller
Twilio *twilio = [[Twilio alloc] init];
[twilio sendMessage: self.phoneNumber: [self getRandomNumberBetween:1000 to:9999]];
Header file
#import <Foundation/Foundation.h>
#interface Twilio : NSObject
#property (strong, nonatomic) NSString *TwilioSID;
#property (strong, nonatomic) NSString *TwilioSecret;
#property (strong, nonatomic) NSString *FromNumber;
#property (strong, nonatomic) NSString *ToNumber;
#property (strong, nonatomic) NSString *Message;
-(id)init;
-(id)sendMessage:(NSString *)phoneNumber :(NSString *)message;
#end
Implementation file
#import "Twilio.h"
#implementation Twilio
-(id)init {
self = [super init];
if(self) {
// Twilio Common constants
self.TwilioSID = #"A....3";
self.TwilioSecret = #"e...8";
self.FromNumber = #"5...2";
self.ToNumber = nil;
self.Message = nil;
}
return self;
}
-(id)sendMessage:(NSString *)phoneNumber :(NSString *)message
{
NSLog(#"Sending request.");
self.ToNumber = phoneNumber;
self.Message = message;
// Build request
NSString *urlString = [NSString stringWithFormat:#"https://%#:%##api.twilio.com/2010-04-01/Accounts/%#/SMS/Messages", self.TwilioSID, self.TwilioSecret, self.TwilioSID];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
// Set up the body
NSString *bodyString = [NSString stringWithFormat:#"From=%#&To=%#&Body=%#", self.FromNumber, self.ToNumber, self.Message];
NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
NSError *error;
NSURLResponse *response;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
// Handle the received data
if (error) {
NSLog(#"Error: %#", error);
} else {
NSString *receivedString = [[NSString alloc]initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"Request sent. %#", receivedString);
}
return self.Message;
}
#end
Updated
With recommendation below I changed my object implementation like so:
//NSError *error;
//NSURLResponse *response;
//NSData *receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[NSURLConnection sendAsynchronousRequest:request queue:self.queue completionHandler:^(NSURLResponse *response, NSData *data, NSError
*error) {
// Handle the received data
if (error) {
NSLog(#"Error: %#", error);
} else {
NSString *receivedString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Request sent. %#", receivedString);
}
NSLog(#"%#",response);
}];
Use method sendAsynchronousRequest:queue:completionHandler:
See it : https://stackoverflow.com/a/9270711/2828120
I've been really confused to solve this problem .
I want get response from https Xcode.
this is the URL -> https://staping.faboo.co.id/ ( The url is not real )
Response from that url is XML format like this :
<response>
<GeneralResponse>
<status>2</status>
<desc>Data Not Found</desc>
</GeneralResponse>
</response>
My code fabooViewController.h is like this :
#import <UIKit/UIKit.h>
#interface FabooViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *passwordField;
#property (weak, nonatomic) IBOutlet UITextField *emailField;
#property (weak, nonatomic) IBOutlet UIButton *buttonLogin;
#property (weak, nonatomic) NSArray *trustedHosts;
#end
My code fabooViewController.m is like this :
- (IBAction)loginAction:(id)sender {
NSString *email = _emailField.text;
NSString *password = _passwordField.text;
NSString *url_string = [NSString stringWithFormat: #"https://staping.faboo.co.id/email=%#&pass=%#",email,password];
NSLog(#"url : %#",url_string);
NSURL *URL = [NSURL URLWithString:url_string];
_trustedHosts = [NSArray arrayWithObjects:#"https://staping.faboo.co.id",nil];
NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:URL];
NSError *error = nil;
NSData *data = [ NSURLConnection sendSynchronousRequest: urlRequest returningResponse: nil error: &error ];
if (error)
{
NSLog(#"error %#", [error localizedDescription]);
}
else
{
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
NSLog(#"Result %#", result);
}
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"host : %#",_trustedHosts);
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
if ([_trustedHosts containsObject:challenge.protectionSpace.host])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
and the error is:
FabooUniversalApp[1570:4903] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9807)
2014-06-10 13:35:19.541 FabooUniversalApp[1570:60b] error The certificate for this server is invalid. You might be connecting to a server that is pretending to be “staping.faboo.co.id” which could put your confidential information at risk.
what should I do?
Edited:
i use this link How to use NSURLConnection to connect with SSL for an untrusted cert? for my reference
SOLVED
in my file.m i implemented NSURLRequest
#interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
#end
and i use this code to get result from https :
NSString *url_string = #"your url";
NSLog(#"url : %#",url_string);
NSURL *URL = [NSURL URLWithString:url_string];
NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:URL];
NSError *error = nil;
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[URL host]];
NSURLResponse *response;
NSData *data = [ NSURLConnection sendSynchronousRequest: urlRequest returningResponse:&response error: &error ];
if (error)
{
NSLog(#"error %#", [error localizedDescription]);
}
else
{
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
NSLog(#"Result %#", result);
NSData *xmlData = [result dataUsingEncoding:NSASCIIStringEncoding];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData];
[xmlParser setDelegate:self];
[xmlParser parse];
}
I have one main entity class with name "Store" like :
Store.h :-
#import <Foundation/Foundation.h>
#import "SignIn.h"
#interface Store : NSObject
#property (nonatomic, retain) NSString *storeId;
#property (nonatomic, retain) NSString *storeProfileId;
#property (nonatomic, retain) NSString *storeName;
#property (nonatomic, retain) NSString *storeRegion;
#property (nonatomic, retain) SignIn *signIn;
#end
Store.m :-
#import "Store.h"
#implementation Store
#synthesize storeId, storeProfileId, storeName, storeRegion, signIn;
- (id) initWithCoder: (NSCoder *)coder
{
self = [[Store alloc] init];
if (self != nil)
{
self.storeId = [coder decodeObjectForKey:#"storeId"];
self.storeProfileId = [coder decodeObjectForKey:#"storeProfileId"];
self.storeName = [coder decodeObjectForKey:#"storeName"];
self.storeRegion = [coder decodeObjectForKey:#"storeRegion"];
self.signIn = [coder decodeObjectForKey:#"signIn"];
}
return self;
}
- (void)encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:storeId forKey:#"storeId"];
[coder encodeObject:storeProfileId forKey:#"storeProfileId"];
[coder encodeObject:storeName forKey:#"storeName"];
[coder encodeObject:storeRegion forKey:#"storeRegion"];
[coder encodeObject:signIn forKey:#"signIn"];
}
#end
Here in Store class, i am taking one more class name "Sign In", that include some other attributes.
SignIn.h :-
#import <Foundation/Foundation.h>
#interface SignIn : NSObject
#property (nonatomic, retain) NSString *inTime;
#property (nonatomic, retain) NSString *outTime;
#property (nonatomic, retain) NSString *isStatus;
#end
SignIn.m :-
#import "SignIn.h"
#implementation SignIn
#synthesize inTime, outTime, isStatus;
- (id) initWithCoder: (NSCoder *)coder
{
self = [[SignIn alloc] init];
if (self != nil)
{
self.inTime = [coder decodeObjectForKey:#"inTime"];
self.outTime = [coder decodeObjectForKey:#"outTime"];
self.isStatus = [coder decodeObjectForKey:#"isStatus"];
}
return self;
}
- (void)encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:inTime forKey:#"inTime"];
[coder encodeObject:outTime forKey:#"outTime"];
[coder encodeObject:isStatus forKey:#"isStatus"];
}
#end
Now i need to post this Store object on server. So I am creating dictionary using below code :
NSMutableArray *storeJSONArray=[NSMutableArray array];
for (Store *store in array1) {
NSMutableDictionary *storeJSON=[NSMutableDictionary dictionary];
[storeJSON setValue:store.storeId forKey:#"storeId"];
[storeJSON setValue:store.storeProfileId forKey:#"storeProfileId"];
[storeJSON setValue:store.storeName forKey:#"storeName"];
[storeJSON setValue:store.storeRegion forKey:#"storeRegion"];
//Sign In
[storeJSON setValue:store.signIn.inTime forKey:#"inTime"];
[storeJSON setValue:store.signIn.outTime forKey:#"outTime"];
[storeJSON setValue:store.signIn.isStatus forKey:#"isStatus"];
[storeJSONArray addObject:storeJSON];
}
NSMutableDictionary *dictionnary = [NSMutableDictionary dictionary];
[dictionnary setObject:storeJSONArray forKey:#"StoreRequest"];
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionnary
options:kNilOptions
error:&error];
NSString *urlString =#"http://...................php";
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
NSURLResponse *response = NULL;
NSError *requestError = NULL;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] ;
But i am not getting correct JSON, can you please check my code and let me know where is my mistake. Thanks in Advance.
If you are working on iOS 5+, then you can use NSJSONSerialization.
NSData *data= [NSJSONSerialization dataWithJSONObject:storeJSONArray
options:NSJSONWritingPrettyPrinted
error:nil];
if (data)
{
NSString *json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"JSON : %#",json );
}
You should serialize your NSMutableDictionary to JSON.
You can do this by using NSJSONSerialization:
NSError *error;
NSData *myData = [NSJSONSerialization dataWithJSONObject:storeJSON options:0 error:&error];
NSString *myJSON = [[NSString alloc] initWithBytes:[myData bytes]];
This should give you your JSON.
But i am not getting correct JSON, can you please check my code and let me know where is my mistake.
The problem is that you're not creating a JSON representation of the object anywhere; you're only creating a dictionary. Dictionaries can be converted to JSON (provided that they only contain certain types of data), but they're not JSON natively -- they're Objective-C objects. You probably want to add a call like:
NSError *error = nil;
NSData *json = [NSJSONSerialization dataWithJSONObject:dictionnary options:0 error:&error];
You've shown us the NSCoding methods in your two classes, but you should understand that NSJSONSerialization doesn't rely on NSCoding, so none of that code is going to come into play.
Update: After modifying your example to include NSJSONSerialization, you say you're getting JSON that looks like this:
{"StoreRequest":[{"signOutStatus":false,"greetingStatus":false,"isBackFromVisit":false,"digitalMerchandisingStatus":false,"feedbackStatus":false,"storeRegion":"Bishan Junction 8","isSubmit":false,"storeName":"Best Denki","storeId":"SG-2","planVisitStatus":false,"storeProfileId":5,"merchandisingStatus":false}]}
That appears to be correct, given the values that you've added to dictionnary. But you say that what you want is:
{ "Checklist": [ { "vm_code": "SGVM0001", "store_id": "SG-12", "store_name": "Best Denki", "store_address": "Ngee Ann City", "visit_date": { "date": "2013-12-04 00:00:00", "timezone_type": 3, "timezone": "Asia/Calcutta" } "sign_in": { "date": "2013-12-05 11:03:00", "timezone_type": 3, "timezone": "Asia/Calcutta" }]
That doesn't at all match the object that you're passing to NSJSONSerialization. So, the problem here is that you're supplying incorrect data to NSJSONSerialization.
Try with
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionaryOrArrayToOutput
options:kNilOptions // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}