Retrieve data from NSMutableArray - ios

I am only starting with IOS Development and creating an IOS application (Final project) for my computer science class which uses JSON to get data from remote MySql database.
Here is the method I call from ViewDidLoad:
- (void)loadJSON
{
//-- Make URL request with server
NSHTTPURLResponse *response = nil;
NSString *jsonUrlString = [NSString stringWithFormat:#"http://vito-service.ru/studentsconnect/profile.php"];
NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//-- Get request and response though URL
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//-- JSON Parsing
NSMutableArray *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"Result = %#",result);
}
and NSLog prints the correct data:
Result = {
users = (
{
IdUser = 1;
facebook = "";
fullname = "";
instagram = "";
phonenumber = "";
username = moderas;
},
{
IdUser = 2;
facebook = "fb.com/petroffmichael";
fullname = "Michael Perov";
instagram = "#petroffmichael";
phonenumber = "(650)557-6168";
username = petroffmichael;
},
{
IdUser = 3;
facebook = "fb.com/testuser";
fullname = "Test User";
instagram = "#testuser";
phonenumber = "111 111-1111";
username = testuser;
}
);
}
But how can I retrieve this data as Strings to put them to the labels then? I tried lots of different options of creating Data objects, which I found here on stack overflow but I always get an "unrecognized selector sent to instance" error. I also tried creating a separate NSObject
#synthesize IdUser, username, fullname, phonenumber, facebook, instagram;
- (id) initWithUsername: (NSString *)uUsername andUserFullName: (NSString *)uFullname andUserPhonenumber: (NSString *)uPhonenumber andUserFacebook: (NSString *)uFacebook andUserInstagram: (NSString *)uInstagram andUserId: (NSString *)uId
{
self = [super init];
if (self) {
username = uUsername;
fullname = uFullname;
phonenumber = uPhonenumber;
facebook = uFacebook;
instagram = uInstagram;
IdUser = uId;
}
return self;
}
and then retrieving data with this method:
-(void)retrieveData
{
NSURL *url = [NSURL URLWithString:getDataUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
usersArray = [[NSMutableArray alloc] init];
for (int i=0; i<jsonArray.count; i++) {
NSString * uId = [[jsonArray objectAtIndex: i] objectForKey:#"IdUser"];
NSString * uUsername = [[jsonArray objectAtIndex: i] objectForKey:#"username"];
NSString * uFullname = [[jsonArray objectAtIndex: i] objectForKey:#"fullname"];
NSString * uPhonenumber = [[jsonArray objectAtIndex: i] objectForKey:#"phonenumber"];
NSString * uFacebook = [[jsonArray objectAtIndex: i] objectForKey:#"facebook"];
NSString * uInstagram = [[jsonArray objectAtIndex: i] objectForKey:#"instagram"];
[usersArray addObject:[[User alloc] initWithUsername:uUsername andUserFullName:uFullname andUserPhonenumber:uPhonenumber andUserFacebook:uFacebook andUserInstagram:uInstagram andUserId:uId]];
}
}
I have all the important #import's but I still get the same error:
2014-04-23 18:35:26.612 testimage[47155:70b] -[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xa72a8b0
2014-04-23 18:35:26.813 testimage[47155:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xa72a8b0'
Can anybody please help to find the right solution?
Thanks!
After listening to multiple comments I changed the code but still receive an error..
I guess I am still doing something wrong
jsonArray is not an array anymore:
#property (nonatomic, strong) NSDictionary *jsonArray;
#property (nonatomic, strong) NSMutableArray *usersArray;
Then the method:
-(void)retrieveData
{
NSURL *url = [NSURL URLWithString:getDataUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
usersArray = [[NSMutableArray alloc] init];
for (NSDictionary *dict in jsonArray)
{
NSString * uId = [dict objectForKey:#"IdUser"];
NSString * uUsername = [dict objectForKey:#"username"];
NSString * uFullname = [dict objectForKey:#"fullname"];
NSString * uPhonenumber = [dict objectForKey:#"phonenumber"];
NSString * uFacebook = [dict objectForKey:#"facebook"];
NSString * uInstagram = [dict objectForKey:#"instagram"];
[usersArray addObject:[[User alloc] initWithUsername:uUsername andUserFullName:uFullname andUserPhonenumber:uPhonenumber andUserFacebook:uFacebook andUserInstagram:uInstagram andUserId:uId]];
}
}
And I am still getting the same error:
2014-04-23 20:44:43.971 testimage[48285:70b] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0xa5547d0
2014-04-23 20:44:44.053 testimage[48285:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0xa5547d0'

Look closely at that output. It isn't what you say. What you have there is not an array — it's a dictionary with one key, #"users", whose value is an array. That's what it's telling you when it starts with { users = …. If you want the array, you'll need to retrieve it from the dictionary.

Try this:
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSMutableArray *result = [res objectForKey:#"users"];
This will do. The response isn't a NSArray. It is a Dictionary. First get the array from the dictionary and then use it as you are using. Hope this helps... :)
EDIT:
You can rewrite the loop by this:
for (NSDictionary *dict in jsonArray)
{
//dict is a NSDictionary. Just get value for keys
}

Related

JSON String with Arrays iOS

My APP gets a JSON string from a api call JSON string has objects and a array in it. This is what i have done so far but i couldn't get the values from it . advice me please and I'm new to iOS .This is my JSON String :
{
"Id":"0d95a9f6-c763-4a31-ac6c-e22be9832c83",
"Name":"john",
"ProjectName":"project1",
"StartDate":"\/Date(1447200000000)\/",
"Documents":
[{
"Id":"2222a","Name":"book1","ContentType":"application/pdf"
},
{
"Id":"3718e","Name":"Toolbox","ContentType":"application/fillform"
}]
}
Code
NSString *URLString = [NSString stringWithFormat:#"http://mysite/API/Assignments?"];
NSURL *url = [NSURL URLWithString:URLString];
NSData *data=[NSData dataWithContentsOfURL:url];
json=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
assignArray=[[NSMutableArray alloc]init];
for (int i=0; i<json.count; i++) {
NSString *aID=[[json objectAtIndex:i]objectForKey:#"Id"];
NSString *uName=[[json objectAtIndex:i]objectForKey:#"Name"];
NSString *pName=[[json objectAtIndex:i]objectForKey:#"ProjectName"];
//[self initwithUserID:uID userName:uName proName:pName];
// [self retrieveAssignmentDetails:aID];
AssignmentsJson *assignment=[[AssignmentsJson alloc]initwithassignID:aID userName:uName proName:pName];
[assignArray addObject:assignment];
your json is not array so parse like following
NSString *aID = json[#"Id"];
NSString *uName = json[#"Name"];
NSString *pName = json[#"ProjectName"];
NSString *startDate = json[#"StartDate"];
NSArray *documents = json[#"Documents"];
for (NSDictionary *item in documents) {
NSString *itemID = item[#"Id"];
NSString *itemName = item[#"Name"];
NSString *itemContentType = item[#"ContentType"];
}
Your Json Object is NSDictionary. so you can directly get data using valueForKey
NSDictionary *json=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSString *aID = json[#"Id"];
NSString *uName = json[#"Name"];
NSString *pName = json[#"ProjectName"];
for Id,Name and ContentType is inside your array object within your NSDictionary object.
so you can get those values accessing array index.
NSArray *arr = json[#"Documents"];
for (int i=0; i<arr.count; i++) {
NSString *aID=[[arr objectAtIndex:i]objectForKey:#"Id"];
NSString *uName=[[arr objectAtIndex:i]objectForKey:#"Name"];
NSString *cType=[[arr objectAtIndex:i]objectForKey:#"ContentType"];
}
You should learn NSArray and NSDictionary Structure first. it will help you in future. Hope this will help you.
you can do it by following way.
Your Json is in NSDictionary format.
NSData * data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://mysite/API/Assignments?"]];
NSDictionary * dicResponse = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if(dicResponse){
NSString * strID = [dicResponse valueForKey:#"Id"];
NSString * strName = [dicResponse valueForKey:#"Name"];
NSString * strProjectName = [dicResponse valueForKey:#"ProjectName"];
NSString * strDate = [dicResponse valueForKey:#"StartDate"];
NSArray * arrDocuments = [NSArray arrayWithArray:[dicResponse valueForKey:#"Documents"]];
for (int i=0; i< arrDocuments.count; i++) {
NSString * ID=[[arrDocuments objectAtIndex:i]valueForKey:#"Id"];
NSString * Name=[[arrDocuments objectAtIndex:i]valueForKey:#"Name"];
NSString * Type=[[arrDocuments objectAtIndex:i]valueForKey:#"ContentType"];
}
}

Unrecognized selector when parsing JSON

So I have the photograph below which is a screenshot I took of a JSON script I am trying to read from a URL. In the code section below, I managed to get the 'name' attribute and assign it to the 'name' NSString object, but when I try do the same for 'address' I get the following error:
[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x174260980
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x174260980'
whats the difference between how I did it inside 'venues' than inside 'location'? I tried many different ways to do it, some including arrays, but nothing seems to work.
NSURL *url = [NSURL URLWithString:urlString];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSDictionary *responseDictionary = [dataDictionary objectForKey:#"response"];
NSDictionary *venueDictionary = [responseDictionary objectForKey:#"venues"];
for (NSDictionary *dict in venueDictionary) {
NSLog(#"%#", dict);
NSString *name = [dict objectForKey:#"name"];
NSDictionary *locationDictionary = [dict objectForKey:#"location"];
for (NSDictionary *locationDict in locationDictionary) {
NSString *address = [locationDict objectForKey:#"address"];
NSLog(#"%#", address);
}
}
You're expecting the "location" key to point to an array, but it doesn't. It points to an object, get rid of for (NSDictionary *locationDict in locationDictionary) { and just pull the address out of locationDictionary instead.

Key Value pair Objective-C

so I've been given a task of using a flickr API created by a lecturer, and we have to use it to populate a tableview of a particular user. I'm able to count the number of elements etc, but I can't figure out for the life of me how to actually call the image/photo element of the pair?
This is the code:
- (NSArray *) photosForUser: (NSString *) friendUserName
{
NSString *request = [NSString stringWithFormat: #"https://api.flickr.com/services/rest/?method=flickr.people.findByUsername&username=%#", friendUserName];
NSDictionary *result = [self fetch: request];
NSString *nsid = [result valueForKeyPath: #"user.nsid"];
request = [NSString stringWithFormat: #"https://api.flickr.com/services/rest/?method=flickr.photos.search&per_page=%ld&has_geo=1&user_id=%#&extras=original_format,tags,description,geo,date_upload,owner_name,place_url", (long) self.maximumResults, nsid];
result = [self fetch: request];
return [result valueForKeyPath: #"photos.photo"];
}
What is used to fetch the data:
- (NSDictionary *) fetch: (NSString *) request
{
self.apiKey = #"26225f243655b6eeec8c15d736b58b9a";
NSLog(#"self.APIKey = %#", self.apiKey);
NSString *query = [[NSString stringWithFormat: #"%#&api_key=%#&format=json&nojsoncallback=1", request, self.apiKey]
stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSURL *queryURL = [NSURL URLWithString: query];
NSData *responseData = [NSData dataWithContentsOfURL: queryURL];
if (!responseData)
return nil;
NSError *error = nil;
NSDictionary *jsonContent = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
if (!jsonContent)
NSLog(#"Could not fetch '%#': %#", request, error);
return jsonContent;
}
Can anyone give me any pointers on how I can actually call the image?
Much appreciated.
edit: this is an NSLog output of what's in the JSON array received from the flickr API.
latestPhotos (
{
accuracy = 16;
context = 0;
dateupload = 1397679575;
description = {
"_content" = "<a href=\"https://www.flickr.com/photos/tanjabarnes/\">
};
farm = 3;
"geo_is_contact" = 0;
"geo_is_family" = 0;
"geo_is_friend" = 0;
"geo_is_public" = 1;
id = 13902059464;
isfamily = 0;
isfriend = 0;
ispublic = 1;
latitude = "34.062214";
longitude = "-118.35862";
owner = "66956608#N06";
ownername = Flickr;
"place_id" = "I78_uSpTWrhPjaINgQ";
secret = cc17afe1b3;
server = 2928;
tags = "panorama losangeles beverlyhills tanjabarnes";
title = blahlbah
woeid = 28288701;
}
)
You need to construct the URL of the image using the ids in your JSON array. Like this:
http://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}.jpg
or
http://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}_[mstzb].jpg
or
http://farm{farm-id}.staticflickr.com/{server-id}/{id}_{o-secret}_o.(jpg|gif|png)
So in your example:
http://farm3.staticflickr.com/2928/13902059464_cc17afe1b3.jpg
Here's how you get to your images:
NSArray *photos = [self photosForUser:friendUserName];
for(NSDictionary *dictionary in photos) {
NSString *farmId = [dictionary objectForKey:#"farm"];
NSString *serverId = [dictionary objectForKey:#"server"];
NSString *photoId = [dictionary objectForKey:#"id"];
NSString *secret = [dictionary objectForKey:#"secret"];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://farm%#.staticflickr.com/%#/%#_%#.jpg", farmId, serverId, photoId, secret]];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
// Do something with your image here
}
Reference: https://www.flickr.com/services/api/misc.urls.html

how to pass a NSString from NSObject to UIViewcontrller?

I understand this is a very basic question, but as a beginner who already google a bunch of resources I just couldn't make it. I would like to pass a NSString from a NSObject to UIViewController. I know if want to pass a value to another class I need to make it public. I have a method in DataConnection.m
- (void)jsonParse{
NSString* path = #"http://phdprototype.tk/getResultData.php";
NSURL* url = [NSURL URLWithString:path];
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary* resultDic = [dic objectForKey:#"maxid"];
NSString* recData = [resultDic objectForKey:#"recommendData"];
NSString* rData = [resultDic objectForKey:#"room"];
NSString* lData = [resultDic objectForKey:#"level"];
NSLog(#"recommendData = %#, room = %#, level = %#",recData,rData,lData);
self->_room = rData;
self->_level = lData;
self->_recommendID = recData;
}
what I want to do is to pass the value of recData to another UIViewController. So I have made a code in 'h:
#property (nonatomic) NSString *recommendID;
in my UIViewController I have this code:
[self.delegate NextScreen: self ndx: recData];
I would like pass value to reData. Anyone tell me how to do that?? sorry for my programme knowledge!
~~~ update~~~
I have put the codes like this:
DataConnection *data = [[DataConnection alloc] init];
[data jsonParse];
[self.delegate NextScreen: self ndx: [data.recommendID]];
but i got expected identifier??
"mmmmmm~i have try some code like DataConnection *data =
[DataConnection jsonParse]; but i got error of no known class method
for selector of "jsonParse" ps: i have put
- (void)jsonParse; in DataConnection.h –"
Above mentioned way is wrong way of calling a method. you can call it this way:
DataConnection *data = [[DataConnection alloc] init];
[data jsonParse];
But, as per your question,
"what I want to do is to pass the value of recData to another
UIViewController. So I have made a code in 'h:"
Change the return type of jsonParse to NSDictionary and return the resultDic which you wish to transfer.
- (NSDictionary *)jsonParse{
NSString* path = #"http://phdprototype.tk/getResultData.php";
NSURL* url = [NSURL URLWithString:path];
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary* resultDic = [dic objectForKey:#"maxid"];
/* NSString* recData = [resultDic objectForKey:#"recommendData"];
NSString* rData = [resultDic objectForKey:#"room"];
NSString* lData = [resultDic objectForKey:#"level"];
NSLog(#"recommendData = %#, room = %#, level = %#",recData,rData,lData);
self->_room = rData;
self->_level = lData;
self->_recommendID = recData;*/
return resultDic;
}
In your view controller,
#property (nonatomic,retain) NSDictionary *resultDict;
#synthesize resultDict;
DataConnection *data = [[DataConnection alloc] init];
self.resultDict = (NSDictionary *)[data jsonParse];
_recommendID = [resultDic objectForKey:#"recommendData"];
_room = [resultDic objectForKey:#"room"];
_level = [resultDic objectForKey:#"level"];
now recommendID will have the recData value.
have you included
#synthesize recommendID;
in the DataConnection.m file?
I did consider adding this as a comment, but i dont have enough reputation for commenting.

Parsing a JSON array with dictionaries

I'm having some trouble getting to the data I want to in the JSON file. Here is a shortened version of the output from my console:
{
AUD = {
15m = "125.15547";
24h = "124.74";
buy = "121.0177";
last = "125.15547";
sell = "123.44883";
symbol = "$";
};
BRL = {
15m = "120.34";
24h = "120.34";
buy = "120.34";
last = "120.34";
sell = "120.34";
symbol = "R$";
};
CAD = {
15m = "129.08612";
24h = "131.07";
buy = "128.66227";
last = "129.08612";
sell = "129.08612";
symbol = "$";
};
}
I'm trying to parse the file using the built in JSON parsing library. Here is the parser in my viewDidLoad method:
_tickerArray = [NSMutableArray array];
NSURL *tickerDataURL = [NSURL URLWithString:#"https://blockchain.info/ticker"];
NSData *jsonData = [NSData dataWithContentsOfURL:tickerDataURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", dataDictionary);
NSArray *ar = [NSArray arrayWithObject:dataDictionary];
for (NSString *key in [dataDictionary allKeys]) {
for (NSDictionary *dict in ar) {
TickerData *t;
t.currency = [dict objectForKey:key];
t.symbol = [dict objectForKey:#"symbol"];
t.last = [dict objectForKey:#"last"];
[_tickerArray addObject:t];
}
}
I want to store the currency code (like AUD or BRL) into t.currency along with some of the other data contained in the currency dictionary but now my app is crashing.
Error code:
NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
None of the objects seem to get added to the _tickerArray
Help?
EDIT: Getting the keys to display with the proper data populating other fields:
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", dataDictionary);
for (NSString *key in [dataDictionary allKeys]) {
NSDictionary *dic=[dataDictionary objectForKey:key];
TickerData *t=[[TickerData alloc] init];
t.currency = key;//EDITED
t.symbol = [dic objectForKey:#"symbol"];
t.last = [dic objectForKey:#"last"];
[_tickerArray addObject:t];
}
t is nil, you have to alloc/ init it:
TickerData *t = [[TickerData alloc] init];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", dataDictionary);
//NSArray *ar = [NSArray arrayWithObject:dataDictionary];//REMOVED
for (NSString *key in [dataDictionary allKeys]) {
NSDictionary *dic=[dataDictionary objectForKey:key];//ADDED
for (NSString *dickey in [dic allKeys]) { //MODIFIED
NSDictionary *dict=[dic objectForKey:dicKey];//ADDED
TickerData *t=[[TickerData alloc] init];//ALLOC INIT ?
t.currency = key;//EDITED
t.symbol = [dict objectForKey:#"symbol"];
t.last = [dict objectForKey:#"last"];
[_tickerArray addObject:t];
}
}
Your data doesn't contain any array, its all dictionaries, try the above code see comments too..
Hope it works..
Edited:
Yes you have initialize the object too, as suggested above in other answers..
Try it....
NSURL *url = [NSURL URLWithString:#"https://blockchain.info/ticker"];
NSLog(#"API : %#",url);
NSMutableData *jsonData = [NSMutableData dataWithContentsOfURL:url];
NSString *data = [[NSString alloc] initWithBytes: [jsonData mutableBytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
dictionary = [data JSONValue];
NSDictionary *dict = [dictionary objectForKey:#"AUD"];
NSLog(#"%#",dict);
NSString *last = [dict valueForKey:#"last"];
NSLog(#"%#",last);

Resources