web-dev-qa-db-ja.com

NSJSONSerializationがURLに余分なエスケープを追加しないようにする方法

NSJSONSerializationがURL文字列に余分なバックスラッシュを追加しないようにするにはどうすればよいですか?

NSDictionary *info = @{@"myURL":@"http://www.example.com/test"};
NSData data = [NSJSONSerialization dataWithJSONObject:info options:0 error:NULL];
NSString *string = [[NSString alloc] initWithData:policyData encoding:NSUTF8StringEncoding];
NSLog(@"%@", string);//{"myURL":"http:\/\/www.example.com\/test"}

バックスラッシュを取り除いてその文字列を使用できますが、可能であればそのステップをスキップしたいと思います...

27
joels

ええ、これは非常に苛立たしいものです。これには「迅速な」修正がないようです(つまり、NSJSONSerializationの場合)。

ソース:
http://www.blogosfera.co.uk/2013/04/nsjsonserialization-serialization-of-a-string-taining-forward-slashes-and-html-is-escaped-incorrectly /
または
スラッシュを含む文字列のNSJSONSerializationシリアライゼーション/およびHTMLが正しくエスケープされない


(ここで暗闇で撮影するので我慢してください)
独自のJSONを作成する場合は、文字列からNSDataオブジェクトを作成し、サーバーに送信します。
NSJSONSerializationを経由する必要はありません。

何かのようなもの:

NSString *strPolicy = [info description];
NSData *policyData = [strPolicy dataUsingEncoding:NSUTF8StringEncoding];

それほど簡単ではないことは知っていますが...ええと...とにかく

5
staticVoidMan

これは私のために働いた

NSDictionary *policy = ....;
NSData *policyData = [NSJSONSerialization dataWithJSONObject:policy options:kNilOptions error:&error];
if(!policyData && error){
    NSLog(@"Error creating JSON: %@", [error localizedDescription]);
    return;
}

//NSJSONSerialization converts a URL string from http://... to http:\/\/... remove the extra escapes
policyStr = [[NSString alloc] initWithData:policyData encoding:NSUTF8StringEncoding];
policyStr = [policyStr stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"];
policyData = [policyStr dataUsingEncoding:NSUTF8StringEncoding];
19
joels

ターゲットがiOS 13.0以上の場合は、オプションに.withoutEscapingSlashesを追加します。

例:

let data = try JSONSerialization.data(withJSONObject: someJSONObject, options: [.prettyPrinted, .withoutEscapingSlashes])

print(String(data: data, encoding: String.Encoding.utf8) ?? "")
1
Vmark

私は長年この問題を追跡してきましたが、まだ修正されていません。 Appleはレガシーな理由でそれを修正することは決してありません(それは何かを壊します)。

Swift 4.2の解:

let fixedString = string.replacingOccurrences(of: "\\/", with: "/")

すべてを置き換えます\//、そうしても安全です。

1
samwize

私はこの問題を抱えていて、代わりに現在利用可能なJSONEncoderを使用することで解決しました。コードで示す:

struct Foozy: Codable {
    let issueString = "Hi \\ lol lol"
}

let foozy = Foozy()

// crashy line
//let json = try JSONSerialization.data(withJSONObject: foozy, options: [])

// working line
let json = try JSONEncoder().encode(foozy)
0
Codezy