Swift Firebase getIDToken以及如何在API调用中使用它
我有一个获取json的API调用,但需要令牌身份验证。tokenauth工作得很好,但是当我尝试将Token传递给API函数时,它返回为nil。我相信这是因为Swift Firebase getIDToken以及如何在API调用中使用它,swift,firebase,swiftui,Swift,Firebase,Swiftui,我有一个获取json的API调用,但需要令牌身份验证。tokenauth工作得很好,但是当我尝试将Token传递给API函数时,它返回为nil。我相信这是因为Auth.Auth().currentUser!。getIDToken(…)尚未实际完成。相关代码如下。。。如何将其修改为 class SessionData : ObservableObject { ... func token() -> String? { var result: String? =
Auth.Auth().currentUser!。getIDToken(…)
尚未实际完成。相关代码如下。。。如何将其修改为
class SessionData : ObservableObject {
...
func token() -> String? {
var result: String? = nil
Auth.auth().currentUser!.getIDToken(completion: { (res, err) in
if err != nil {
print("*** TOKEN() ERROR: \(err!)")
} else {
print("*** TOKEN() SUCCESS: \(err!)")
result = res!
}
})
return result
}
...
}
class FetchPosts: ObservableObject {
@Published var posts = [Post]()
func load(api: Bool, session: SessionData) {
if api {
let url = URL(string: MyAPI.getAddress(token: session.token()!))!
URLSession.shared.dataTask(with: url) {(data, response, error) in
do {
if let postsData = data {
// 3.
let decodedData = try JSONDecoder().decode(Response.self, from: postsData)
DispatchQueue.main.async {
self.posts = decodedData.result
if decodedData.error != nil {
print("ERROR: \(decodedData.error!)")
session.json_error(error: decodedData.error!)
}
}
} else {
print("No data. Connection error.")
DispatchQueue.main.async {
session.json_error(error: "Could not connect to server, please try again!")
}
}
} catch {
print("* Error: \(error)")
}
}.resume()
} else {
let url = Bundle.main.url(forResource: "test", withExtension: "json")!
let data = try! Data(contentsOf: url)
let decoder = JSONDecoder()
if let products = try? decoder.decode([Post].self, from: data) {
self.posts = products
}
}
}
}
这就是.load函数的调用方式:
UserViewer(fetch: posts)
.transition(AnyTransition.slide)
.animation(.default)
.onAppear {
withAnimation{
posts.load(api: true, session: session)
}
}
.environmentObject(session)
因为
getIDToken
异步执行并返回,所以不能直接从它返回。相反,您需要使用回调函数
以下是对函数的修改:
func token(_ completion: @escaping (String?) -> ()) {
guard let user = Auth.auth().currentUser else {
//handle error
return
}
user.getIDToken(completion: { (res, err) in
if err != nil {
print("*** TOKEN() ERROR: \(err!)")
//handle error
} else {
print("*** TOKEN() SUCCESS: \(err!)")
completion(res)
}
})
}
然后,您可以在以后使用它:
.onAppear {
session.token { token in
guard let token = token else {
//handle nil
return
}
withAnimation{
posts.load(api: true, session: session, token: token)
}
}
}
修改加载
以获取令牌
参数:
func load(api: Bool, session: SessionData, token: String) {
if api {
guard let url = URL(string: MyAPI.getAddress(token: token)) else {
//handle bad URL
return
}
此外,正如您在我的代码示例中所看到的,我将尝试摆脱使用
的习惯代码>强制展开选项。如果可选项为nil
,并且您使用代码>,您的程序将崩溃。相反,要熟悉guard let
和if let
,并学会以不会导致崩溃的方式处理可选项——这是Swift的最大好处之一。您必须使用所谓的“回调函数”,因为它是异步完成的。