Swift 3.0 Data to String?

89
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {}

Eu quero deviceTokenamarrar

mas:

let str = String.init(data: deviceToken, encoding: .utf8)

str é nil

Swift 3.0

como posso deixar dataparastring ?

Registrando-se para notificações push no Xcode 8 / Swift 3.0? não está funcionando e a resposta é alguns meses atrás, eu tentei:

insira a descrição da imagem aqui

e imprimir:

insira a descrição da imagem aqui

weijia.wang
fonte
18
Da próxima vez que você pedir a alguém para testar seu código, certifique-se de que ele não seja colado como imagem.
Desdenova
Se alguém vem através desta ao ler um arquivo, verifique se o arquivo é UTF8 codificado: file -I /path/to/file.txt. Se não converter usando iconv:iconv -f UTF-16LE -t UTF-8 /path/to/file.txt > /path/to/utf8/file.txt
Pulkit Goyal de

Respostas:

157

Eu vim procurando a resposta para a pergunta Swift 3 Data to String e nunca obtive uma boa resposta. Depois de algumas brincadeiras, pensei o seguinte:

var testString = "This is a test string"
var somedata = testString.data(using: String.Encoding.utf8)
var backToString = String(data: somedata!, encoding: String.Encoding.utf8) as String!
4redwings
fonte
4
Eu tentei responder. Funcionou em outra função, mas não funciona func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data). Não sei por quê?
weijia.wang
o token do dispositivo não é uma string utf8, é binário bruto
Hogdotmac
então o que fazer se for binário bruto?
Kingalione
String.Encoding.utf8.rawValue - para qualquer um no Swift mais recente
Stephen J
1
para decodificar o token usando didRegisterForRemoteNotificationsWithDeviceToken veja isto: stackoverflow.com/questions/37956482/…
pw2
34

aqui está minha extensão de dados. adicione isso e você pode chamar data.ToString ()

import Foundation

extension Data
{
    func toString() -> String?
    {
        return String(data: self, encoding: .utf8)
    }
}
luhuiya
fonte
Esta é uma codificação muito ruim - você nunca deve forçar o desempacotamento, pois a codificação sempre pode falhar e isso travaria o aplicativo. Em vez disso, retorne uma string opcional como a API da Apple faz por boas razões.
Walter White
@WalterWhite sim, no aplicativo eu retorno uma string opcional. mas não atualize esta resposta, obrigado pelo comentário
luhuiya
1
Se você passar a codificação como um parâmetro, talvez o padrão para .utf8 se quiser, você pode usar isso para mais de um único tipo de codificação.
Micah Montoya
18
let str = deviceToken.map { String(format: "%02hhx", $0) }.joined()
Hogdotmac
fonte
7

Eu encontrei a maneira de fazer isso. Você precisa converter Datapara NSData:

let characterSet = CharacterSet(charactersIn: "<>")
let nsdataStr = NSData.init(data: deviceToken)
let deviceStr = nsdataStr.description.trimmingCharacters(in: characterSet).replacingOccurrences(of: " ", with: "")
print(deviceStr)
weijia.wang
fonte
2
qual characterSet é esse?
Kingalione
Vamos evitar o uso de NSData com Swift.
Brennan
Não use este método. Não é seguro.
Bogdan,
2

Isso é muito mais fácil no Swift 3 e posterior usando reduzir:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.reduce("") { $0 + String(format: "%02x", $1) }

    DispatchQueue.global(qos: .background).async { 
        let url = URL(string: "https://example.com/myApp/apns.php")!

        var request = URLRequest(url: url)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        request.httpBody = try! JSONSerialization.data(withJSONObject: [
            "token" : token, 
            "ios" : UIDevice.current.systemVersion,
            "languages" : Locale.preferredLanguages.joined(separator: ", ")
            ])

        URLSession.shared.dataTask(with: request).resume()
    }
}
Gárgula
fonte
2

Versão do Swift 4 da resposta do 4redwings:

let testString = "This is a test string"
let somedata = testString.data(using: String.Encoding.utf8)
let backToString = String(data: somedata!, encoding: String.Encoding.utf8)
Abhishek Jain
fonte
0

Para estender a resposta de weijia.wang:

extension Data {
    func hexString() -> String {
        let nsdataStr = NSData.init(data: self)
        return nsdataStr.description.trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
    }
}

usar com deviceToken.hexString()

Markus
fonte
0

Se seus dados forem codificados em base64.

if ( dataObj != nil ) {
    let encryptedDataText = dataObj!.base64EncodedString(options: NSData.Base64EncodingOptions())
    NSLog("Encrypted with pubkey: %@", encryptedDataText)
}
jeet.chanchawat
fonte
0

De acordo com o documento da Apple abaixo, o token do dispositivo não pode ser decodificado. Então, eu acho que a melhor coisa a fazer é deixar como está.

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html

Arquitetura de Segurança

Um token de dispositivo é uma instância NSData opaca que contém um identificador exclusivo atribuído pela Apple a um aplicativo específico em um dispositivo específico. Apenas APNs podem decodificar e ler o conteúdo de um token de dispositivo. Cada instância do aplicativo recebe seu token de dispositivo exclusivo quando se registra com APNs e deve então encaminhar o token para seu provedor, conforme descrito em Configurando o suporte de notificação remota. O provedor deve incluir o token do dispositivo em cada solicitação de notificação push que visa o dispositivo associado; O APNs usa o token do dispositivo para garantir que a notificação seja entregue apenas à combinação exclusiva de aplicativo-dispositivo para a qual se destina.

Kyle Bing
fonte
0
let urlString = baseURL + currency

    if let url = URL(string: urlString){
        let session = URLSession(configuration: .default)        
        let task = session.dataTask(with: url){ (data, reponse, error) in
            if error != nil{
                print(error)
                return
            }


            let dataString = String(data: data!, encoding: .utf8)
            print(dataString)

        }

        task.resume()

    }
usuário12739102
fonte
0

para o swift 5

let testString = "This is a test string"
let somedata = testString.data(using: String.Encoding.utf8)
let backToString = String(data: somedata!, encoding: String.Encoding.utf8) as String?
print("testString > \(testString)")
//testString > This is a test string
print("somedata > \(String(describing: somedata))")
//somedata > Optional(21 bytes)
print("backToString > \(String(describing: backToString))")
//backToString > Optional("This is a test string")
Zgpeace
fonte