如何使用 Swift Async 方法从后端数据库中检索数据?

Posted

技术标签:

【中文标题】如何使用 Swift Async 方法从后端数据库中检索数据?【英文标题】:How to retrieve data from backendless DB using Swift Async method? 【发布时间】:2016-04-11 20:55:29 【问题描述】:

我正在尝试快速从后端数据库接收数据。代码抛出一个致命错误:在展开可选值时意外发现 nil

func findPlayersByPosition(position: String) -> [Player] 

    let whereClause = "category = '\(position)'"
    let dataQuery = BackendlessDataQuery()
    dataQuery.whereClause = whereClause

    var error: Fault?

    let players = Backendless.sharedInstance().data.of(Player.ofClass()).find(dataQuery, fault: &error)

    if error == nil 
        print("Contacts have been found: \(players.data)") // **Fatal error is thrown on this line**
    
    else 
        print("Server reported an error: \(error)")
    

    var playerDB = players.data as! [Player]

    return playerDB

“players”确实包含数据,所以我认为可能会出现此错误,因为我正在使用同步方法来检索调用 print(players.data) 时尚未完成的播放器。如果我错了,请纠正我。

所以我想使用异步方法来查看是否可以解决错误。我一直在研究backendless documentation,它确实解释了如何进行异步调用:

func find(_ dataQuery: BackendlessDataQuery!, responder responder: IResponder!) -> Void

但我还是不明白如何将此方法应用到我自己的代码中?非常感谢您的帮助。

更新问题

感谢到目前为止的回答。我发现当我从 viewdidload() 内部调用该函数时,它工作正常。但是,当我在视图控制器中使用所需的 init 方法调用函数时,如下所示:

required init?(coder aDecoder: NSCoder) 
    do 
        let players = findPlayersByPosition("GK")
     catch let error 
        fatalError("\(error)")
    
    super.init(coder: aDecoder)

那么玩家仍然是零

Q1:为什么这在所需的 init() 中不起作用?

【问题讨论】:

你试过用断点调试它吗?代码中存在的变量的内容是什么。 更新了我的问题。问题:当我从 viewdidload() 调用它时,我的函数确实可以工作,但当我从 viewcontroller 内的所需 init 调用它时却不行。知道为什么不? 同样的逻辑适用 - 不存在布局信息。如果它从 viewDidLoad 工作,那是纯粹的运气 - 它不会在所有设备上工作,将每个布局逻辑放在它所属的地方,而不是 init 或 didLoad 我还在学习布局逻辑。看来我还有一些阅读要做。感谢您的回答 【参考方案1】:

您的播放器对象可能为 nil(或 player.data 可能为 nil)。在 if 语句之前打印出来。

您可以按如下方式保护您的代码:

if let players = players 
    if error == nil 
        print("Contacts have been found: \(players.data)") // **Fatal error is thrown on this line**
    
    else 
        print("Server reported an error: \(error)")
    

else 
    print("nil players object")

看来您应该异步调用 Backendless:

let dataStore = Backendless.sharedInstance().data.of(Player.ofClass())

let players = dataStore.find(dataQuery, 
    response:  (result: BackendlessCollection!) -> Void in

        // handle response here

    , 
    error:  (fault: Fault!) -> Void in

        // handle error here

    )

https://backendless.com/documentation/data/ios/data_search_and_query.htm

【讨论】:

players.data 由于 where 子句中的拼写错误而为空。修复了该问题,但在“var playerDB = player.data as![Player]”行尝试投射到 [player] 时仍然出现错误。关于如何解决这个问题的任何想法? 我不知道players.data是什么类型,所以我只能给你一些指导。您不能随意将数据转换为某种类型对象的数组。 Backendless 说要做什么?您是否从他们那里寻找过文档或示例? 是的,他们自己在文档中转换为数组。实际上,我只是让该函数在 viewdidload() 中工作,但是当我从 viewcontroller 内所需的 init 中调用它时它仍然无法工作(请参阅更新的问题)。 Backendless 的调用真的是同步的吗? 看起来这个函数不包括响应者处理程序:Backendless.sharedInstance().data.of(Player.ofClass()).find(dataQuery, fault: &error) 而异步调用签名在文档中确实(请参阅问题)。我已就如何解决此问题征求他们的支持。当我得到答案时会在这里发布。

以上是关于如何使用 Swift Async 方法从后端数据库中检索数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将自定义错误从后端(Express)传递到前端(Vue)

如何从后端通知前端?

如果你有 apollo react 钩子从后端获取数据,你如何使用 nextjs 进行服务器端渲染?

如何使用节点 js 从后端 API 请求 apikey?

从后端连接到外部数据库

如何修改 Angular 组件以从后端获取信息?