【问题标题】:How can I get the JSON data from a URL into my Objective-C application, Using XCode 8?如何使用 XCode 8 从 URL 获取 JSON 数据到我的 Objective-C 应用程序?
【发布时间】:2017-02-09 00:32:44
【问题描述】:

我目前正在尝试从 URL 获取天气信息,并将其转换为字符串或数据文件,我可以使用这些文件在屏幕上使用标签显示信息。

我根据目前收到的回复编辑了以下内容;我目前的代码如下:

// 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);

我已经注释掉或分离了部分,因为我收到了一个异常处理程序错误,我将它缩小到这一行(或不同方法中的等效项):

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

这可能与 JSON 数据、格式、来源有关,或者我可能需要在访问之前更改设置或权限。我确实使用方法 4 收到了此消息: “pp Transport Security 已阻止明文 HTTP (http://) 资源加载,因为它不安全。可以通过应用程序的 Info.plist 文件配置临时异常。” 但我不知道我需要进行哪些编辑,而且它说的是临时的,所以我认为这不是你想要修复它的方式。我什至不知道这是否与我的问题有关,或者我将不得不面对的其他事情。

有问题的 JSON 数据如下所示:

{
    "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
}

最终我希望能够通过以下方式访问它:

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

任何进一步的帮助将不胜感激; 提前感谢那些已经指导我的人:)

【问题讨论】:

  • 欢迎来到 SO。您应该在创建自己的答案之前搜索答案。这个问题已经被问很多次了,对于同一个问题有很多答案,基本上都是一样的。
  • 谢谢;在过去的几周里,我发现在最近的更新之后,许多关于我的查询的旧帖子都不再起作用了,到目前为止,那个链接中的答案都没有起作用,因为我不知道这是实际问题,我已经发布了我所做的并指定了平台,希望找到问题所在。它可能是来自网站的 JSON 数据格式,这与该链接中的示例不同,它可能是链接中未提及的安全性或设置,因此我不知道我是否正确,它可能是别的东西
  • 我删除了重复的标志。但是,如果您在问题中写下您已经搜索了类似的问题并链接了一些,并且它们对您不起作用,那么这对其余部分会有所帮助。您的问题是 “Transport Security 已阻止明文 HTTP” 您无法再从 iOS 连接到不安全的服务器。您需要运行 https 或将密钥和 URL 添加到您的 plist。 在此处查看答案stackoverflow.com/questions/30731785/…Apple 可能会拒绝您没有 https 的应用

标签: ios objective-c json


【解决方案1】:

更改此代码:

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

进入这个:

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

更新

您仍然收到错误是因为以下 2 行:

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

您的网址为 nil,因为您的路径包含特殊字符。 将这两行更改为:

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

【讨论】:

  • 感谢您的帮助,但即使进行了这些修改,我仍然收到“未捕获的异常”错误,我的代码中是否有任何步骤丢失,您能想到的任何内容,因为这是新的领土对我来说,我可能错过了一些其他明显的东西
  • 请查看我的更新答案。这将解决您的问题。
【解决方案2】:

最有可能的数据是零。 JSONObjectWithData 认为编程错误的一件事是被传递为零;那是它抛出异常的时候。我不认为 initWithContentsOfFile 接受不是文件 URL 的 URL。

顺便说一句。结果绝对不是 NSMutableDictionary。它可能是一个 NSDictionary,但你需要检查一下。而不是 [s objectForKey:@"temperature"] 只需写 s[@"temperature"]。

【讨论】:

  • 谢谢你,我会试试这些,看看我如何相处:)
【解决方案3】:

你有三个问题:

  1. 您正在尝试将远程数据源作为文件打开
  2. 必须将远程数据源字符串转换为 URL
  3. NSJSONSerialization 的返回类型只是一个 NSDictionary

以下是更正后的代码:

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];

【讨论】:

  • 感谢您的建议,我尝试了这种方法,当我的调试进一步深入时,我仍然收到“NSException 类型的未捕获异常”错误:- NSDictionary *s = [NSJSONSerialization JSONObjectWithData :数据选项:0 错误:NULL]; - 知道为什么会发生这种情况,或者我是否遗漏了其他东西?该网址绝对有效(您可以在自己的浏览器中测试)
  • 您需要添加一些与从 initWithContentsOfURL 返回的 NSData 对象相关的 NSLog 语句。检查是否为 nil,如果它不是 nil,则转储内容等。
【解决方案4】:

您是否设法禁用 ATS?尝试将以下内容添加到您的 Info.plist:

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

我还要添加一个数据检查:

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];

【讨论】:

    猜你喜欢
    • 2012-12-15
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多