如何调用进行 API 调用的类的实例以及该类中发出请求的函数,并将其分配给变量?迅速

2024-05-27

这是以下问题的后续:为什么代码不在第二个 URLSession.shared.dataTask 之后/之内执行,即在初始 URLSession.shared.dataTask 的 do 块内?迅速 https://stackoverflow.com/questions/72308605/why-isnt-code-being-executed-after-within-a-second-urlsession-shared-datatask/72329561?noredirect=1#comment127788962_72329561

我正在尝试使用分配变量的当前实例self.variable从类的实例进行函数调用。

这可以在所附代码中 ViewController.swift 中以“self.venues =”开头的代码行中看到。

我相信Task与此有关。我读过有关的文档Task,并在网上阅读了更多相关信息,但尚未找到解决方案。

另外:我在 ViewController.swift 中以“self.venues =”开头的代码行收到错误消息“无法将类型‘Task’的值分配给类型‘[Venue]’”。

Code:

ViewController.swift:

import UIKit
import CoreLocation

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet var tableView: UITableView!
    
    var venues: [Venue] = []
    
    override func viewDidLoad() async {
        super.viewDidLoad()
        
        tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")
        tableView.delegate = self
        tableView.dataSource = self
        
        let yelpApi = YelpApi(apiKey: "Api key")
        
        self.venues = Task {
            do { try await yelpApi.searchBusiness(latitude: selectedLatitude, longitude: selectedLongitude, category: "category query goes here", sortBy: "sort by query goes here", openAt: )

            }
            catch {
            //Handle error here.
            print("Error")
            }
        }
        
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
        
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return venues.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell
        
        //Details for custom table view cell go here.
    }
        
    //Rest of table view protocol functions.
}

Venue.swift:

import Foundation

// MARK: - BusinessSearchResult
struct BusinessSearchResult: Codable {
    let total: Int
    let businesses: [Venue]
    let region: Region
}

// MARK: - Business
struct Venue: Codable {
    let rating: Double
    let price, phone, alias: String?
    let id: String
    let isClosed: Bool?
    let categories: [Category]
    let reviewCount: Int?
    let name: String
    let url: String?
    let coordinates: Center
    let imageURL: String?
    let location: Location
    let distance: Double
    let transactions: [String]

    enum CodingKeys: String, CodingKey {
        case rating, price, phone, id, alias
        case isClosed
        case categories
        case reviewCount
        case name, url, coordinates
        case imageURL
        case location, distance, transactions
    }
}

// MARK: - Category
struct Category: Codable {
    let alias, title: String
}

// MARK: - Center
struct Center: Codable {
    let latitude, longitude: Double
}

// MARK: - Location
struct Location: Codable {
    let city, country, address2, address3: String?
    let state, address1, zipCode: String?

    enum CodingKeys: String, CodingKey {
        case city, country, address2, address3, state, address1
        case zipCode
    }
}

// MARK: - Region
struct Region: Codable {
    let center: Center
}

FetchData.swift:

import UIKit
import Foundation
import CoreLocation

class YelpApi {
    
    private var apiKey: String
    
    init(apiKey: String) {
        self.apiKey = apiKey
    }
    
    func searchBusiness(latitude: Double,
                        longitude: Double,
                        category: String,
                        sortBy: String) async throws -> [Venue] {
        
        var queryItems = [URLQueryItem]()
        queryItems.append(URLQueryItem(name:"latitude",value:"\(latitude)"))
        queryItems.append(URLQueryItem(name:"longitude",value:"\(longitude)"))
        queryItems.append(URLQueryItem(name:"categories", value:category))
        queryItems.append(URLQueryItem(name:"sort_by",value:sortBy))
       
        var results = [Venue]()
        
        var expectedCount = 0
        let countLimit = 50
        var offset = 0
        
        queryItems.append(URLQueryItem(name:"limit", value:"\(countLimit)"))
        
        repeat {
            
            var offsetQueryItems = queryItems
            
            offsetQueryItems.append(URLQueryItem(name:"offset",value: "\(offset)"))
            
            var urlComponents = URLComponents(string: "https://api.yelp.com/v3/businesses/search")
            urlComponents?.queryItems = offsetQueryItems
            
            guard let url = urlComponents?.url else {
                throw URLError(.badURL)
            }
            
            var request = URLRequest(url: url)
            request.setValue("Bearer \(self.apiKey)", forHTTPHeaderField: "Authorization")
            
            let (data, _) = try await URLSession.shared.data(for: request)
            let businessResults = try JSONDecoder().decode(BusinessSearchResult.self, from:data)

            expectedCount = min(businessResults.total,1000)
            
            results.append(contentsOf: businessResults.businesses)
            offset += businessResults.businesses.count
        } while (results.count < expectedCount)
        
        return results
    }
}

Thanks!


你有一个异步操作 -searchBusinesses。当你调用这个函数时,需要一些时间才能得到结果。您正在使用await来处理这个问题。

你不能使用await在异步上下文之外,viewDidLoad不是。您正在使用一个Task创建异步上下文。到目前为止,一切都很好。

你出错的地方是试图将结果分配给venues。您只能执行此任务一次await完成。你不会得到这个结果from a Task, 你懂了in the Task:

Task {
    do { 
        self.venues = try await yelpApi.searchBusiness(latitude: selectedLatitude, longitude: selectedLongitude, category: "category query goes here", sortBy: "sort by query goes here", openAt: )
        self.tableView.reloadData()
    } catch {
            //Handle error here.
            print("Error")
    }
}

请注意,您不应将 GCD 调度队列和 async/await 结合起来,在这种情况下,您无需担心主队列。

