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í

weijia.wang
fuente
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!
4redwings
fuente
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)
    }
}
luhuiya
fuente
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()
Hogdotmac
fuente
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)
weijia.wang
fuente
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()
    }
}
Gárgola
fuente
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)
Abhishek Jain
fuente
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()

Markus
fuente
0

Si sus datos están codificados en base64.

if ( dataObj != nil ) {
    let encryptedDataText = dataObj!.base64EncodedString(options: NSData.Base64EncodingOptions())
    NSLog("Encrypted with pubkey: %@", encryptedDataText)
}
jeet.chanchawat
fuente
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.

Kyle Bing
fuente
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()

    }
usuario12739102
fuente
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")
Zgpeace
fuente