Swift 3.0 ¿Datos a cadena?


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

Quiero deviceTokenencadenar

pero:

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

str es nil

rápido 3.0

¿Cómo puedo permitir dataa string?

¿Estás registrando notificaciones push en Xcode 8 / Swift 3.0? no funciona y la respuesta es hace unos meses, lo había probado:

ingrese la descripción de la imagen aquí

e imprimir:

ingrese la descripción de la imagen aquí


18
La próxima vez que le pida a alguien que pruebe su código, asegúrese de que no esté pegado como imagen ..
Desdenova

Si alguien viene a través de este al leer un archivo, compruebe que el archivo está codificado UTF8: file -I /path/to/file.txt. Si no convierte usando iconv:iconv -f UTF-16LE -t UTF-8 /path/to/file.txt > /path/to/utf8/file.txt
Pulkit Goyal

Respuestas:


155

Vine buscando la respuesta a la pregunta Swift 3 Data to String y nunca obtuve una buena respuesta. Después de tontear, se me ocurrió esto:

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!

4
Intenté responder. Ha funcionado en otras funciones, pero no funciona func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data). No sé por qué?
weijia.wang

el token del dispositivo no es una cadena utf8, es binario sin
formato

entonces, ¿qué hacer si es binario sin formato?
Kingalione

String.Encoding.utf8.rawValue - para cualquier persona en el último Swift
Stephen J

1
para decodificar el token usando didRegisterForRemoteNotificationsWithDeviceToken, vea esto: stackoverflow.com/questions/37956482/…
pw2

33

aquí está mi extensión de datos. agregue esto y puede llamar a data.ToString ()

import Foundation

extension Data
{
    func toString() -> String?
    {
        return String(data: self, encoding: .utf8)
    }
}

Esta es una codificación muy mala; nunca debe forzar la apertura de esto, ya que la codificación siempre puede fallar y esto bloquearía la aplicación. En su lugar, devuelva una cadena opcional como lo hace la API de Apple por muy buenas razones.
Walter White

@WalterWhite sí, en la aplicación devuelvo una cadena opcional. pero no actualice esta respuesta, gracias por el comentario
luhuiya

1
Si pasa la codificación como parámetro, tal vez por defecto sea .utf8 si lo desea, puede usar esto para más de un tipo de codificación.
Micah Montoya

18
let str = deviceToken.map { String(format: "%02hhx", $0) }.joined()

7

Encontré la manera de hacerlo. Necesita convertir Dataa NSData:

let characterSet = CharacterSet(charactersIn: "<>")
let nsdataStr = NSData.init(data: deviceToken)
let deviceStr = nsdataStr.description.trimmingCharacters(in: characterSet).replacingOccurrences(of: " ", with: "")
print(deviceStr)

2
¿Qué conjunto de caracteres es este?
Kingalione

Evitemos usar NSData con Swift.
Brennan

No utilice este método. Es inseguro.
Bogdan

2

Esto es mucho más fácil en Swift 3 y versiones posteriores usando reduce:

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()
    }
}

2

Versión Swift 4 de la respuesta de 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)


0

Para ampliar la respuesta de weijia.wang:

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

usarlo con deviceToken.hexString()


0

Si sus datos están codificados en base64.

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

0

Según el documento de Apple a continuación, el token del dispositivo no se puede decodificar. Entonces, creo que lo mejor que puedes hacer es dejarlo así.

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

Arquitectura de seguridad

Un token de dispositivo es una instancia de NSData opaca que contiene un identificador único asignado por Apple a una aplicación específica en un dispositivo específico. Solo los APN pueden decodificar y leer el contenido de un token de dispositivo. Cada instancia de aplicación recibe su token de dispositivo único cuando se registra con APN y, luego, debe reenviar el token a su proveedor, como se describe en Configuración del soporte de notificación remota. El proveedor debe incluir el token del dispositivo en cada solicitud de notificación de inserción que se dirija al dispositivo asociado; APN utiliza el token del dispositivo para garantizar que la notificación se envíe solo a la combinación única de aplicación y dispositivo para la que está destinada.


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()

    }

0

para 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")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.