Невозможно вызвать "findObjectsInBackground" при разборе в swift - PullRequest
0 голосов
/ 05 января 2019

В моем следующем коде, когда я звоню openDatabase () , он показывает фатальную ошибку , поскольку pathToDatabase равен нулю.
На самом деле, когда я звоню findObjectsInBackground я не могу войти в блок. так что я получаю pathToDatabase как ноль? Пожалуйста, помогите мне.

import UIKit  
import Parse  

class existDatabase: NSObject {

    var databaseFileName = ""
    var pathToDatabase: String!
    var database: FMDatabase!
    var userAccessCode = ""


    override init()
    {
        super.init()


        if let accesscode = USERDEFAULTS.string(forKey: "UserAccessCode"){

            let query: PFQuery = PFQuery(className: "AccessCode")
            query.whereKey("RegisterCode", equalTo: accesscode)
            query.findObjectsInBackground { (objects, err) in
                if err == nil{
                    if let users = objects{
                        if users.isEmpty {

                        }
                        else{

                            for post in users{
                                if let surgery = post["SurgeryType"] as? String{

                                    if surgery == "Trigger Finger"{
                                        self.databaseFileName = "thumbtriggerfinger"
                                        self.pathToDatabase = Bundle.main.path(forResource: "thumbtriggerfinger", ofType: "db")
                                    }
                                }
                            }
                        }
                    }
                }
                else{
                    print(err?.localizedDescription)
                }
            }

        }
    }

    func openDatabase() -> Bool {
        if database == nil {

            if FileManager.default.fileExists(atPath: pathToDatabase) {
                database = FMDatabase(path: pathToDatabase)
            }
        }

        if database != nil {
            if database.open() {
                return true
            }
        }

        return false
    }
}

1 Ответ

0 голосов
/ 05 января 2019

Предположительно, у вас есть код, похожий на

 let x = existDatabase()
 x.openDatabase()

Проблема в том, что в вашем инициализаторе есть асинхронный блок, что означает, что объект не будет полностью инициализирован, когда инициализатор вернется; выборка фонового анализа еще не завершена.

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

Наличие асинхронной операции в инициализаторе редко является хорошим дизайном.

Я бы предложил вам реструктурировать свой код так, чтобы openDatabase выполнял асинхронную операцию и принимал обработчик завершения.

Кроме того, стилистически имена классов должны начинаться с заглавной буквы и обычно являются существительными, а не глаголами.

class DatabaseManager {

    static database(for accessCode: String, completion: @escaping (FMDatabase?,Error?)) {
        let query: PFQuery = PFQuery(className: "AccessCode")
        query.whereKey("RegisterCode", equalTo: accessCode)
        query.findObjectsInBackground { (objects, err) in
            if err == nil{
                if let users = objects, !users.isEmpty {
                    for post in users{
                        if let surgery = post["SurgeryType"] as? String{
                            if surgery == "Trigger Finger"{
                                let pathToDatabase = Bundle.main.path(forResource: "thumbtriggerfinger", ofType: "db")
                                if FileManager.default.fileExists(atPath: pathToDatabase) {
                                    database = FMDatabase(path: pathToDatabase)
                                    if database.open() {
                                        completion(database,nil)
                                    } else {
                                        completion(nil, nil)
                                    }
                                break
                                }
                            }
                        }
                    }
                } else {
                    completion(nil,nil)
                }
            }
            else{
                completion(nil, err)
            }
        }
    }
}

Позвоните, используя:

if let accesscode = USERDEFAULTS.string(forKey: "UserAccessCode"){
    DatabaseManager.database(for: accesscode) { (database, error) in {
        guard error == nil else {
            print("error: (error!.localalizedDescription)")
            return
        } 
        guard let db = database else {
            print("No database")
            return
        }
        // Do something with db
    }
}
...