Swift: преобразование _PFEncodedString в String (экспорт атрибутов базовых данных с использованием JSONEncoder) - PullRequest
0 голосов
/ 17 ноября 2018

Я пишу Swift для iOS 11, и в некотором контексте (описанном в части 2) я получаю переменную типа String. Тем не менее, при проверке переменной в отладчике XCode тип отображается как _PFEncodedString (который я читал в другом месте, является внутренним подклассом String). По какой-то причине (описанной ниже, но не имеющей прямого отношения к первой части моего вопроса) я хочу преобразовать переменную _PFEncodedString в обычную строковую переменную. Я нашел единственный способ сделать это следующим образом:

var attributeName : String      
// ... attributeName is assigned a value and ends up being _PFEncodedString
let data = attributeName.data(using: String.Encoding.utf8)!
let plainName = String(data: data, encoding: String.Encoding.utf8)!     // this is type String not _PFEncodedString

Первая часть моего вопроса : Безопасно ли это преобразование или есть более простой или лучший способ сделать это?

Часть 2. Во второй части моего вопроса я сначала опишу контекст, в котором вышеизложенное становится проблемой. Я использую Core Data и хочу экспортировать имена атрибутов (и значения) в JSON. Используя отражение, я могу найти имена сущностей Core Data и найти имена атрибутов, которые должны быть экспортированы в JSON. Проблема в том, что когда я использую JSONEncoder с этими данными, сгенерированный JSON содержит китайские символы, а имена атрибутов модели Core Data - нет. Я обнаружил, что JSONEncoder производит частично китайский вывод, когда Strings в экспортируемом объекте имеет тип _PFEncodedString, но отлично работает при обработке «простых» типов String. Поэтому первая часть моих вопросов.

Вот код, иллюстрирующий проблему, сведенный к минимуму. QPTVideo является подклассом NSManagedObject с двумя атрибутами: «qaUUID» и «thumbnailData».

// First define a struct to be used with JSONEncoder
struct AttributeForJSON : Codable {
   var name : String
}

let entityDescription = QPTVideo.entity()
let attributes = entityDescription.attributesByName // this is an array of (key: String, value: NSAttributeDescription).
var allAttributes : [AttributeForJSON] = [] // this will be an array of all the attribute names for export to JSON.
for attribute in attributes {
    let attributeName = attribute.key // NOTE: debugger shows this as: attributeName   String class name = _PFEncodedString
    let aj = AttributeForJSON(name: attributeName)
    print(aj.name) // this works just fine, printing “qaUUID” or “thumbnailData”
    allAttributes.append(aj) // when exported, the attribute names look nothing like they should, containing Chinese characters.

    // now use the work-around from first part of my question:
    let data = attributeName.data(using: String.Encoding.utf8)!
    let plainName = String(data: data, encoding: String.Encoding.utf8)! // NOTE: debugger shows this as: plainName String "thumbnailData"
    let ajplain = AttributeForJSON(name: plainName)
    allAttributes.append(ajplain) // when exported, the attribute names are correct.
}
// the rest is just use of JSONEncoder to generate the JSON
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
    let data = try encoder.encode(allAttributes)
    try data.write(to: URL(fileURLWithPath: “/Users/someone/so.json"), options: Data.WritingOptions.atomic)
} catch {
    print(error.localizedDescription)
}

Экспортированный JSON выглядит следующим образом (где я ожидал, что оба первых значения name будут иметь значение «qaUUID», а следующие два - «thumbnailData»):

[
    {
        "name" : "慱啕䑉\u0000戨্"
    },
    {
        "name" : "qaUUID"
    },
    {
        "name" : "桴浵湢楡䑬瑡a\u0000戨্\u0001\u0000\u0000"
    },
    {
        "name" : "thumbnailData"
    }
]

Итак, мой здесь вопрос : Почему я получаю китайские иероглифы? Что я делаю неправильно в том, как я использую API-интерфейс отражения основных данных и / или JSONEncoder? Как мне сделать это, не прибегая к обходным путям из первой части моего вопроса?

...