UIViewController已标记@MainActor。这意味着任务已经在主要参与者上执行,除非您专门创建一个分离任务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何调用进行 API 调用的类的实例以及该类中发出请求的函数,并将其分配给变量?迅速 的相关文章

  • Flutter 应用程序在 iOS 平台的 firebase 电话身份验证中崩溃

    我在我的项目中实现了 Firebase Phone auth 在 Android 端 一切正常 但对于 iOS 端 当我尝试从我的端发送验证码时 应用程序崩溃并失去连接 我已在下面提交了我的代码 主程序 dart class MyApp e
  • 如何为 iPhone 6+、6 和 5 指定不同尺寸?

    我想让 iPhone 6 6 和 5 上的视图看起来几乎相同 在附图中 我的意思是 例如 取消 按钮在 iPhone 5 中距离屏幕左边缘应为 30 像素 在 6 中为 35 像素 在 6 中为 45 像素 其他元素也类似 如何为每种类型设
  • BigQuery 未显示链接的 Firebase Analytics 事件日志的任何数据集

    我将我的帐户链接到 Big Query 但 Firebase Analytics 事件不会自动加载到 BigQuery 中 显示 未找到数据集 警告 我的工作进度附在下面 请查收 I have getting firebase Analyt
  • 为什么选择选择器选项后我的 SwiftUI 页面标题会发生变化?

    struct SettingsView View let settings Setting Setting name Aperture Increments options 1 3 1 2 1 Setting name Shutter Sp
  • 我的 UICollectionView 无法使用 Swift 平滑滚动

    我有一个CollectionView它使单元出队取决于message类型 例如 文本 图像 我遇到的问题是当我向上 向下滚动时滚动确实很不稳定 因此用户体验不是很好 这仅在第一次加载单元格时发生 之后滚动就会平滑 我有什么想法可以解决这个问
  • SwiftUI:隐藏键盘但显示光标

    我想使用自定义按钮将文本输入到TextField 但仍显示并移动光标 有没有办法隐藏默认键盘 同时仍然显示光标 我希望有这样的事情 TextField text text keyboardType none 这是它目前的样子 您可以使用UI
  • 未知异常和崩溃

    当我尝试快速滚动表格视图或从远程重新加载数据时 我的应用程序崩溃了 当我先进行远程获取然后滚动表格视图时 一切似乎都工作正常 我不知道下面的崩溃日志意味着什么 它只是有时工作正常 有时崩溃 Incident Identifier 710A1
  • Android 中 Kotlin 协程的正确使用方式

    我正在尝试使用异步更新适配器内的列表 我可以看到有太多的样板 这是使用 Kotlin 协程的正确方法吗 这个可以进一步优化吗 fun loadListOfMediaInAsync async CommonPool try Long runn
  • 不能从模板 C++ 类继承[重复]

    这个问题在这里已经有答案了 我不知道这里出了什么问题 也许有人可以帮助我 我想继承我的新班级MyDictionary来自模板抽象类dictionary 我有这样的代码 字典 h ifndef UNTITLED CPP DICTIONARY
  • 未捕获 Func<> 的异常(异步)

    我有以下代码 为了进行此重现而进行了简化 显然 catch 异常块将包含更多逻辑 我有以下代码 void Main var result ExecuteAction async gt Will contain real async code
  • 使用 UITabBarController 时覆盖整个屏幕的视图?

    我想在 UITabBarController 设置中在整个屏幕上覆盖 HUD 样式的透明图形 执行此操作的按钮位于第一个选项卡的屏幕 FirstViewController 中 并且覆盖层也应该覆盖选项卡 这可能吗 您可以将新视图直接附加到
  • 在 Objective-C 中的 Swift 类上调用 NSStringFromClass 返回模块损坏的名称

    我知道这个问题 https stackoverflow com questions 24107658 get a user readable version of the class name in swift in objc nsstri
  • ios8 键盘高度有所不同

    我使用下面的代码来获取键盘高度 该高度在带有 ios8 的 iPhone 5s 设备中与带有 ios7 的 IPhone4s 设备中有所不同 因此 当我在带有 ios8 的 iPhone5s 中点击它时 我的文本字段移动得非常高 而相同的代
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 所有 RestKit 项目在归档时都无法构建

    这个问题涉及RESTKIT 0 9 x 如果您是 Restkit 新手 请考虑使用较新的版本0 10 x https github com RestKit RestKit tree v0 10 1 branch 我最近继承了一个项目 使用r
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 使用强光混合模式时突出显示伪影

    我正在 iPhone 应用程序中使用顶部图像的 HardLight 混合模式混合两个图像 它看起来像这样 UIGraphicsBeginImageContext size sourceImage drawInRect rectangle b
  • 上传存档错误:“缺少 iOS 发行版签名身份......”

    我正在尝试使用 Xcode 将我的 iOS 应用程序存档上传到 iTunes Connect 但是当我单击 上传到 App Store 时 出现错误 Xcode 尝试查找或生成匹配的签名资产并 由于以下问题未能做到这一点 缺少 iOS 为
  • Unwind segue 的用途是什么以及如何使用它们?

    iOS 6 和 Xcode 4 5 有一个称为 Unwind Segue 的新功能 展开转场可以允许过渡到故事板中场景的现有实例 除了 Xcode 4 5 发行说明中的 这个简短条目之外 UIViewController 现在似乎还有几个新
  • Fitbit oauth2 公共 API 停止工作。给出错误 - 抱歉,这不是你..是我们

    几个月前 我准备了一个关于 Fitbit oauth2 公共 API 的演示 其中我使用特定用户登录并获取他的活动 一切正常 但最近 我打开演示并尝试使用同一用户登录 但它没有登录并反复出现此错误 我尝试更改在 Fitbit 上注册的演示应

随机推荐