Приложение зависает при попытке установить данные в UserDefaults, без ошибок - PullRequest
0 голосов
/ 29 марта 2019

Я хочу сохранить массив пользовательских объектов в UserDefaults. Большую часть времени это работает довольно хорошо, но иногда выполнение останавливается на шаге 2 и продолжается через много секунд, где я сохраняю объект данных в UserDefaults. Это не происходит регулярно, но кажется, что проблема возникает чаще, когда массив содержит много элементов.

Не выдается никакой ошибки, похоже, что кодировка или сохранение Data каким-то образом повреждены, но я не понимаю, в чем может быть проблема.

Мой класс объектов:

struct AWFavourite: Codable {

    enum MediaType: String, Codable {
        case album
        case artist
        case playlist
    }

    let identifier: String
    let title: String
    let mediaType: MediaType
    let image: UIImage?
    let source: AWMediaSource

    enum CodingKeys: String, CodingKey {
        case identifier
        case title
        case mediaType
        case image
        case source
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let imageData = try container.decode(Data.self, forKey: .image)
        image = NSKeyedUnarchiver.unarchiveObject(with: imageData) as? UIImage 

        title = try container.decode(String.self, forKey: .title)
        identifier = try container.decode(String.self, forKey: .identifier)
        mediaType = try container.decode(MediaType.self, forKey: .mediaType)
        source = try container.decode(AWMediaSource.self, forKey: .source)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(title, forKey: .title)
        try container.encode(identifier, forKey: .identifier)
        try container.encode(mediaType, forKey: .mediaType)
        print("Probuje obrazek")
        let imageData = NSKeyedArchiver.archivedData(withRootObject: image as Any)
        print("zrobilem obrazek")
        try container.encode(imageData, forKey: .image)
        print("Przeszedlem obrazek")
        try container.encode(source, forKey: .source)
    }

}

И метод, который сохраняет массив избранных

static private let key = "favouritesKey"

var favourites: [AWFavourite]!

private func saveFavourites(_ completion: (() -> Void)?) {
        DispatchQueue.global(qos: .background).async {
            do {
                print("Step 1")
                let data = try JSONEncoder().encode(self.favourites)
                print("Step 2") // Most often the freezing occurs here and Step 3 gets printed after few seconds
                UserDefaults.standard.set(data, forKey: AWFavouriteManager.key)
                print("Step 3") // Step 3 gets printed but Step 4 is printed after few seconds, sometimes even more than 20
                DispatchQueue.main.async {
                    print("Step 4\n")
                    completion?()
                }
            } catch let error {
                print("*** \(error.localizedDescription) ***") // No error is ever thrown here, app just freezes
            }
        }
    }

// This is called in init
    func loadFavourites() {
        favourites = []
        guard let data = UserDefaults.standard.data(forKey: AWFavouriteManager.key) else {
            return
        }
        do {
            favourites = try JSONDecoder().decode([AWFavourite].self, from: data)
            print(favourites.map({$0.mediaType.rawValue}))
        } catch let error {
            print("*** \(error.localizedDescription) ***")
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...