Swift 3.0 данные в строку?

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

Я хочу deviceTokenнатянуть

но:

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

str является nil

быстрый 3.0

как я могу позволить , dataчтобы string?

Регистрация для push-уведомлений в Xcode 8 / Swift 3.0? не работает, и ответ - несколько месяцев назад, я пробовал:

введите описание изображения здесь

и распечатайте:

введите описание изображения здесь

weijia.wang
источник
18
В следующий раз, когда вы попросите кого-нибудь опробовать ваш код, убедитесь, что он не вставлен как изображение ..
Десденова
Если кто - то сталкивался с этим при чтении файла, убедитесь , что файл UTF8 кодируется: file -I /path/to/file.txt. Если не конвертировать с помощью iconv:iconv -f UTF-16LE -t UTF-8 /path/to/file.txt > /path/to/utf8/file.txt
Pulkit Goyal

Ответы:

155

Я искал ответ на вопрос Swift 3 Data to String и так и не получил хорошего ответа. После некоторого дурака я придумал следующее:

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
источник
4
Я пытался тебе ответить. Он работает в других функциях, но не работает в. func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)Не знаю почему?
weijia.wang
токен устройства не является строкой utf8, это необработанный двоичный файл
Hogdotmac
так что делать, если это необработанный двоичный файл?
Kingalione
String.Encoding.utf8.rawValue - для всех, кто пользуется последней версией Swift
Стивен Дж.
1
для декодирования токена с помощью didRegisterForRemoteNotificationsWithDeviceToken см. это: stackoverflow.com/questions/37956482/…
pw2 05
33

вот мое расширение данных. добавьте это, и вы можете вызвать data.ToString ()

import Foundation

extension Data
{
    func toString() -> String?
    {
        return String(data: self, encoding: .utf8)
    }
}
Лухуйя
источник
Это очень плохая кодировка - вам никогда не следует принудительно разворачивать это, поскольку кодирование всегда может завершиться ошибкой, и это приведет к сбою приложения. Вместо этого верните необязательную строку, как это делает Apple API, по очень веским причинам.
Уолтер Уайт
@WalterWhite да, в приложении я возвращаю необязательную строку. но не обновляйте этот ответ, спасибо за комментарий
luhuiya
1
Если вы передаете кодировку в качестве параметра, возможно, по умолчанию это .utf8, если хотите, вы можете затем использовать это для более чем одного типа кодирования.
Мика Монтойя
18
let str = deviceToken.map { String(format: "%02hhx", $0) }.joined()
Hogdotmac
источник
7

Я нашел способ это сделать. Вам нужно преобразовать Dataв 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
источник
2
Какой набор символов это?
Kingalione
Давайте избегать использования NSData со Swift.
Бреннан
Не используйте этот метод. Это небезопасно.
Богдан
2

Это намного проще в Swift 3 и более поздних версиях с помощью 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

Swift 4 версия ответа 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

Чтобы продолжить ответ weijia.wang:

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

использовать это с deviceToken.hexString()

Маркус
источник
0

Если ваши данные закодированы в base64.

if ( dataObj != nil ) {
    let encryptedDataText = dataObj!.base64EncodedString(options: NSData.Base64EncodingOptions())
    NSLog("Encrypted with pubkey: %@", encryptedDataText)
}
jeet.chanchawat
источник
0

Согласно документу Apple ниже, токен устройства не может быть декодирован. Итак, я думаю, что лучше всего просто оставить все как есть.

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

Архитектура безопасности

Токен устройства - это непрозрачный экземпляр NSData, который содержит уникальный идентификатор, присвоенный Apple определенному приложению на определенном устройстве. Только APN могут декодировать и читать содержимое токена устройства. Каждый экземпляр приложения получает свой уникальный токен устройства при регистрации в APN, а затем должен переслать токен своему провайдеру, как описано в разделе Настройка поддержки удаленных уведомлений. Провайдер должен включать токен устройства в каждый запрос push-уведомления, нацеленный на связанное устройство; APNs использует токен устройства, чтобы уведомление было доставлено только той уникальной комбинации приложение-устройство, для которой оно предназначено.

Кайл Бинг
источник
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
источник
0

для 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
источник