Задать вопрос
  • Как в swift преобразовать кодироку строки?

    doublench21
    @doublench21 Куратор тега Swift
    let str = "Привет Как дела"  // Внутренняя кодировка Свифта utf-32
    
    let cp1251Data = str.data(using: .windowsCP1251) 
    let utf8Data = str.data(using: .utf8)
    
    cp1251Data.count // 15
    utf8Data.count // 28
    
    // ***********************************
    
    let session = URLSession.shared
    var URL = URL(string: "https://greatcomments.server/add")!
    var request = URLRequest(url: URL)
    request.httpMethod = "POST"
        
     // Headers
    request.addValue("application/x-www-form-urlencoded; charset=windows-1251", forHTTPHeaderField: "Content-Type")
    
    // Form URL-Encoded Body 
    let bodyParameters = [
         "comment": "Проверка",
    ]
    let bodyString = bodyParameters.queryParameters
    request.httpBody = bodyString.data(using: . win1251, allowLossyConversion: true)
    
    let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
          if (error == nil) {
            // Success
            let statusCode = (response as! HTTPURLResponse).statusCode
            print("URL Session Task Succeeded: HTTP \(statusCode)")
          }
          else {
            // Failure
            print("URL Session Task Failed: %@", error!.localizedDescription);
          }
        })
    task.resume()
    session.finishTasksAndInvalidate()
    
    
    // ***********************************
    
    protocol URLQueryParameterStringConvertible {
      var queryParameters: String {get}
    }
    
    extension Dictionary : URLQueryParameterStringConvertible {
      var queryParameters: String {
        var parts: [String] = []
        for (key, value) in self {
          let part = String(format: "%@=%@",
                            String(describing: key).win1251Encoded,
                            String(describing: value).win1251Encoded)
          parts.append(part as String)
        }
        return parts.joined(separator: "&")
      }
      
    }
    
    extension URL {
      func appendingQueryParameters(_ parametersDictionary : [String: String]) -> URL {
        let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters)
        return URL(string: URLString)!
      }
    }
    
    // Раньше Swift(Foundation) позволял любую строку закодировать в url-encode в любой кодировке. 
    // Сейчас же де факто это можно лишь сделать в utf-8. 
    // Видимо Apple аргументирует это тем,  что utf-8 - это стандарт в вебе. 
    
    // Да всех остальных случаев нужно писать такую функцию самому. 
    // Ниже кодировка в url-encode в windows-1251
    
    extension CharacterSet {
      static let rfc3986Unreserved = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~=&+")
    }
    
    extension String.Encoding {
      static let win1251 = String.Encoding(rawValue: CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringEncodings.windowsCyrillic.rawValue)))
    }
    
    extension String {
      func addingPercentEncoding(withAllowedCharacters characterSet: CharacterSet, using encoding: String.Encoding) -> String {
        let stringData = self.data(using: encoding, allowLossyConversion: true) ?? Data()
        let percentEscaped = stringData.map {byte->String in
          if characterSet.contains(UnicodeScalar(byte)) {
            return String(UnicodeScalar(byte))
          } else if byte == UInt8(ascii: " ") {
            return "+"
          } else {
            return String(format: "%%%02X", byte)
          }
          }.joined()
        return percentEscaped
      }
      
      var win1251Encoded: String {
        return self.addingPercentEncoding(withAllowedCharacters: .rfc3986Unreserved,  using: . win1251)
      }
    }
    Ответ написан