ios send push notification with GCM Device to Device - ios

I want to be able to send push notification to a topic from device to device. I am already able to receive the notifications if I send them from a server but in the end I don't want a server to interact with my apps.
I wrote a method that send the notification that look like this :
-(void)sendNotif {
NSDictionary *message = #{
#"notification" : #"{ \"text\" : \"test\", \"title\" : \"test\"}",
#"to" : #"/topics/test"
};
// kSenderID is the senderID you want to send the message to
NSString *kSenderID = #"X";
NSString *to = [NSString stringWithFormat:#"%##gcm.googleapis.com", kSenderID];
DLOG(#"dict %#, to : %#",message, to);
[[GCMService sharedInstance] sendMessage:message to:to withId:#"id1"];
}
But it seems nothing is sent.
So I have 2 questions :
How do I write my method?
How do I implement the callback methods?

A solution I found is to create my own HTTPRequest like in google example :
-(void)sendNotif {
NSString *sendUrl = #"https://android.googleapis.com/gcm/send";
NSString *subscriptionTopic = #"/topics/test";
NSString *title = notifTitle.text;
NSString *body = notifBody.text;
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:sendUrl ]];
req.HTTPMethod = #"POST";
[req setValue:#"application/json" forHTTPHeaderField: #"Content-Type"];
[req setValue:#"key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" forHTTPHeaderField: #"Authorization"];
NSDictionary *message = [self getMessageTo:subscriptionTopic withTitle:title withBody:body];
NSError *jsonError;
NSMutableString *jsonString;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:message options:NSJSONWritingPrettyPrinted error:&jsonError];
if (! jsonData) {
NSLog(#"Got an error: %#", jsonError);
} else {
jsonString = [[NSMutableString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
DLOG(#"json string%#", jsonString);
req.HTTPBody = jsonData;
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error != nil) {
DLOG(#"truc error %#",error);
} else {
DLOG(#"Success! Response from the GCM server:");
DLOG(#"%#",response);
}
}];
}
-(NSDictionary *) getMessageTo:(NSString *) to withTitle:(NSString *) title withBody:(NSString *) body{
// [START notification_format]
NSDictionary *message = #{
#"notification" : #{#"title" : title,#"text" : body},
#"to" : to
};
return message;
// [END notification_format]
}

There is no normal way to publish a message to topic from the client. The one proposed by the question author him/herself is basically a hack that requires keeping the API key on the client which is very insecure.
The main reason why it is not allowed is that it would let adversary to tamper with the client and send spam messages to other users.

Related

Validating App store receipt gives DrmInvalidArgumentException

I'm following the documentation here.
https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
I have a receipt-data from my team that I'm trying to validate, they're getting error code 21002 which was malformed JSON. It looks like they had extra parameters appended to the base64 data, so I tried removing those and sending:
- (void)viewDidLoad {
[super viewDidLoad];
NSData *receipt; // Sent to the server by the device
// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = #{
#"receipt-data": #"<<$mybase64data>>", #"password" : #"<<$thepassword>>"};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&error];
if (!requestData) { /* ... Handle error ... */ }
// Create a POST request with the receipt data.
NSURL *storeURL = [NSURL URLWithString:#"https://buy.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:#"POST"];
[storeRequest setHTTPBody:requestData];
// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
/* ... Handle error ... */
NSLog(#"conerror %#", connectionError);
} else {
NSError *error;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"hello %#", jsonResponse);
NSLog(#"error %#", error);
if (!jsonResponse) {
}
}
}];
}
result:
2017-03-03 22:45:47.454 receipttest[89851:352604] hello {
exception = "com.apple.jingle.mzfairplay.validators.DrmInvalidArgumentException";
status = 21002;
}
2017-03-03 22:45:47.455 receipttest[89851:352604] error (null)
Something to keep in mind: In this example the data is sent to Apple straight from the App, but you might do this from a server too. When you testing your server App don't use NSLog() to print your base64 data, NSLog truncates data.
I had this issue when using a receipt from a test user that was a couple days old with a yearly auto-renewable subscription.
I checked the above helpful responses about extra characters etc (I also checked I had supplied my app secret for auto-renewable) with no joy.
In the end I tried creating A NEW SANDBOX user and it worked first time
with no other changes other than the new Receipt!
Hope this helps someone.
I also received the same error response for serveral receipts. The solution for me was to remove all occurrences of \r\n.
Maybe you have the same issue. I still haven't figured out when and why these chars are inserted.
Pay attention to URLENCODE:
- (NSString *)URLEncodedString
{
// CharactersToBeEscaped = #":/?&=;+!##$()~',*";
// CharactersToLeaveUnescaped = #"[].";
NSString *unencodedString = self;
NSString *encodedString = (NSString *)
CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8));
return encodedString;
}

Unable to perform operations on response object?

I am struggling with a response object from one of my API calls. I receive it fine, but if I try to perform a count or valueForKey operation on the object, I get a "Unrecognized selector sent to instance" error. I have a feeling I am not correctly decoding the response object, any input would be greatly appreciated!
Method for the API call:
- (void)callRegisterAccount:(NSString *)email
password:(NSString *)password
confirmPassword:(NSString *)confirmPassword
completionBlock:(void (^)(NSMutableArray *resultsArray))completion{
NSLog(#"REGISTER ACCOUNT CALLED!");
NSString *appendUrl = [NSString stringWithFormat:#"Account/Register"];
NSURL *aUrl = [NSURL URLWithString:[NSString stringWithFormat:#"%#""%#", #"xxx", appendUrl]];
NSLog(#"URL: %#",aUrl);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
[request setHTTPMethod:#"POST"];
[request addValue:#"application/json, text/plain, */*" forHTTPHeaderField:#"Accept"];
[request addValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
//build an info object and convert to json
NSDictionary* info = [NSDictionary dictionaryWithObjectsAndKeys:
email,
#"Email",
password,
#"Password",
confirmPassword,
#"ConfirmPassword",
nil];
//convert object to data
NSError *error;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:info
options:NSJSONWritingPrettyPrinted error:&error];
NSString *strData = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#",strData);
[request setHTTPBody:[strData dataUsingEncoding:NSUTF8StringEncoding]];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// NSLog(#"REGISTER PUSH NOTIFICATIONS RESPONSE: %#", response);
// NSLog(#"REGISTER PUSH NOTIFICATIONS ERROR: %#", error);
// NSLog(#"REGISTER PUSH NOTIFICATIONS DATA: %#", data);
NSData *_data = data;
NSMutableString *_string = [NSMutableString stringWithString:#""];
for (int i = 0; i < _data.length; i++) {
unsigned char _byte;
[_data getBytes:&_byte range:NSMakeRange(i, 1)];
if (_byte >= 32 && _byte < 127) {
[_string appendFormat:#"%c", _byte];
} else {
[_string appendFormat:#"[%d]", _byte];
}
}
NSLog(#"REGISTER ACCOUNT RESPONSE: %#", _string);
if(_string) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
completion((NSMutableArray*)_string);
}
}];
}
Response object:
This line is all wrong:
completion((NSMutableArray*)_string);
_string is an instance of NSMutableString, and here you're telling the compiler to trust you that it's actually an instance of NSMutableArray. This is obviously a lie and when you try to use it as an array you get an exception.
Note that the JSON could be an array or a dictionary, and in your example it is actually a dictionary, so you need to check this and work out how to return an array - or change the completion block. You need to explicitly deal with this container type variation somewhere...
You don't need to do the funky data to string processing you have, you can just use NSJSONSerialization to go straight from data to JSON object (dictionary or array), and it'll return an error if there is some issue with the JSON.
Hmmm, looking at that data processing again indicates some reformatting of the data, which is a bit weird but ok. After you've done that and got your string you should turn it back into data and then use NSJSONSerialization.

NSMutableURLRequest returning JSON with empty sub-arrays

I have created a method that uses NSMutableURLRequest to request and receive JSON from a RESTful API running on a remote machine. The request successfully returns some JSON, but the returned sub-arrays in the JSON (see tasks: []) are empty.
The JSON returned from the API is:
{
"error":false,
"tasks":[
{
"id":1,
"task":"Get Milk",
"status":0,
"createdAt":"2014-08-09 12:29:15"
},
{
"id":2,
"task":"Call Mom",
"status":0,
"createdAt":"2014-08-09 12:46:52"
},
{
"id":3,
"task":"Call Dad",
"status":0,
"createdAt":"2014-08-09 12:47:04"
},
{
"id":4,
"task":"Study",
"status":0,
"createdAt":"2014-08-09 12:47:08"
}
]
}
The method that utilizies NSMutableURLRequest (proper parameters being passed is assumed) is:
-(NSDictionary *) apiRequestWithEndpoint:(NSString *) endpoint
withParams:(NSDictionary *) params
withHTTPHeaders:(NSDictionary *) headers
withHTTPMethod:(NSString *) method
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:endpoint]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:method];
//set headers
for (id key in headers) {
[request setValue:[headers valueForKey:key] forHTTPHeaderField:key];
}
//set paramaters in request body
NSMutableString *requestBody = [[NSMutableString alloc] init];
int keyIndex = 0;
for (id key in params) {
if (keyIndex == 0) {
[requestBody appendFormat:#"%#=%#", key, [params valueForKey:key]];
} else {
[requestBody appendFormat:#"&%#=%#", key, [params valueForKey:key]];
}
keyIndex++;
}
[request setHTTPBody:[requestBody dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *response;
NSError *NSURLError = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&NSURLError];
if (NSURLError) {
NSLog(#"Error: %# Cancelling operation.", NSURLError);
return nil;
}
NSError *NSJSONSerializationError = nil;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&NSJSONSerializationError];
if (NSJSONSerializationError) {
NSLog(#"Error: %# Cancelling operation.", NSJSONSerializationError);
return nil;
}
NSLog(#"Data: %#",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
return responseJSON;
}
Notice the 4th last line that logs the returned NSData from the NSMutableURLRequest, the output is:
Data: {"error":false "tasks":[]}
The code that calls the above method:
NSString *getAllTasksEndpoint = #"http://developmentVPS.com/TaskList-API/v1/tasks";
NSString *apiKey = #"A Valid API Key";
NSDictionary *headers = [[NSDictionary alloc] initWithObjectsAndKeys:apiKey, #"Authorization", nil];
NSDictionary *responseJSON = [self apiRequestWithEndpoint:getAllTasksEndpoint
withParams:nil
withHTTPHeaders:headers
withHTTPMethod:#"GET"];
It is my understanding that the entire data returned from the request should be logged in that NSLog call, but "tasks" is empty. I am new to iOS development, so I may be missing something simple. Does anybody see anything I am missing here?

NSURLConnection wrong order

I have a NSURLConnection (two of them), and they're running in the wrong order.
Here's my method:
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
}
}
else {
NSLog(#"error: %#", error);
}
}];
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:#"POST"];
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError)
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
}
}
else {
NSLog(#"error: %#", homeError);
}
}];
}
- (NSString *)percentEscapeString:(NSString *)string
{
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)string,
(CFStringRef)#" ",
(CFStringRef)#":/?#!$&'()*+,;=",
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:#" " withString:#"+"];
}
So, it's two NSURLConnection's that are added to the [NSOperationQueue mainQueue]. What my output is showing me is that the second NSURLConnection is running before the first one. So it tries to go to the page where I download data before I'm logged in, so it (obviously) returns a "You're not logged in" error.
How do I schedule them one after another?
The issue, as I suspect you have realized, is that you're doing asynchronous network requests (which is good; you don't want to block the main queue), so there's no assurance of the order they'll finish.
The quickest and easiest answer is to simply put the call to the second request inside the completion block of the first one, not after it. You don't want to be making that second one unless the first one succeeded anyway.
To keep your code from getting unwieldy, separate the login from the request for main page. And you can use the completion block pattern which is common with asynchronous methods. You add a parameter to loginToMistarWithPin that specifies what it should do when the request finishes. You might have one completion block handler for success, and one for failure:
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password success:(void (^)(void))successHandler failure:(void (^)(void))failureHandler {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
// assuming you validated that everything was successful, call the success block
if (successHandler)
successHandler();
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
if (failureHandler)
failureHandler();
}
}
else {
NSLog(#"error: %#", error);
if (failureHandler)
failureHandler();
}
}];
}
- (void)requestMainPage {
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[requestHome setHTTPMethod:#"GET"]; // this looks like GET request, not POST
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError)
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
}
}
else {
NSLog(#"error: %#", homeError);
}
}];
}
Then, when you want to login, you can do something like:
[self loginToMistarWithPin:#"1234" password:#"pass" success:^{
[self requestMainPage];
} failure:^{
NSLog(#"login failed");
}];
Now, change those successHandler and failureHandler block parameters to include whatever data you need to pass back, but hopefully it illustrates the idea. Keep your methods short and tight, and use completion block parameters to specify what an asynchronous method should do when it's done.
Can you check the below link. It is about forcing one operation to wait for another.
NSOperation - Forcing an operation to wait others dynamically
Hope this helps.

