Swift-特殊字符的编码和解码字符串

Ale*_*ama 4 string encoding utf-8 swift swift3

这是我的问题:我目前正在开发一个应用程序,其中包括即时聊天(使用FCM)。除非我尝试发送特殊字符(例如“é”或表情符号),否则一切都正常。收到的推送通知包含一个好的字符串,但是当讨论保存在服务器上然后重新加载时,我无法阅读它们并获得UTF8文本,例如“ê”的“ u00ea”。我对编码等并不了解很多,但是如果你们能帮助我,我将非常高兴!

这是我用来发送消息的代码:

    func sendMessage(_ completion: @escaping (_ response: String) -> ()) {

    DispatchQueue.global(qos: .userInitiated).async { () -> Void in
        let urlString = //Server adress
        let url = URL(string: urlString)

        var request = URLRequest(url: url!)
        let set = CharacterSet()
        request.httpMethod = "POST"
        let postString = "Message=" + /*String text to send*/
        request.httpBody = postString.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in

        })
        task.resume()
    }
}
Run Code Online (Sandbox Code Playgroud)

非常感谢 !

PS:我是问堆栈溢出的新手,所以请随时询问更多详细信息

按照Rob的要求进行编辑:我发送了“ testéè”消息。
另一部电话通过推送通知接收到“ testéè”。
当一部电话从服务器上加载服务器中的讨论时,其答案来自服务器。

    [{"content":"test u00e9 u00e8","sender":"103","timestamp":"1475491191"}]
Run Code Online (Sandbox Code Playgroud)

另外,我不是在编码服务器,而是正在制作一个可以很好地处理特殊字符的android应用程序的人。

编辑#2:我也尝试此代码

    var request = URLRequest(url: url!)
        let set = CharacterSet()
        request.httpMethod = "POST"
        let postString = "Message=" + self.message.addingPercentEncoding(withAllowedCharacters: set)!
        let bytesArray = UTF8Encoding.decode(postString)

        request.httpBody = Data(bytes: UnsafePointer<UInt8>(bytesArray), count: bytesArray.count)
Run Code Online (Sandbox Code Playgroud)

它没有任何区别。

非常感谢您的帮助。

Rob*_*Rob 5

您要使用addingPercentEncoding百分比对字符串进行转义。但是请不要尝试使用像这样的字符集urlQueryAllowed,因为那样会使某些关键字符(尤其是&+)不加转义地传递。

有关如何正确执行此操作的一个很好的示例,请参阅Alamofire的ParameterEncoding escape例程。这是作为扩展实现的演绎形式:

extension String {
    public func addingPercentEncodingForQueryParameter() -> String? {
        return addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
    }
}

extension CharacterSet {
    static let urlQueryValueAllowed: CharacterSet = {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="

        var allowed = CharacterSet.urlQueryAllowed
        allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode)

        return allowed
    }()
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以执行以下操作:

func send(message: String, _ completion: @escaping (_ response: String) -> ()) {
    let urlString = ...
    let url = URL(string: urlString)

    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    let postString = "Message=\(message.addingPercentEncodingForQueryParameter()!)"
    request.httpBody = postString.data(using: .utf8)

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        ...
    }
    task.resume()
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*ama 3

好吧,我想我已经有了,

正如所建议的,这部分是由于服务器的实现。由于其安全性,它过滤了某些字符,这就是它不起作用的原因。

我们已经纠正了这个问题,但是当讨论从 iOS 到 Android 或 Android 到 iOS 时,它仍然不起作用。

非常感谢你的帮助 !

这是我的最终代码:

var request = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "Message=" + (self.message.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed))!
request.httpBody = postString.data(using: String.Encoding.utf8, allowLossyConversion: true)
Run Code Online (Sandbox Code Playgroud)