gpt4 book ai didi

ios - 如何在执行完成后返回 "GTLRSheetsQuery_SpreadsheetsValuesGet"查询的结果(使用 Sheets API 的 Swift)?

转载 作者:行者123 更新时间:2023-11-29 05:35:34 25 4
gpt4 key购买 nike

我正在尝试使用 Swift 和 Google Sheets API 创建适用于 iOS 的库存管理应用。在开始之前,我想熟悉 API 并确保一切正常工作。为此,我想创建一个函数 getCell,它返回硬编码行和列处的单元格内容(根据需要以 A1 表示法给出)。由于 Swift 中的 Sheets API 实现似乎需要回调模型(一般来说,我是回调和异步编程的初学者),我还没有弄清楚如何在查询完成后在我的函数中返回单元格的内容.

我已按照 Google ( https://developers.google.com/sheets/quickstart/ios?ver=swift&hl=zh-cn ) 提供的 Sheets API iOS 快速入门在开发者控制台中启用 API 并安装必要的 Cocoapods(我的 Podfile 安装“GoogleAPIClientForREST/Sheets”和“GoogleSignIn”)。在将某些部分转换为较新的 Swift 语法后,我得到了包含的代码,可以正常运行和工作。

当我在 ViewController.swift 文件中编写 getCell 函数时,出现了问题。从下面的代码中可以看出,我假设查询将在 getCellQuery 完成时完成,以便 getCell 将能够访问由回调函数 (displayResultWithTicket) 更新的全局变量。然而,我放入的调试打印语句显示回调函数仅在程序末尾执行,在 getCell 检查全局变量并没有发现任何新内容之后。请注意,电子表格 ID 需要替换为真实 ID 才能运行此代码。

import GoogleAPIClientForREST
import GoogleSignIn
import UIKit

struct MyVariables {
static var currentCell: String? = nil
}

class ViewController: UIViewController, GIDSignInDelegate, GIDSignInUIDelegate {

private let scopes = [kGTLRAuthScopeSheetsSpreadsheets]
private let service = GTLRSheetsService()

@IBOutlet weak var signInButton: GIDSignInButton!

override func viewDidLoad() {
super.viewDidLoad()

GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().scopes = scopes
}

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
print("\(error.localizedDescription)")
self.service.authorizer = nil
} else {
self.signInButton.isHidden = true
self.service.authorizer = user.authentication.fetcherAuthorizer()

//main program starts here
print("Cell: " + getCell(a1: "Inventory!A1"))
}
}

func getCell(a1: String) -> String {
print("Started getCell")
getCellQuery(a1: a1)
if MyVariables.currentCell != nil {
print("Finished getCell")
return MyVariables.currentCell!
} else {
print("Error: the global variable is nil and probably hasn't been changed")
print("Finished getCell")
return ""
}
}

func getCellQuery(a1: String) {
print("Started getCellQuery")
let spreadsheetId = "INSERT ID HERE"

// arbitrary row and column in A1 notation
let getRange = a1
let getQuery = GTLRSheetsQuery_SpreadsheetsValuesGet.query(withSpreadsheetId: spreadsheetId, range:getRange)
service.executeQuery(getQuery, delegate: self, didFinish: #selector(displayResultWithTicket(ticket:finishedWithObject:error:)))
print("Finished getCellQuery")
}

@objc func displayResultWithTicket(ticket: GTLRServiceTicket,
finishedWithObject result : GTLRSheets_ValueRange,
error : NSError?) {
print("Started callback")
if let error = error {
print("\(error.localizedDescription)")
return
}

// turn 2d array into string
let rows = result.values!
for row in rows {
for item in row {
// update global variable
MyVariables.currentCell = item as? String
}
}
print("Finished callback")
}
}

登录后,我希望控制台中出现以下内容:

Started getCell
Started getCellQuery
Started callback
Finished callback
Finished getCellQuery
Finished getCell
Cell: <Whatever the cell has>

相反,我得到了这个:

Started getCell
Started getCellQuery
Finished getCellQuery
Error: the cell value is nil and probably hasn't been changed
Finished getCell
Cell:
Started callback
Finished callback

另外,我也尝试过使用 while 循环来等待全局变量更新,但 Swift 似乎始终选择在整个程序结束时调用回调函数,这很烦人。

如果有一种不太笨重的方法来完成这个简单的任务,我们很高兴知道。

最佳答案

您的问题似乎与异步调用模式有关。当您调用 service.executeQuery 时,它将开始异步查询,但由于它正在访问 Web 服务,因此该查询可能需要很长时间才能完成。 executeQuery 函数立即返回,查询本身可能已由其库排队。在下一次机会,请求被发送,当回复返回时,您的 displayResultWithTicket(ticket:finishedWithObject:error:) 回调被调用,但与此同时,您的 getCellQuery 函数的其余部分已完成,就像 getCell 一样。

更好的模式是解雇一些 notification现在您已经有了响应(并传递您在通知中返回的值),然后让该通知的监听器获取响应并对结果执行适当的操作。

或者,sheets API 中可能有一种方法可以传入 closure这很像回调,但它的代码位于传递它的函数中,因此状态管理更容易一些。我不熟悉该 API,因此不确定它是否存在。

这是一篇关于 managing async code 的文章在 Swift 中涵盖了一些选项。它有点旧,但涵盖了基础知识。

关于ios - 如何在执行完成后返回 "GTLRSheetsQuery_SpreadsheetsValuesGet"查询的结果(使用 Sheets API 的 Swift)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57065972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com