Swift 3.0 Data to String?


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

Je veux deviceTokenenchaîner

mais:

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

str est nil

Swift 3.0

comment puis - je laisser dataà string?

Vous vous inscrivez aux notifications push dans Xcode 8 / Swift 3.0? ne fonctionne pas et la réponse est il y a quelques mois, je l'avais essayé:

entrez la description de l'image ici

et imprimez:

entrez la description de l'image ici


18
La prochaine fois que vous demanderez à quelqu'un d'essayer votre code, assurez-vous qu'il n'est pas collé comme image ..
Desdenova

Si quelqu'un vient à travers ce lors de la lecture d' un fichier, vérifiez que le fichier est encodé en UTF8: file -I /path/to/file.txt. Sinon convertir en utilisant iconv:iconv -f UTF-16LE -t UTF-8 /path/to/file.txt > /path/to/utf8/file.txt
Pulkit Goyal

Réponses:


155

Je suis venu chercher la réponse à la question Swift 3 Data to String et je n'ai jamais obtenu de bonne réponse. Après quelques bêtises, je suis venu avec ceci:

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
J'avais essayé de vous répondre. Cela a fonctionné dans d'autres fonctions, mais pas dans func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data).Je ne sais pas pourquoi?
weijia.wang

le jeton de périphérique n'est pas une chaîne utf8, c'est un binaire brut
Hogdotmac

alors que faire si c'est binaire brut?
Kingalione

String.Encoding.utf8.rawValue - pour tout le monde dans le dernier Swift
Stephen J

1
pour décoder le jeton à l'aide de didRegisterForRemoteNotificationsWithDeviceToken voir ceci: stackoverflow.com/questions/37956482/…
pw2

33

voici mon extension de données. ajoutez ceci et vous pouvez appeler data.ToString ()

import Foundation

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

C'est un très mauvais codage - vous ne devriez jamais forcer le déballage car l'encodage peut toujours échouer et cela planterait l'application. Au lieu de cela, retournez une chaîne facultative comme le fait l'API Apple pour de très bonnes raisons.
Walter White

@WalterWhite ouais dans l'application, je renvoie une chaîne facultative. mais ne mettez pas à jour cette réponse, merci pour le commentaire
luhuiya

1
Si vous passez l'encodage en tant que paramètre, peut-être par défaut il est .utf8 si vous le souhaitez, vous pouvez alors l'utiliser pour plus d'un type d'encodage.
Micah Montoya

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

7

J'ai trouvé le moyen de le faire. Vous devez convertir Dataen NSData:

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

2
quel characterSet s'agit-il?
Kingalione

Evitons d'utiliser NSData avec Swift.
Brennan

N'utilisez pas cette méthode. C'est dangereux.
Bogdan

2

C'est beaucoup plus facile dans Swift 3 et versions ultérieures en utilisant réduire:

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

Version Swift 4 de la réponse 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

Pour prolonger la réponse de weijia.wang:

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

utilisez-le avec deviceToken.hexString()


0

Si vos données sont encodées en base64.

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

0

Selon la documentation Apple ci-dessous, le jeton d'appareil ne peut pas être décodé. Donc, je pense que la meilleure chose à faire est de laisser les choses en place.

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

Architecture de sécurité

Un jeton d'appareil est une instance NSData opaque qui contient un identifiant unique attribué par Apple à une application spécifique sur un appareil spécifique. Seuls les APN peuvent décoder et lire le contenu d'un jeton d'appareil. Chaque instance d'application reçoit son jeton d'appareil unique lorsqu'elle s'enregistre auprès des APN, puis doit transmettre le jeton à son fournisseur, comme décrit dans Configuration de la prise en charge des notifications à distance. Le fournisseur doit inclure le jeton d'appareil dans chaque demande de notification push qui cible l'appareil associé; Les APN utilisent le jeton d'appareil pour garantir que la notification n'est envoyée qu'à la combinaison unique d'application-appareil à laquelle elle est destinée.


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

pour 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")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.