代码之家  ›  专栏  ›  技术社区  ›  lf_araujo

Linux支持URLSession吗?

  •  0
  • lf_araujo  · 技术社区  · 6 年前

    curl -X GET --header 'Accept: text/plain' --header 'app_id: 8a7dd147' --header 'app_key: 7e7d022fbce6d8d4523eac3baa5bd04c' 'https://od-api.oxforddictionaries.com/api/v1/entries/en/ace'
    

    返回Ace这个词的json数据。现在,在Ubuntu 18.04上,我尝试以下方法:

    import Foundation
    //var request = URLRequest(url: URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/en/love")!)
    
    // TODO: replace with your own app id and app key
    let appId = "8a7dd147"
    let appKey = "7e7d022fbce6d8d4523eac3baa5bd04c"
    let language = "en"
    let word = "Ace"
    let word_id = word.lowercased() //word id is case sensitive and lowercase is required
    let url = URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/en/love")!  // \(language)/\(word_id)")!
    var request = URLRequest(url: url)
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue(appId, forHTTPHeaderField: "app_id")
    request.addValue(appKey, forHTTPHeaderField: "app_key")
    //request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    print("passed request addValue")
    
    let session = URLSession.shared
    _ = session.dataTask(with: request, completionHandler: { data, response, error in
        if let response = response,
            let data = data,
            let jsonData = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) {
                print("about to give you a response")
            print(response)
            print(jsonData)
        } else {
            print(error)
            print(NSString.init(data: data!, encoding: String.Encoding.utf8.rawValue))
        }
    }).resume()
    

    或以下情况:

    import Foundation
    
    let params: [String: String] = ["app_id": "8a7dd147", "app_key": "7e7d022fbce6d8d4523eac3baa5bd04c"]
    
    var request = URLRequest(url: URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/en/love")!)
    request.httpMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("8a7dd147", forHTTPHeaderField: "app_id")
    request.addValue("7e7d022fbce6d8d4523eac3baa5bd04c", forHTTPHeaderField: "app_key")
    
    URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
        print(response!)
        do {
            let json = try JSONSerialization.jsonObject(with: data!)
            print(json)
            print("we did it!")
        } catch {
            print("error")
        }
    }).resume()
    
    //task.resume()
    

    但是没有人返回“爱”这个词的json信息。我一直在试着调试这个,但不知道出了什么问题。

    • 它是否与操作系统相关,因此是一个bug?有人能在MacOS上测试一下吗。还是我遗漏了什么?
    1 回复  |  直到 6 年前
        1
  •  4
  •   user9335240    6 年前

    URLSession 在后台线程上执行操作。当你结束一个多线程程序的主线程时,所有的线程都会被终止(除了在一些像Java这样的语言中你可以设置守护进程线程,守护进程线程可能是其他线程,但是程序的结束应该在该线程结束之后)。

    因此,您的解决方案是延长主线程的生存期,如:

    let group = DispatchGroup.init()
    
    group.enter() // Use this before making anything that needs to be waited for
                  // This manually add one to operation count in the dispatch group
    URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
        defer {  // Defer makes all ends of this scope make something, here we want to leave the dispatch.
                 // This is executed when the scope ends, even if with exception.
    
    
           group.leave() // Manually subtract one from the operation count
        }
        print(response!)
        do {
            let json = try JSONSerialization.jsonObject(with: data!)
            print(json)
            print("we did it!")
        } catch {
            print("error")
        }
    }).resume()
    
    group.wait()  // Wait for group to end operations.
    

    但更好的是,在实际应用程序中,不要阻塞主线程,例如web应用程序,应用程序通常比请求更活跃,因此不需要干预,但要尽量避免阻塞用户( sleep DispatchGroup.wait 除非是在后台线程中,等等…)

        2
  •  0
  •   Tiago Mendes chengsam    4 年前

    您还可以使用以下代码:

    // Avoid closing this project for 40 seconds
    RunLoop.main.run(until: Date(timeIntervalSinceNow: 40))