【问题标题】:Encoding issue: Cocoa Error 261?编码问题:Cocoa 错误 261?
【发布时间】:2010-12-28 05:11:24
【问题描述】:

所以我从我的 iPhone 应用程序中的 php 脚本中获取 JSON 字符串:

NSURL *baseURL = [NSURL URLWithString:@"test.php"];
NSError *encodeError = [[NSError alloc] init];
NSString *jsonString = [NSString stringWithContentsOfURL:baseURL encoding:NSUTF8StringEncoding error:&encodeError];
NSLog(@"Error: %@", [encodeError localizedDescription]);
NSLog(@"STRING: %@", jsonString);

在我测试输出时验证 JSON 字符串。现在我遇到了编码问题。当我获取单个回显行时,例如:

{ "testKey":"é" }

JSON 解析器工作正常,我能够创建一个有效的 JSON 对象。然而,当我获取我的 2MB JSON 字符串时,我会看到:

Error: Operation could not be completed. (Cocoa error 261.)

和一个空字符串。我的 PHP 文件本身是 UTF8,我没有使用 utf8_encode(),因为这似乎对数据进行了双重编码,因为我已经将数据作为 NSUTF8StringEncoding 提取。无论哪种方式,在我的单回声测试中,这种方法让我能够在构建 JSON 对象时成功记录 \ASDAS 样式的 UTF8 转义。

如果字符串较大,可能导致错误的原因是什么?

另外,我不确定它是否会有所不同,但我在我解析的 php 数据上使用 php 函数 addlashes() 来解释构建 JSON 字符串时的引号等。

【问题讨论】:

    标签: iphone objective-c cocoa json


    【解决方案1】:

    不知道这是否是您的问题,但我只是有一个类似的东西(stringWithContentsOfFile,没有 JSON),问题是该文件有 CRLF(windows)行尾和 Western-whatever-it's-所谓编码。我使用 SubEthaEdit 转换为 LF(Mac/Unix 行尾)和 UTF-8 编码,现在一切正常。

    【讨论】:

    • 检查文件编码类型也很有用。我使用文本牧马人来做到这一点。打开文件,在窗口底部会显示它的编码类型。我需要 UTF16,但有很多变化。
    【解决方案2】:

    编码问题:Cocoa 错误 261? 我通过尝试不同的编码解决了这个问题。首先我使用的是 NSUTF8,然后我切换到 NSASCIIStringEncoding 并且它工作了

    NSString* path = [[NSBundle mainBundle] pathForResource: @"fileName" ofType: @"type"];
    NSData* data = [NSData dataWithContentsOfFile:path];
    NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"%@",string);
    

    【讨论】:

      【解决方案3】:

      对我有帮助的只是将物理文件编码更改为 UTF-8。我的编辑器已将其设置为默认值,MacRoman,并且不喜欢带有重音符号的字母。

      【讨论】:

        【解决方案4】:

        我很惊讶在调用 [NSString stringWithContentsOfFile:encoding:error:] 时没有人提到使用不同的编码值而不是 NSUTF8StringEncoding。

        我在解析 JSON 文件时也遇到了 Cocoa 错误 261。我刚刚浏览了NSString encodings 的列表,直到一个工作。幸运的是,第一个对我有用:NSASCIIStringEncoding!

        您也可以使用NSString stringWithContentsOfFile:usedEncoding:error: 来尝试找到正确的编码(如下所述:How to use stringWithContentsOfURL:encoding:error:?)。

        【讨论】:

        • 这完全是我的问题。我接受的答案的问题是您可能无法更改输入文件。
        • 同意您可能无法更改输入文件。我的意思是:问题不在于 json(或 php),而在于字符串编码。我更改了文件,但也可以更改 NS 编码值。
        【解决方案5】:

        为了将来参考,如果您需要覆盖编码,并且您正在使用没有嵌入 NUL 的流,这样的事情可能会很好(我刚刚在这里写了一个粗略的草图大纲,请检查此代码是否存在在使用之前想要你想要的):

        NSHTTPURLResponse* resp=nil;
        NSData* jsonAsImmutableData = [NSURLConnection sendSynchronousRequest:
          [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://<whatever>"]]
          returningResponse:&resp error:NULL];
        
        NSMutableData*modifiedData = [NSMutableData dataWithData:jsonAsImmutableData];
        
        char extraNulls[7] =
          {0,0,0,0,0,0,0}; // is this defensive enough for your encoding?
        [modifiedData appendBytes:extraNulls length:7];
        
        NSString* jsonAsString = [NSString stringWithCString:[modifiedData bytes]
          encoding:<whatever your encoding is>];
        

        但我希望您最好的做法是检查您的服务器是否正在使用和声称使用 UTF-8 编码或其他 Apple iPhone 支持的编码。

        编辑

        修改的代码注释。

        【讨论】:

        • 我不太确定我理解你所说的足够防御是什么意思,或者这有什么额外的作用……你能详细说明一下吗?
        • 哦,如果您的编码碰巧是 32 位字符(例如 UTF32)而不是 8 位字符,则获得一个 32 位的结尾全部为空(终止 C 字符串,需要 stringWithCString: API 调用)可以只能通过添加 7 个 NUL 字符来确保(如果完全对齐则需要 4 个;在最坏的未对齐情况下需要额外的 3 个)。如果它只是 ASCII 8 位编码,1 NUL 字节就足够了,但我坚持额外,因为我不知道你使用的是什么编码。
        • 我当然是指具有高位清除的美国 ASCII(因此 8 位字节中的 7 位代码)。而且我不确定真正需要多少 Null 字节,即使是 UTF32 也是如此。我正在将检查交给您,以检查您的(特定)编码。谢谢你..!
        • 不幸的是,这似乎没有任何改变。
        • 好吧,一旦你在内存中有了字符字节,你可以手动在循环中使用一些 C 位旋转代码来检查编码规则,看看有什么问题被编码。我对 iPhone API 和字符编码的经验是,即使有人可能认为它应该有用地用替换字符替换任何错误的编码,但如果你给它甚至稍微损坏的编码,它确实会中断并且不会返回任何有用的输出,而且我有在某些情况下编写我自己的编码预验证器和预修复器。
        猜你喜欢
        • 2014-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-31
        • 2012-11-14
        • 2014-10-13
        相关资源
        最近更新 更多