Как мне исправить «Дополнительный аргумент в вызове» при декодировании с необходимым удобством init? (Кодер :)? - PullRequest
0 голосов
/ 14 октября 2019

Я относительно новичок в разработке приложений и пытаюсь добавить постоянство в приложение для управления домашними заданиями, написанное с использованием SwiftUI. Я реализую NSCoding в своем классе «UserData» и смог без проблем создать функцию кодирования, но после настройки функции декодирования я получаю сообщение об ошибке «Назначение дополнительных аргументов в вызове» в self.init () линия. Что именно не так с моим кодом?

class UserData: NSObject, NSCoding, ObservableObject {

    // MARK:- Properties

    @Published var assignments: [Assignment]
    @Published var courses: [Course] = []

    @Published var username: String = ""
    @Published var appState: AppState = AppState(willPresentSplashScreen: false)

...

 // MARK:- NSCoding

    func encode(with coder: NSCoder) {
        coder.encode(assignments, forKey: PropertyKey.assignments)
        coder.encode(courses, forKey: PropertyKey.courses)
        coder.encode(username, forKey: PropertyKey.username)
        coder.encode(appState, forKey: PropertyKey.appState)
    }

    required convenience init?(coder decoder: NSCoder) {

        let assignments = decoder.decodeObject(forKey: PropertyKey.assignments) as? [Assignment]
        let courses = decoder.decodeObject(forKey: PropertyKey.courses) as? [Course]
        let username = decoder.decodeObject(forKey: PropertyKey.username) as? String
        let appState = decoder.decodeObject(forKey: PropertyKey.appState) as? AppState

        self.init(assignments: assignments, courses: courses, username: username, appState: appState)
    }
}

1 Ответ

0 голосов
/ 14 октября 2019

UserData - это класс, и классы, в отличие от структур, не получают инициализатор по умолчанию для членов. Вам нужно создать инициализатор, который принимает эти параметры. Без него ближайший инициализатор, который может найти Swift, - это init(), унаследованный от NSObject, за исключением того, что имена параметров не совпадают, поэтому он выдает ошибку.

Вам необходимо создать членinitializer:

init(assignments: [Assignment], courses: [Course], username: String, appState: AppState) {
    self.assignments = assignments
    self.courses = courses
    self.username = username
    self.appState = appState
}

Это даст вам ошибку, что параметры, которые вы передаете из init?(coder decoder: NSCoder), должны быть развернуты, так как у вас есть опции, а инициализатор не ожидает опций.

init?(coder decoder: NSCoder) - сбойный инициализатор, поэтому вы можете вернуть nil, если что-то не так:

required convenience init?(coder decoder: NSCoder) {

        guard let assignments = decoder.decodeObject(forKey: PropertyKey.assignments) as? [Assignment],
            let courses = decoder.decodeObject(forKey: PropertyKey.courses) as? [Course],
            let username = decoder.decodeObject(forKey: PropertyKey.username) as? String,
            let appState = decoder.decodeObject(forKey: PropertyKey.appState) as? AppState else {
                return nil
        }

        self.init(assignments: assignments, courses: courses, username: username, appState: appState)
}

Я бы, вероятно, избавился от значений по умолчанию, присвоенных courses, username и appState - они вам не нужны, так как значения поступят из инициализатора

...