Отдельная загрузка данных в две сущности Core Data со связями с помощью Swift - PullRequest
0 голосов
/ 06 июня 2019

Я загружаю данные в две сущности Core Data при запуске приложения.Нет проблем с загрузкой обычных атрибутов, но я не могу понять, как установить отношения в Swift 5.

Из двух соответствующих сущностей CellData имеет единственное отношение «один к одному» с селектором (каждая строка селектора)может иметь много строк CellData).

enter image description here

Мой класс одной модели загружает данные для двух объектов ...

class LoadData
{
init ()
{

используя цикл for, который сначала определяет данные объекта Selector для средства выбора ...

    for count in 0...3
    {
        var text = "Value not found"
...

        switch count
        {
        case 0:
            text = "Masculine"
        case 1:
            text = "Neutral"
        case 2:
            text = "Feminine"
        case 3:
            text = "Plural"
        default:
            text = "Value unassigned"
        }

..., а затем вызывает метод (ниже) для добавления данных к объекту "средство выбора".

        loadSelector(text: text, sortOrder: sortOrder, ...)
    }

... Внутри того же init есть цикл for для определения CellData

    for count in 0...51
    {
        var text = "Cell text not found"
        var sortOrder: Int32 = 0
        ...

        sortOrder = Int32(count)
        ...
        switch count
        {
        case 0:
            text = "Blank"
            color1 = subject
            colorRangeLoc1 = 0
            colorRangeLen1 = Int32(text.count)
        ...   
        case 8:
            text = "Der Mann"
            color1 = article
            ...

        case 9:
            text = "Die Frau"
            color1 = article
            color2 = subject
            colorRangeLoc1 = 0
            colorRangeLoc2 = 4
            colorRangeLen1 = 3
            colorRangeLen2 = 4
            underlineRangeLoc1 = 1
            underlineRangeLen1 = 2
        ...

..., который также передает данные из каждого цикла в метод загрузки.

           loadCellData(text: text, ...)
    }
}

func loadSelector(text: String, sortOrder: Int32, color1: String?, color2: String?, color3: String?, colorRangeLoc1: Int32?, colorRangeLen1: Int32?, colorRangeLoc2: Int32?, colorRangeLen2: Int32?, colorRangeLoc3: Int32?, colorRangeLen3: Int32?)
{
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let entry: Selector = NSEntityDescription.insertNewObject(forEntityName: "Selector", into: context) as! Selector

    entry.text = text
    entry.sortOrder = sortOrder

    do { try context.save() }
    catch let error as NSError
    { print("Could not save. \(error), \(error.userInfo)") }
}

Это, вероятно, не лучший подход, но я работаю над загрузкой данных через plist.

Что я не могу понять, так это как создать связь в CellData,Случай 8, например, нуждается в связи с данными Selector, где .text = 'Masculine', а CellData, случай 9, должен быть связан с записью Selector .text = 'Feminine'.

Должен ли яповторно выбрать записи селектора - до или внутри - второй цикл for, а затем назначить в каждом случае?Я пробовал это, но безуспешно - если возможно, покажите код, и где код должен быть.Большая часть информации, кажется, находится в Obj-c.Swift 5 был бы потрясающим!

Ответы [ 2 ]

0 голосов
/ 24 июля 2019

Единственный способ определить отношение к существующей записи - это выборка записи по отдельности из CoreData.

Взято из проекта Hacking Swift 38, где 'commit' - это экземпляр CoreData Entity, имеющий отношение к объекту Author:

var commitAuthor: Author!       // instantiate an Author object

let authorRequest = Author.createFetchRequest()     // create a fetch request...
authorRequest.predicate = NSPredicate(format: "name == %@", json["commit"]["committer"]["name"].stringValue)       // predicating the author's name...

let authors = container.viewContext.fetch(authorRequest)

commitAuthor = authors[0] }   // pull the author out of the array
// and assign the author to the commit.author relationship
commit.author = commitAuthor

Хотя вопрос был больше о назначении отношения, следующее(основываясь на ответе Иоахима) - это лучший способ загрузить данные так, чтобы они были видны и передавались в виде plist или JSON-загрузки.По сути, для обхода массива словарей:

let genders: NSArray = [["text": "Masculine", "sortOrder" : Int32(0)], ["text": "Neutral", "sortOrder" : Int32(1)], ["text": "Feminine", "sortOrder" : Int32(2)], ["text": "Plural", "sortOrder" : Int32(3)]]

    // loading a gender entity in context with a dictionary of items from array
    for eachDicItem in genders
    {
        let gender = NSEntityDescription.entity(forEntityName: "Gender",
                                                in: context)!
        let genderInContext = Gender(entity: gender,
                            insertInto: context)

        let genderDictionary = eachDicItem as! [String : Any]

        genderInContext.text = genderDictionary["text"] as? String
        genderInContext.sortOrder = genderDictionary["sortOrder"] as? Int32 ?? 99
    }

    // save the context
    do { try context.save() }
    catch let error as NSError
    { print("Could not save. \(error), \(error.userInfo)") }
0 голосов
/ 06 июня 2019

Обращайтесь с ними так же, как с обычными объектами, Core Data обрабатывает большинство магических вещей для вас.

Я бы создал метод, который создает все селекторы и возвращает их в виде словаря с именем в качестве ключа (или любых других коллекций, которые вам подходят)

func createSelectors(text: String) -> [String: Select] {
    var result = [String: Selector]() 
    //loop creating Selector 
    result[text: entity]
    return result
}

вы можете даже пропустить свой метод loadSelector и выполнить фактическую реализацию как

let entity = Selector(context: context)

в методе createSelectors и try context.save() можно сделать в конце, но не для каждого объекта. Обратите внимание, что добавление создания объекта, подобного этому, помещает его в NSManagedObjectContext, и на данный момент этого достаточно, чтобы иметь возможность использовать объекты, сохранение фактически можно выполнить один раз в самом конце вашей загрузки.

Теперь при создании CellData вы можете сделать что-то вроде

let selectors = createSelectors()
...
let cellData = CellData(context: context)
if let sel = selectors {
    cellData.selectorToData = sel
}
....

и после создания всех сущностей CellData вы можете позвонить try context.save()

context во всем приведенном выше коде это управляемый объект, который вы получаете таким образом, `let context = appDelegate.persistentContainer.viewContext, но вы, вероятно, уже получили это.

«Селектор» - это такое специальное имя в Swift, поскольку это встроенная структура, я бы серьезно подумал об изменении имени этой сущности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...