【问题标题】:Get items from json data and add to array从 json 数据中获取项目并添加到数组
【发布时间】:2026-01-17 13:20:06
【问题描述】:

我正在使用 Flickr api 根据使用以下代码的搜索检索图像。该函数将图像 id 发送到端点并返回一个对象,我解析该对象以获得所述图像的特定 url。我得到了我想要的响应,但我正在尝试获取 item.source 中的所有图像 url 并将它们添加到数组中。我尝试返回一个数组,但编译器抱怨这无法完成,因为它是 non-void return from a void method,尽管我将 [String] 设置为返回值。如何将item.source 列表作为要在getURLImages() 之外使用的数组?或者,我创建了如下所示的 urlsList,并尝试将 item.source 附加到此,但这始终打印为空。对于上下文,我计划创建一个UICollectionView 来显示所述图像/网址。

更新

下面是 A 类调用 B 类 getURLImages 的函数:

 let result = try JSONDecoder().decode(Response.self, from: data)
  
 if (result.stat == "ok"){
     for urls in result.photos!.photo {           
         DispatchQueue.main.async {
             GetImageInfo().getURLImages(photoId: urls.id) { urlsList in
                  print("Received \(urlsList)")
              }
         }
      }
 }

下面是B类的函数:

let result = try JSONDecoder().decode(Response.self, from: data)
var urlList = [String]()
for item in result.sizes!.size {
    DispatchQueue.main.async {
        if (item.label == "Square"){
            urlList.append(item.source)
                            
        }
    }
 }
 completion(urlList)

如何在函数范围之外访问 urlsList 属性,以便将其实现到 UICollectionView 中

【问题讨论】:

    标签: arrays json swift


    【解决方案1】:

    您不能直接从闭包中返回函数的值。您将不得不为此使用完成处理程序闭包。


    例子:

    func getURLImages(photoId: String, completion: @escaping ([String]) -> Void) {
        ...
        // Call completion handler when you generate your [String] response
        completion(yourImageURLs)
        ...
    }
    

    并像这样使用它:

    let urls = [String]()
    
    getURLImages(photoId: "some id") { [weak self] imageURLs in
        guard let self = self else { return }
    
        print("Received some \(imageURLs)"
        self.urls = imageURLs
        self.updateCollectionViewOrSomething()
    }
    
    func updateCollectionViewOrSomething() {
        self.collectionView.reloadData()
    }
    

    【讨论】:

    • 在函数内部,我会用什么替换 yourImageURLS?它们目前是在遍历 json 响应和特定键值出现的地方获得的。我会完成(urlsList)吗?
    • 您可以在开始 for 循环之前在闭包内创建一个本地 [String] 数组并填充该数组而不是 urlsList,然后在完成中使用该数组。这样您就可以轻松地将您的 getURLImages 移动到其他地方,而不会破坏您的代码。
    • 为了进一步将您的功能与外部隔离,您可以改进您的参数列表:getURLImages(photoId: String, config: AppConfig = AppConfig(), completion: ...)
    • 这样您就可以将getURLImages 移动到其单独的文件或代码库中的任何其他位置,而不会破坏现有代码。
    • 顺便说一句,完成处理程序应该在你完成收集你的 url 时被调用,所以,在 for 循环之外。