Swift 4 使用外部网络框架时将结果传输到主线程

Swift 4 Transfer results to main thread when using external networking framework

我想从服务器 api 获取数据。 问题是所有的网络框架都是异步的。 所以我遇到的问题是 return 变量 return 为空这是我的代码。

调用函数的视图控制器

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let url = "http://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id=12693365&apikey=63ee7da5e2ee269067ecc42b25590922"

        let musixrequest = MusicMatchRequest()
        let endResults =  musixrequest.gettingLyrics(url: url)
        if !endResults.isEmpty{
            print("The end results are \(endResults)")
        }else{
            print("No results found")
        }


    }

这是我的 class 我正在尝试获取数据的地方

public class MusicMatchRequest : NSObject{

public override init(){}

 public func gettingLyrics(url : String) -> String {

    var endResults = ""

    DefaultProvider.request(Route(path:"\(url)")).responseJSON { (response:Response<Any>) in
        switch response.result{
        case .success(let json):
         endResults = String(describing:json)
            print(endResults)
          case .failure(let error):
            print("error: \(error)")
            }
        }
        return endResults
    }


}

当我从它正在工作的任务中打印 endRsults 时,它打印结果但 var endResults return 为空。 想法如何传输数据。

我尝试了两个框架

  1. Alamofire

  2. 尼卡

在两个框架中它的行为相同。

Solution 我不完全知道引擎盖下发生了什么,但作为任何网络操作,这也必须是异步的(这意味着它需要一定的时间来获取数据)。

let endResults = musixrequest.gettingLyrics(url: url)

如果它在主线程上同步完成,它会阻塞它,因此用户无法与应用程序交互,这是非常糟糕的。鉴于它在您的代码中是异步的,您会立即在下一行中读取该值,此处:

if !endResults.isEmpty {
    print("The end results are \(endResults)")
} else {
    print("No results found")
}

网络操作不太可能在一行时间内完成,因此您不会在那里获得数据。 你应该做的是在这个方法中传递一个完成处理程序:

public func gettingLyrics(url : String) -> String

并像这样分派到主线程:

DispatchQueue.main.async { // do you UI stuff here }

将您的功能更改为:

public func gettingLyrics(url : String, completionHandler: (String) -> Void)

并在成功分支中调用完成处理程序:

completionHandler(String(describing:json))