【问题标题】:addingPercentEncoding works different in SwiftaddedPercentEncoding 在 Swift 中的工作方式不同
【发布时间】:2017-04-06 11:53:40
【问题描述】:

我有编码字符串的 obj-C 方法:

- (NSString *) encodeValue:(NSString*) unescaped{
    return [unescaped stringByAddingPercentEncodingWithAllowedCharacters:
             [NSCharacterSet URLHostAllowedCharacterSet]];
}

输入:testswiftapppod://

输出:testswiftapppod%3A%2F%2F

我在 Swift 中编写了相同的方法,但得到了不同的输出:testswiftapppod:%2F%2F

static func encodeValue(unescaped:String!) -> String{
   return unescaped.addingPercentEncoding(
        withAllowedCharacters: CharacterSet.urlHostAllowed)!
}

由于某种原因冒号未转换

如何解决这个问题?

我使用 Xcode 8.3

[编辑]

来自文档:

// 通过替换所有返回从接收器生成的新字符串 未使用百分比编码的 allowedCharacters 集中的字符 人物。 UTF-8 编码用于确定正确的百分比 编码的字符。不能对整个 URL 字符串进行百分比编码。这 方法旨在对 URL 组件或子组件进行百分比编码 字符串,而不是整个 URL 字符串。 allowedCharacters 中的任何字符 7 位 ASCII 范围之外的内容将被忽略。 - (nullable NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters NS_AVAILABLE(10_9, 7_0);

【问题讨论】:

  • 奇怪的是,Objective-C 代码的行为方式不同,但是 URL 的主机部分允许使用冒号 ,例如http://myhost.com:myport/path
  • URL 编码中允许使用冒号。只是一个问题,您是否尝试过类似“unes​​caped.stringByAddingPercentEncodingForFormData()”之类的方法?
  • 另外,“testswiftapppod://”看起来更像是一个 URL 方案,你为什么需要转义它呢?
  • @MartinR 因为我想把它作为 URL 的参数

标签: objective-c swift string encoding


【解决方案1】:

编辑:

这可能是未记录但预期的行为。详情请见is `addingPercentEncoding` broken in Xcode 9 beta 2?


这是一个错误。

我查看了不同的案例,似乎所有 Swift 代码都能正常工作。请注意,: 在 URL 主机中是允许的,因此不应对其进行编码,并且 该错误在 Obj-C 版本中

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet];    
NSLog(@"Colon is member: %@", [set characterIsMember:':'] ? @"true" : @"false"); // prints true

这是一个有趣的错误,因为如果您手动将":" 添加到字符集

NSMutableCharacterSet *set = [[NSCharacterSet URLHostAllowedCharacterSet] mutableCopy];
[set addCharactersInString:@":"];

一切都开始正常工作。

举报。

请注意,在对 URL 参数进行编码时,不应使用 urlHostAllowed。如果可能,请改用NSURLQuery 来构建您的URL。这两个预定义集实际上都不适合 URL 编码。您可以从urlQueryAllowed 开始,但您仍然需要从中删除一些字符。

请参阅例如this answer 以获得正确的解决方案或例如Alamofire library 中的实现。

【讨论】:

    【解决方案2】:

    可以通过以下方式生成所需的输出:

    func encodeValue(_ string: String) -> String? {
        guard let unescapedString = string.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: ":/").inverted) else { return nil }
    
        return unescapedString
    }
    
    let encodedString = encodeValue("testswiftapppod://") // testswiftapppod%3A%2F%2F
    

    【讨论】:

      猜你喜欢
      • 2017-09-08
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 2011-05-28
      • 2018-12-11
      • 2014-09-20
      • 1970-01-01
      • 2016-07-04
      相关资源
      最近更新 更多