无法在 swift 中的解析中调用 "findObjectsInBackground"
Unable to call "findObjectsInBackground" in parse in swift
在下面的代码中,当我调用 openDatabase() 时,它显示 fatal error as pathToDatabase 为零。
实际上,当我调用 findObjectsInBackground 时,我无法进入块。这样我得到 pathToDatabase 为 nil ?请帮我。
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
}
}
想必你有这样的代码
let x = existDatabase()
x.openDatabase()
问题是您的初始化程序中有一个异步块,这意味着当初始化程序 returns 时对象不会被完全初始化; Parse 后台提取尚未完成。
你会崩溃,因为隐式展开的可选是 nil
。您需要使用隐式展开的可选项这一事实是您的第一个警告信号。您应该能够为初始化程序中的 属性 集使用非可选值,但您不能,因为属性是在闭包中设置的。
在初始化程序中进行异步操作很少是一个好的设计。
我建议您重构代码,以便 openDatabase
执行异步操作并接受完成处理程序。
此外,从文体上来说,class 名称应以大写字母开头,并且通常是名词,而不是动词。
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
}
}
在下面的代码中,当我调用 openDatabase() 时,它显示 fatal error as pathToDatabase 为零。
实际上,当我调用 findObjectsInBackground 时,我无法进入块。这样我得到 pathToDatabase 为 nil ?请帮我。
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
}
}
想必你有这样的代码
let x = existDatabase()
x.openDatabase()
问题是您的初始化程序中有一个异步块,这意味着当初始化程序 returns 时对象不会被完全初始化; Parse 后台提取尚未完成。
你会崩溃,因为隐式展开的可选是 nil
。您需要使用隐式展开的可选项这一事实是您的第一个警告信号。您应该能够为初始化程序中的 属性 集使用非可选值,但您不能,因为属性是在闭包中设置的。
在初始化程序中进行异步操作很少是一个好的设计。
我建议您重构代码,以便 openDatabase
执行异步操作并接受完成处理程序。
此外,从文体上来说,class 名称应以大写字母开头,并且通常是名词,而不是动词。
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
}
}