ios parsing json result after http request

am starting to build login form reading from external server via http request i need to parse json result to get user name
- (IBAction)getlogin:(UIButton *)sender {
NSString *rawStrusername = [NSString stringWithFormat:#"username=%#",_username.text];
NSString *rawStrpassword = [NSString stringWithFormat:#"password=%#",_password.text];
NSString *post = [NSString stringWithFormat:#"%#&%#", rawStrusername, rawStrpassword];
// NSString *post = #"rawStrusername&rawStrpassword";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
/* NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]]; */
NSURL *url = [NSURL URLWithString:#"http://www.othaimmarkets.com/my_services_path/user/login.json"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
/* [request setValue:postLength forHTTPHeaderField:#"Content-Length"]; */
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSLog(#"responseData: %#", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
//NSLog(#"responseData: %#", responseData);
}
I get this result:
{"sessid":"g2ev7til6d750ducrkege0cbj2","session_name":"SESS02795057fe9e6b2fc0777bf4057b248f","user":{"uid":"617","name":"mohammed.abdelrasoul#gmail.com","mail":"mohammed.abdelrasoul#gmail.com","mode":"0","sort":"0","threshold":"0","theme":"","signature":"","signature_format":"0","created":"1316602317","access":"1352643854","login":"1352666338","status":"1","timezone":"10800","language":"ar","picture":"","init":"mohammed.abdelrasoul#gmail.com","data":"a:5:{s:18:\"country_iso_code_2\";s:2:\"SA\";s:13:\"timezone_name\";s:11:\"Asia/Riyadh\";s:5:\"block\";a:1:{s:7:\"webform\";a:1:{s:15:\"client-block-88\";i:1;}}s:13:\"form_build_id\";s:37:\"form-3ae73833f08accc7abe5517347ea87eb\";s:7:\"contact\";i:0;}","country_iso_code_2":"SA","timezone_name":"Asia/Riyadh","block":{"webform":{"client-block-88":1}},"form_build_id":"form-3ae73833f08accc7abe5517347ea87eb","contact":0,"roles":{"2":"authenticated user"}}}
Or, formatted for the sake of legibility:
{
"sessid":"g2ev7til6d750ducrkege0cbj2",
"session_name":"SESS02795057fe9e6b2fc0777bf4057b248f",
"user":{
"uid":"617",
"name":"mohammed.abdelrasoul#gmail.com",
"mail":"mohammed.abdelrasoul#gmail.com",
"mode":"0",
"sort":"0",
"threshold":"0",
"theme":"",
"signature":"",
"signature_format":"0",
"created":"1316602317",
"access":"1352643854",
"login":"1352666338",
"status":"1",
"timezone":"10800",
"language":"ar",
"picture":"",
"init":"mohammed.abdelrasoul#gmail.com",
"data":"a:5:{s:18:\"country_iso_code_2\";s:2:\"SA\";s:13:\"timezone_name\";s:11:\"Asia/Riyadh\";s:5:\"block\";a:1:{s:7:\"webform\";a:1:{s:15:\"client-block-88\";i:1;}}s:13:\"form_build_id\";s:37:\"form-3ae73833f08accc7abe5517347ea87eb\";s:7:\"contact\";i:0;}",
"country_iso_code_2":"SA",
"timezone_name":"Asia/Riyadh",
"block":{
"webform":{
"client-block-88":1
}
},
"form_build_id":"form-3ae73833f08accc7abe5517347ea87eb",
"contact":0,
"roles":{
"2":"authenticated user"
}
}
}
how i can get the objects data or parse the result to get user name
any help or examples will be appreciated
You need to use the NSJSONSerialization class method, JSONObjectWithData:options:error: to create an NSDictionary:
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if (! error) {
NSLog(#"%#",jsonDict);
}else{
NSLog(#"%#",error.localizedDescription);
}
This will get you to the point where you can look at the dictionary, which will be easier to read. It looks like you need to use objectForKey:#"sessid" to get you to user, then objectForKey#"user", then objectForKey:#"name" to get you to the name.
Check out this framework for parsing json. https://github.com/stig/json-framework/
Also check out this answer iPhone/iOS JSON parsing tutorial. You'll find a link to a tutorial you can do to get acquainted with json parsing in ios.
See this answer and some code :
NSMutableData *data; // Contains data received from the URL connection declares in header
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)dataIn
{
// Do it this way because connection doesn't guarantee all the data is in
POLLog(#" Tide View connection");
[data appendData:dataIn];
}
- (void) connectionDidFinishLoading:(NSURLConnection *) conn
{
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *results = [jsonString JSONValue]; // This is a new category added to the NSString by SBJSON
//100 parameters
for (int n=0;n<=100;n++)
{
// Get all the returned results
params[n] = [[results objectForKey:[NSString stringWithFormat:#"param%d",n]] floatValue];
}
To expand upon rdelmar's answer (which I think you should accept), you can use NSJSONSerialization and then navigate the NSDictionary results to extract the userName:
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData
options:0
error:&error];
if (error == nil) {
NSDictionary *userDictionary = [jsonDict objectForKey:#"user"];
NSString *userName = [userDictionary objectForKey:#"name"];
// do what you need with the userName
} else {
NSLog(#"%#",error.localizedDescription);
}
Or if using the latest version of Xcode, you can replace those objectForKey references with the even more concise Modern Objective-C syntax:
NSDictionary *userDictionary = jsonDict[#"user"];
NSString *userName = userDictionary[#"name"];

Resources