【问题标题】:Can't load data into ViewController from a JSON response swift无法从 JSON 响应快速将数据加载到 ViewController
【发布时间】:2019-12-07 20:26:07
【问题描述】:

我在理解使用 SWIFT 使用 REST api 服务的过程时遇到了问题,似乎我在这里遗漏了一些简单但又很重要的东西。

这是单例 DataManager 类,我使用 loadNews() 方法来使用 API,如您所见,它很简单,请求方法、getter 和初始化器将加载数据。

对于 loadNews(),我使用 Alamofire 处理请求,使用 SwiftyJSON 解析响应。

class DataManager{
    static let shared = DataManager()
    private var data:JSON = JSON()
    private init(){
        print("testprint1 \(self.data.count)")
        loadNews() { response in
            self.data = response

            print("initprint \(self.data.count)")
            print(self.data["response"]["results"].count)
            print(self.data["response"]["results"][0]["id"].stringValue)
        }
        print("testprint2 \(self.data.count)")
    }
    func getNews() -> JSON {        
        return data
    }
    func loadNews(completion: @escaping (JSON) -> ()){
        Alamofire.request("...")
            .responseJSON{ response in
                guard response.result.isSuccess,
                  let value = response.result.value else {
                    print("Error: \(String(describing: response.result.error))")
                    completion([])
                    return
                }
                let json = JSON(value)
                completion(json)
        }     
    }
}

我面临的问题是,当我尝试在 ViewController 中调用 DataManager() 实例时,由于某种原因我无法读取控制器中的数据,这是控制器代码(相关代码):

class SecondViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let data1 = DataManager.shared.getNews()
        print("qa \(data1.count)")
    }
...
}

现在困扰我的是 - 这背后的逻辑应该很简单,let data1 = DataManager.shared.getNews() - 如果我没记错,将(应该)执行以下流程:

init()->loadNews()->getNews() initialize 方法将调用 loadNews,loadNews 将从 API 获取数据,填充数据数组,getNews 应该返回填充的数据数组,但该流程似乎不正确

console output

控制台输出文本

testprint1 0
testprint2 0
qa 0
initprint 1
50
commentisfree/2019/dec/07/lost-my-faith-in-tech-evangelism-john-naughton

所以看起来 init() 中的两个打印都在它们之间的 loadNews() 方法之前执行,以及在 ViewController 中打印数组大小的“qa0”打印。

现在我的问题是,有没有人在这里看到错误,这是因为长时间的网络查询而发生的,还是我只是遗漏了一些东西,因为在我看来数据已正确加载和解析,这在最后 2 中看到输出行,但我无法在需要它的地方得到它,就像它消失一样。我的逻辑错了吗?如果有人可以提供帮助,我将不胜感激。

【问题讨论】:

    标签: json swift alamofire swifty-json


    【解决方案1】:

    Alamofire 进程是异步工作的,但你不考虑,那就是错误。

    把代码改成

    class DataManager{
        static let shared = DataManager()
    
        func loadNews(completion: @escaping (JSON) -> ()){
            Alamofire.request("...")
                .responseJSON{ response in
                    guard response.result.isSuccess,
                      let value = response.result.value else {
                        print("Error:", response.result.error)
                        completion([])
                        return
                    }
                    let json = JSON(value)
                    completion(json)
            }     
        }
    }
    

    class SecondViewController: UITableViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            DataManager.shared.loadNews() { response in
    
                print("initprint \(response.count)")
                print(response["response"]["results"].count)
                print(response["response"]["results"][0]["id"].stringValue)
            }
        }
    ...
    }
    

    您必须从 SecondViewController 中的完成处理程序中获取数据

    【讨论】:

    • 比你好多了,我拿到SecondViewController里的数据,你是救星!!
    • 不客气。请注意,稍后在 viewDidLoad 中,您不能使用闭包之外的数据
    • 我刚刚到了那个地步.. 但是我将如何使用这些数据呢?
    • 在闭包内执行您必须执行的操作,例如调用方法或将数据分配给属性并重新加载表格视图或填充其他 UI 元素。
    猜你喜欢
    • 2021-05-04
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多