I use the iOS 5 JSON features to load data from web.
My target is to get some twitter data - the data is filtered via web and I get it via the following url:
http://botpwn.org/ios/getfollowers.json?uid=63964843
Thats working and I dont have problems there - but my problems begin with parsing the data in my app.
I load the data here
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://botpwn.org/ios/getfollowers.json?uid=%#", my_uid]]];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
-(void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
latestFollower = [json objectForKey:#"followers"]; //2
for (int i = 0; i < [latestFollower count]; i++){
[temp addObject:[latestFollower objectAtIndex:i]];
}
if (latestFollower == nil || latestFollower.count == 0){
NSLog(#"No followers");
}
}
And now I always get the answer that I have an empty latestFollower array - and I know that the problem is, that some names (not screennames) of twitter users contain special chars and iOS can't parse it.
I searched for solutions (set the php header to utf8 etc.) but nothing helps.
Maybe you have an idea how to parse it right, or maybe I'm doing something wrong but i don't get it.
EDIT: Just fixed it myself - finally I used a tool (http://jsonlint.com/) to check whether there is an error in the json output and yes - it was. Thanks for your ideas ! :)
Just fixed it myself - finally I used a tool (http://jsonlint.com/) to check whether there is an error in the json output and yes - it was. Thanks for your ideas ! :)
Related
This question already has answers here:
NSLog on devices in iOS 10 / Xcode 8 seems to truncate? Why?
(7 answers)
Closed 5 years ago.
I'm pulling a .json file from my server and trying to read it into an NSDictionary in my app. Some of the file is being correctly parsed but it is incomplete - only some of the file is being read.
The strange thing is that the NSData is an equal length to the actual file, so it seems that it has full access, at least at some stage. When I log the NSData however, it seems to be way too short for the size of the file.
Here's the code I'm using to find the bug:
//SYNC BOOL
if (isSyncing){ return; }
isSyncing = true;
//FETCH BOOTSTRAP
NSError * fetchError = nil;
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:syncPath]
options:kNilOptions
error:&fetchError];
if (fetchError){ [self error]; return; }
//PARSE JSON
NSError * jsonError = nil;
NSDictionary * json = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&jsonError];
if (jsonError){ [self error]; return; }
NSLog(#"data length is %lu", data.length);
NSLog(#"json is %#", json);
I've tried loading remotely from the server and locally from NSBundle - same result.
Could this be related to encoding / a rogue character in the JSON / some NSData max length?
Those options on the NSData fetch method and JSON Serialisation method, I've always left blank with no issue in the past, in terms of what's being pulled it's the same. I've also tried requests and sessions etc with no love.
EDIT:
I should add that when I log the the .allKeys of the json dictionary, it returns all keys correctly (including those not included in the log of the dictionary itself). This coupled with the correct NSData length implies that the data is in fact there, in completion. An explanation would be if the NSLog itself is somehow being truncated, implying an error when none exists. The problem is I haven't changed anything there. It could be a beta bug in the new Xcode.
EDIT B:
Logger Error on Xcode 9?
NSString * string = #"";
for (int n = 0; n < 10000; n++){
string = [NSString stringWithFormat:#"%# %i",string,n];
}
NSLog(#"string is %#", string);
Outputs to 6.7k not 10k.
See if you get different results with:
NSLog(#"json is %#", json.description);
Or to rule out NSLog altogether, maybe breakpoint the code there, and right click on json in the variables pane of the debug area and choose Print description of "json"
My experience is NSJSONSerialization will return an error for malformed JSON.
This is some silly feature in Xcode itself it seems. This define works for the full NSLog:
#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
Taken from here:
NSLog on devices in iOS 10 / Xcode 8 seems to truncate? Why?
How many developers will spend time looking for imaginary bugs in the lazy logger...
For those coming afterwards, I'm running Xcode 9.0.
I'm trying to resolve the Cocoa error 3840 for a couple hours now. I've read all the answers posted here on stackoverflow and on any other sources I could find but nothing seems to help...
The problem is that I know this error occurs when there is something wrong with the JSON object you receive from the server but the JSON I'm receiving is valid. I've tested it on multiple JSON validators online and its checks out every time.
Here's my code:
NSError *localError = nil;
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&localError];
if (localError != nil) {
NSLog(#"%#", [localError localizedDescription]);
} else {
//NSDictionary *dict = [parsedObject objectForKey:#"status"];
//NSLog(#"%#", [dict objectForKey:#"message"]);
}
return parsedObject;
Heres a google drive link to the JSON: https://docs.google.com/document/d/1rC_--QiS85A82L2AohuqjC0JWIgVEAj68i7UUOxpvMw/edit?usp=sharing
This error only occurs for some responses that i get from the server. The same code works fine for other links from the same API.
I've tried this with NSArray instead of NSDictionary thinking that maybe the server might be serving an array instead of a hash, also tried changing the option value for JSONObjectWithData:data:options:error method but as you can guess nothing worked.
I'll greatly appreciate any help I can get.
I want to retrieve Recent Activity images from flickr application, please any one suggest me how to retrieve that. thanks in advance.
This is not the best way of doing this but I will provide you a way to retrieve recent pictures on flickr. Standford iTunesU had a few lectures that related to this. I am getting almost all of my information from them. Here is a link to the course material:
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/
For the basic, non multithreaded version look under lecture 10 and download Shutterbug Universal. You will also need a flickr API key which you can currently get here:
http://www.flickr.com/services/api/misc.api_keys.html
I will attempt to outline for you though how to go about completing your request, especially since either of those links may not be around for long.
You will want to create a class FlickrFetcher or something, then have a public class method
+ (NSArray *)latestGeoreferencedPhotos;
Implementation
+ (NSArray *)latestGeoreferencedPhotos
{
NSString *request = [NSString stringWithFormat:#"http://api.flickr.com/services/rest/?method=flickr.photos.search&per_page=500&license=1,2,4,7&has_geo=1&extras=original_format,tags,description,geo,date_upload,owner_name,place_url"];
return [[self executeFlickrFetch:request] valueForKeyPath:#"photos.photo"];
}
Where executeFlickrFetch is implemented:
+ (NSDictionary *)executeFlickrFetch:(NSString *)query
{
query = [NSString stringWithFormat:#"%#&format=json&nojsoncallback=1&api_key=%#", query, FlickrAPIKey];
query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *jsonData = [[NSString stringWithContentsOfURL:[NSURL URLWithString:query] encoding:NSUTF8StringEncoding error:nil] dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
NSDictionary *results = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error] : nil;
if (error) NSLog(#"[%# %#] JSON error: %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);
return results;
}
You will need to get your API key and either define it (#define FlickrAPIKey #"myAPIkey") or just directly insert it here.
In the Standford course they call latestGeoreferencedPhotos from a TVC subclass and set an array of photos in viewDidLoad:
// photos is a defined property
self.photos = [FlickrFetcher latestGeoreferencedPhotos];
Then in the setter for photos they reload a tableView that presents the images:
- (void)setPhotos:(NSArray *)photos
{
_photos = photos;
[self.tableView reloadData];
}
photos is now an array of dictionaries where so you can access specific image data by doing things like:
return [self.photos[row][#"title"] description]; // description because could be NSNull
I did find a github resource that may be valuable:
https://github.com/lukhnos/objectiveflickr.
I did not look into it much but it is probably worth checking into!
Your question did not provide much detail so I hope that this answer is sufficient for your needs.
I'm new to ios development.My app gets slower when i'm parsing image using json parser in ios 5.
Please could anybody help to solve this problem.
-(NSDictionary *)Getdata
{
NSString *urlString = [NSString stringWithFormat:#"url link"];
urlString = [urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *url = [NSURL URLWithString:urlString];
NSData* data = [NSData dataWithContentsOfURL:url];
NSError* error;
NSDictionary* json;
if (data) {
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"json...%#",json);
}
if (error) {
NSLog(#"error is %#", [error localizedDescription]);
// Handle Error and return
// return;
}
return json;
}
Your description of the problem isn't exactly helpful. It's unclear to me if everything in your app is slow, or just certain operations; if you exprience a slow action and then it becomes fast again or if it continues to perform slowly.
Whatever, the general rule is to performan all network communication including the parsing of the answer on a separate thread, i.e. not on the main thread that is responsible for managing the user interface. That way the app remains responsive and appears to be fast.
If you can download the images separately, you can already display the result and put a placeholder where the image will appear. Later, when you have received the image you remove the placeholder and put the image there.
This line is probably the culprit.
NSData* data = [NSData dataWithContentsOfURL:url];
If you're calling this on the main thread (and because you haven't mentioned threads at all I suspect that you are) it will block everything and wait until the server has responded.
This is a spectacularly bad experience for the user :)
You need to do all of this on a background thread and notify the main thread when you're done. There's a couple of ways of doing this (NSOperation etc) but the simplest is just this :
// Instead of calling 'GetData', do this instead
[self performSelectorOnBackgroundThread:#selector(GetData) withObject:nil];
// You can't return anything from this because it's going to be run in the background
-(void)GetData {
...
...
// Instead of 'return json', you need to pass it back to the main thread
[self performSelectorOnMainThread:#selector(GotData:) withObject:json waitUntilDone:NO];
}
// This gets run on the main thread with the JSON that's been got and parsed in the background
- (void)GotData:(NSDictionary *)json {
// I don't know what you were doing with your JSON but you should do it here :)
}
I'm having this problem. I'm trying to build an UITableView with data from a JSON Dictionary made with NSJSONSerialization. I have no idea where to start. i've been trying for 3 days but silo have achieved nothing. This is the code i've came up with:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define kJsonURL [NSURL URLWithString: #"http://rs-hosting.nl/panel/serverstatus_json.php"]
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:kJsonURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSDictionary *clients = [json objectForKey:#"announcements"];
NSArray *announcements = [clients objectForKey:#"announcement"];
NSDictionary* announcement = [announcements objectAtIndex:1];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
#end
I'm able to display content in a label on a single view in a label but i have no clue how to het all the data in the json to a table. Can someone please healp me out?
SDK: 5.1
OSX: 10.7.3
XCODE: 4.3.1
Tnx in advance
You need to store your data somewhere (keeping that NSDictionary with the whole json file is fine for a start) and then add a UITableView, set it up to point its data source to your class and then implement the UITableViewDataSource methods as outlined.
The UITableView will then request data from these methods as it fills in the table. The only two required methods are tableView:numberOfRowsInSection: and tableView:cellForRowAtIndexPath: so start with those two and get the data displaying on the table before doing any other customization.
after getting data in NSDictionary, save it in NSArray filled with NSString objects that u want to show and then call the function [Tableview reloadData]; in you ViewDidLoad function and ur good to go.