简体   繁体   中英

How can I get the JSON data from a URL into my Objective-C application, Using XCode 8?

I am currently trying to get weather information from a URL and into a string or data file that I can use to display the information on screen using labels.

I have edited the following based on the responses I have gotten so far; the code I have so far is as follows:

// Method 1
NSString *path = @"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; // This line triggers the exception error

// method 2
NSString *path = @"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; // this line triggers the exception error


// Method 3
NSString *path = @"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b";
NSURL *url = [NSURL URLWithString:path];
NSError *error = nil;
NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; // this line triggers exception error
/*
if (error)
    NSLog(@"JSONObjectWithData error: %@", error);

for (NSMutableDictionary *dictionary in array)
{
    NSString *arrayString = dictionary[@"array"];
    if (arrayString)
    {
        NSData *data = [arrayString dataUsingEncoding:NSUTF8StringEncoding];
        NSError *error = nil;
        dictionary[@"array"] = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (error)
            NSLog(@"JSONObjectWithData for array error: %@", error);
    }
}
 */

 // Method 4
 //-- Make URL request with server
 NSHTTPURLResponse *response = nil;
 NSString *jsonUrlString = [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b"];
 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]; // This line triggers the exception error
 //NSLog(@"Result = %@",result);

I've commented out or separated parts because I am getting an exception handler error, and I narrowed it down to this line (or the equivalent in different methods):

NSMutableDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

It may have something to do with the JSON data, the format, the source, or maybe I need to change settings or permissions before accessing it. I did get this message with method 4: "pp Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file." But I do not know what edits I need to make, and it says temporary, so I assume that's not how you're meant to fix it anyway. I do not even know if this is related to my issue, or something else I will have to face.

JSON data in question looks like following:

{
    "coord":{"lon":-0.13,"lat":51.51},
    "weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],
    "base":"stations",
    "main":
        {"temp":282.4,"pressure":1014,"humidity":76,"temp_min":281.15,"temp_max":284.15},
    "visibility":10000,
    "wind":{"speed":4.1,"deg":280},
    "clouds":{"all":20},
    "dt":1486471800,
    "sys":
        {"type":1,"id":5091,"message":0.004,"country":"GB","sunrise":1486452468,"sunset":1486486938},
    "id":2643743,
    "name":"London",
    "cod":200
}

And ultimately I want to be able to access it with something like:

NSString *temperature =s[@"temperature"];
NSLog(@"%@", temperature);
NSString *humidity = [s objectForKey:@"humidity"]; 

Any further assistance would be greatly appreciated; Thanks in advance and to those that have guided me already :)

Change this code:

NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSMutableDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

into this:

NSData *data = [NSData dataWithContentsOfURL:path];
NSError *error = nil;
NSDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

UPDATE

You are still getting error is because of these 2 lines:

NSString *path = @"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b";
NSURL *url = [NSURL URLWithString:path];

Your url is nil because your path contains special characters. Change those 2 lines into these:

NSString *path = [@"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString:path];

Most likely data is nil. The one thing JSONObjectWithData considers a programming error is being passed nil; that's when it throws an exception. I don't think initWithContentsOfFile accepts URLs that are not file URLs.

BTW. The result is most definitely not an NSMutableDictionary. It may be an NSDictionary, but you need to check this. And instead of [s objectForKey:@"temperature"] just write s[@"temperature"].

You have three problems:

  1. you are trying to open a remote data source as a file
  2. a remote data source string must be converted to a URL
  3. the return type from NSJSONSerialization is just an NSDictionary

Here is the corrected code:

NSString *path = @"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

Did you manage to disable ATS? Try to add the following to you Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>

I would also add a check for data:

NSString *path = @"http://api.openweathermap.org/data/2.5/weather?q={London}&appid=4737e39e801a13bd10da52d8837e470b";
NSURL *url = [NSURL URLWithString:path];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSAssert(data, @"No data received!");
NSDictionary *s = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM