从Objc到Swift的URLE编码3

时间:2017-08-16 06:05:25

标签: ios swift3 url-encoding

我们正在使用Objective C中的以下URL编码,现在我们正在迁移到swift。对于下面的ObjC到swift 3,它将是等效的编码。

- (NSString *) URLEncodedString {
    NSMutableString * output = [NSMutableString string];
    const unsigned char * source = (const unsigned char *)[self UTF8String];
    int sourceLen = strlen((const char *)source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = source[i];
        if (thisChar == ' '){
            [output appendString:@"+"];
        } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || 
                   (thisChar >= 'a' && thisChar <= 'z') ||
                   (thisChar >= 'A' && thisChar <= 'Z') ||
                   (thisChar >= '0' && thisChar <= '9')) {
            [output appendFormat:@"%c", thisChar];
        } else {
            [output appendFormat:@"%%%02X", thisChar];
        }
    }
    return output;
}

4 个答案:

答案 0 :(得分:2)

此代码应生成与Objective-C代码完全相同的结果。 (应该在Swift 3和4中按预期编译和工作。)

extension String {
    var urlEncoded: String {
        var output = ""
        for thisChar in self.utf8 {
            switch thisChar {
            case UInt8(ascii: " "):
                output.append("+")
            case UInt8(ascii: "."), UInt8(ascii: "-"), UInt8(ascii: "_"), UInt8(ascii: "~"),
                 UInt8(ascii: "a")...UInt8(ascii: "z"),
                 UInt8(ascii: "A")...UInt8(ascii: "Z"),
                 UInt8(ascii: "0")...UInt8(ascii: "9"):
                output.append(Character(UnicodeScalar(UInt32(thisChar))!))
            default:
                output = output.appendingFormat("%%%02X", thisChar)
            }
        }
        return output
    }
}
print("https://www.google.es".urlEncoded) //->https%3A%2F%2Fwww.google.es

有些观点:

  • 您可以使用for thisChar in self.utf8

  • 对每个UTF-8字节进行迭代
  • 要将字符串文字(实际上是UnicodeScalar Literal)转换为UInt8,您可以使用UInt8(ascii:)

  • 您最好考虑将addingPercentEncoding(withAllowedCharacters:)与正确的CharacterSet和前/后处理

  • 一起使用

答案 1 :(得分:1)

你可以这样做 -

extension String{

    func urlEncodedString() -> String {
        var output = String()
        let source: [UInt8] = Array(self.utf8)
        let sourceLen: Int = source.count
        for i in 0..<sourceLen {
            let thisChar = source[i]
            if thisChar == UInt8(ascii: " ") {
                output += "+"
            }
            else if thisChar == UInt8(ascii: ".") || thisChar == UInt8(ascii: "-") || thisChar == UInt8(ascii: "_") || thisChar == UInt8(ascii: "~") || (thisChar >= UInt8(ascii: "a") && thisChar <= UInt8(ascii: "z")) || (thisChar >= UInt8(ascii: "A") && thisChar <= UInt8(ascii: "Z")) || (thisChar >= UInt8(ascii: "0") && thisChar <= UInt8(ascii: "9")) {
                output += "\(Character(UnicodeScalar(UInt32(thisChar))!))"
            }
            else {
                output += String(format: "%%%02X", thisChar)
            }
        }
        return output
    }
}

答案 2 :(得分:0)

试试这个swift 3兼容代码。我在操场上测试过它并且工作正常。

extension String {
    func urlEncodedString() -> String {
        var output = ""
        for thisChar in self.utf8 {
            if thisChar == UInt8(ascii: " ") {
                output += "+"
            }
            else if thisChar == UInt8(ascii: ".") ||
                thisChar == UInt8(ascii: "-") ||
                thisChar == UInt8(ascii: "_") ||
                thisChar == UInt8(ascii: "~") ||
                (thisChar >= UInt8(ascii: "a") && thisChar <= UInt8(ascii: "z")) ||
                (thisChar >= UInt8(ascii: "A") && thisChar <= UInt8(ascii: "Z")) ||
                (thisChar >= UInt8(ascii: "0") && thisChar <= UInt8(ascii: "9")) {
                output += "\(Character(UnicodeScalar(UInt32(thisChar))!))"
            }
            else {
                output += String(format: "%%%02X", thisChar)
            }
        }
        return output
    }
}

使用示例:

let url = "https://www.google.es".urlEncodedString()
print(url)

答案 3 :(得分:0)

只需替换下面的代码(Swift 3.1.1):

func urlEncodedString() -> String {
    var output = String()
    let source: [UInt8] = UInt8(utf8)
    let sourceLen: Int = strlen(CChar(source))
    for i in 0..<sourceLen {
        let thisChar: UInt8 = source[i]
        if thisChar == " " {
            output += "+"
        }
        else if thisChar == "." || thisChar == "-" || thisChar == "_" || thisChar == "~" || (thisChar >= "a" && thisChar <= "z") || (thisChar >= "A" && thisChar <= "Z") || (thisChar >= "0" && thisChar <= "9") {
            output += "\(thisChar)"
        }
        else {
            output += String(format: "%%%02X", thisChar)
        }
    }
    return output
}