iOS private / publi c управление и хранение данных в Swift - PullRequest
0 голосов
/ 14 февраля 2020

Можно ли отображать в виде одного массива объекты, извлеченные из сети и той же модели, но извлеченные из основных данных. Цель состоит в том, чтобы иметь такие же данные, которые могут быть опубликованы c (затем извлечены из сети) или частными, а затем эти данные хранятся локально в модели coredata. Атрибуты / свойства будут одинаковыми для обоих.

Я планирую отобразить это как представление swiftUI (если это имеет значение)

После некоторого поиска у меня возникла идея создать одну структуру, основанную на ее Свойство конфиденциальности будет переведено в базовую модель класса данных или, если publi c напрямую подключено к сетевому уровню?

, например (некоторые псевдо-swift;))

struct Note {
   let note: String
   let isPrivate: Bool

   func save(self) {
       if self.isPrivate { save to CoreData }
       else { send save request with use of networking }
   }
}

class coreDataModel: NSManagedObject {
   var note: String
   let isPrivate = true
}

struct networkingModel {
   var note: String
   let isPrivate = false
}

class modelManager {
   func joinData() {
       let joinedModel: Note = coreDataModel + networkingModel 
    // and so on to display that model

   }
}

1 Ответ

1 голос
/ 15 февраля 2020

Я думаю, вы можете попробовать это, сначала загрузите пользовательский интерфейс с существующими локальными данными. В то же время, сделайте вызов вашего API в фоновой очереди. Как только результаты API станут доступны, отфильтруйте дубликаты и сохраните их локально. Затем последним шагом является уведомление пользователя о перезагрузке.

Этот псевдокод является битовым спецификацией UIKit c, однако к SwiftUI можно применять те же логики c. Вам не нужно закрытие, вы будете вычислять напрямую для вашего объекта издателя, и пользовательский интерфейс будет реагировать на основе любых новых излучений.

/// you can have one model for both api and core data 
struct Note: Hashable { let uuid = UUID.init() }

class ModelManager {
    private var _items: Array<Note> = []

    var onChanged: ((Array<Note>) -> Void)? = nil
    // you might also have an init, where you can have a timer running
    func start() {
        loadFromCoreData { [weak self] (items) in
            guard let `self` = self else { return }
            self._items.append(contentsOf: items)
            self.onChanged?(self._items)
            self.loadFromApi()
        }
    }

    private func loadFromCoreData(completion: @escaping (Array<Note>) -> Void) {
        // background queue
        // logic to load from coredata.
        let coreDataResults: Array<Note> = []
        completion(coreDataResults)
    }

    private func loadFromApi() {
        // background queue
        let apiResults: Array<Note> = []
        compute(contents: apiResults)
    }

    private func compute(contents: Array<Note>) {
        let combined = zip(_items, contents).flatMap{[$0.0, $0.1] }
        let newItems = Array(Set(combined)) // set doesn't allow duplicates 
        // save to db

        // insert to new to _items
        _items.append(contentsOf: newItems)
        // sort maybe to place new items on top
        self.onChanged?(self._items)

    }

}



// usage of this object 
    let manager = ModelManager()
    manager.start()
    manager.onChanged = { items in
        // [weak self] remember of retain cycles
        // make sure you are on main queue when reloading

    }
...