swift 3.0 Dane do ciągu?

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

Chcę deviceTokensznurować

ale:

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

str jest nil

swift 3.0

Jak mogę pozwolić data, aby string?

Rejestracja w celu korzystania z powiadomień push w Xcode 8 / Swift 3.0? nie działa, a odpowiedź brzmi kilka miesięcy temu, próbowałem:

wprowadź opis obrazu tutaj

i wydrukuj:

wprowadź opis obrazu tutaj

weijia.wang
źródło
18
Następnym razem, gdy poprosisz kogoś o wypróbowanie Twojego kodu, upewnij się, że nie jest wklejony jako obraz ...
Desdenova
Jeśli ktoś napotka to podczas czytania pliku, sprawdź, czy plik jest UTF8 zakodowane: file -I /path/to/file.txt. Jeśli nie konwertujesz za pomocą iconv:iconv -f UTF-16LE -t UTF-8 /path/to/file.txt > /path/to/utf8/file.txt
Pulkit Goyal

Odpowiedzi:

155

Szukałem odpowiedzi na pytanie Swift 3 Data to String i nigdy nie uzyskałem dobrej odpowiedzi. Po kilku wygłupach wymyśliłem to:

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
źródło
4
Spróbowałem odpowiedzieć. Działa w innej func, ale nie działa. func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)Nie wiem dlaczego?
weijia.wang
token urządzenia nie jest ciągiem znaków utf8, jest to nieprzetworzony plik binarny
Hogdotmac,
więc co zrobić, jeśli jest to surowy plik binarny?
Kingalione,
String.Encoding.utf8.rawValue - dla każdego w najnowszym Swift
Stephen J
1
do dekodowania tokena za pomocą didRegisterForRemoteNotificationsWithDeviceToken patrz: stackoverflow.com/questions/37956482/ ...
pw2
33

oto moje rozszerzenie danych. dodaj to i możesz wywołać data.ToString ()

import Foundation

extension Data
{
    func toString() -> String?
    {
        return String(data: self, encoding: .utf8)
    }
}
luhuiya
źródło
To bardzo złe kodowanie - nigdy nie należy wymuszać tego, ponieważ kodowanie zawsze może się nie powieść, co spowodowałoby awarię aplikacji. Zamiast tego zwróć opcjonalny ciąg, tak jak robi to Apple API z bardzo dobrych powodów.
Walter White
@WalterWhite yeah w aplikacji zwracam opcjonalny ciąg. ale nie aktualizuj tej odpowiedzi, dzięki za komentarz
luhuiya
1
Jeśli podasz kodowanie jako parametr, może domyślną wartością jest .utf8, jeśli chcesz, możesz następnie użyć tego dla więcej niż jednego typu kodowania.
Micah Montoya
18
let str = deviceToken.map { String(format: "%02hhx", $0) }.joined()
Hogdotmac
źródło
7

Znalazłem sposób, aby to zrobić. Musisz przekonwertować Datana 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
źródło
2
który zestaw znaków to jest?
Kingalione,
Unikajmy używania NSData w Swift.
Brennan
Nie używaj tej metody. To niebezpieczne.
Bogdan
2

Jest to znacznie łatwiejsze w Swift 3 i późniejszych przy użyciu redukuj:

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()
    }
}
Gargulec
źródło
2

Wersja Swift 4 odpowiedzi 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
źródło
0

Aby rozszerzyć odpowiedź z weijia.wang:

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

używaj go z deviceToken.hexString()

Markus
źródło
0

Jeśli Twoje dane są zakodowane w formacie base64.

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

Zgodnie z dokumentem Apple poniżej, token urządzenia nie może zostać zdekodowany. Więc myślę, że najlepszą rzeczą do zrobienia jest po prostu zostawienie tego.

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

Architektura bezpieczeństwa

Token urządzenia to nieprzezroczysta instancja NSData, która zawiera unikalny identyfikator przypisany przez firmę Apple do określonej aplikacji na określonym urządzeniu. Tylko APN mogą dekodować i odczytywać zawartość tokenu urządzenia. Każde wystąpienie aplikacji otrzymuje swój unikatowy token urządzenia, gdy rejestruje się w APN, a następnie musi przekazać token do swojego dostawcy, zgodnie z opisem w sekcji Konfigurowanie obsługi zdalnego powiadamiania. Dostawca musi dołączyć token urządzenia do każdego żądania powiadomienia wypychanego, które jest przeznaczone dla skojarzonego urządzenia; Punkty APN używają tokena urządzenia, aby zapewnić, że powiadomienie zostanie dostarczone tylko do unikalnej kombinacji aplikacja-urządzenie, dla której jest przeznaczone.

Kyle Bing
źródło
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()

    }
user12739102
źródło
0

dla szybkiego 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
źródło