Swift 3 URLSession. Shared () Tham chiếu mơ hồ đến dataTask của thành viên (với: xongHandler :) lỗi (lỗi)


169

Xin chào Tôi đã làm việc mã phân tích json cho swift2.2 nhưng khi tôi sử dụng nó cho Swift 3.0 thì tôi gặp lỗi đó

ViewControll.swift: 132: 31: Tham chiếu mơ hồ đến dataTask của thành viên (với: xongHandler :) '

Mã của tôi ở đây

   let listUrlString =  "http://bla.com?batchSize=" + String(batchSize) + "&fromIndex=" + String(fromIndex)
    let myUrl = URL(string: listUrlString);
    let request = NSMutableURLRequest(url:myUrl!);
    request.httpMethod = "GET";

    let task = URLSession.shared().dataTask(with: request) {
        data, response, error in

        if error != nil {
            print(error!.localizedDescription)
            DispatchQueue.main.sync(execute: {
                AWLoader.hide()
            })

            return
        }

        do {

            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray

            if let parseJSON = json {

                var items = self.categoryList

                items.append(contentsOf: parseJSON as! [String])

                if self.fromIndex < items.count {

                    self.categoryList = items
                    self.fromIndex = items.count

                    DispatchQueue.main.async(execute: {

                        self.categoriesTableView.reloadData()

                        AWLoader.hide()

                    })
                }else if( self.fromIndex == items.count){


                    DispatchQueue.main.async(execute: {

                        AWLoader.hide()

                    })

                }



            }

        } catch {
            AWLoader.hide()
            print(error)

        }
    }

    task.resume()

Cảm ơn ý tưởng.


2
Tôi đã nhận được cùng một lỗi bởi vì tôi đã chuyển một chuỗi đến dataTask(with:ví dụ như tôi có url = "www.yahoo.comvà tôi đã chuyển thẳng vào hàm mà không chuyển đổi nó thành mộtURL
Honey

Câu trả lời:


312

Trình biên dịch bị nhầm lẫn bởi chữ ký hàm. Bạn có thể sửa nó như thế này:

let task = URLSession.shared.dataTask(with: request as URLRequest) {

Nhưng, lưu ý rằng chúng tôi không phải bỏ "yêu cầu" như URLRequesttrong chữ ký này nếu nó được tuyên bố trước đó URLRequestthay vì NSMutableURLRequest:

var request = URLRequest(url:myUrl!)

Đây là quá trình truyền tự động giữa NSMutableURLRequestvà mới URLRequestđang thất bại và buộc chúng tôi phải thực hiện việc đúc này ở đây.


7
var request = URLRequest(url:myUrl!)
Leo Dabus

1
SE-0072 cho biết, loại bỏ cầu nối ngầm. khi "tên hàm swifty" trở thành "phương thức ghi đè thực tế", chúng ta không thể đảo ngược tra cứu Objective-C SEL, vì vậy chúng ta phải sử dụng hoặc chuyển sang Foundation struct.
quesera2

2
Câu trả lời rất hữu ích. Tôi chỉ thêm rằng sẽ tốt hơn nếu tránh myUrl! buộc phải hủy kết nối bằng cách thực hiện việc này: bảo vệ hãy để myUrl = URL (chuỗi: listUrlString) khác {return} thì yêu cầu có thể được gọi mà không cần! var request = URLRequest (url: myUrl)
Đánh dấu Semsel

2
Nhà URL(string:)xây dựng có thể thất bại bao giờ?
BallpointBen

Phải bỏ phiếu nhưng tôi vẫn gặp sự cố, nó xuất ra "giá trị không hợp lệ xung quanh ký tự 0" có ai không?
Marfin. F

33

Bạn có init'd myRequestnhư NSMutableURLRequest, bạn cần điều này:

var URLRequest

Swift đang bỏ cả hai NSMutable...thứ. Chỉ cần sử dụng varcho các lớp mới.


17

Xcode 8 và Swift 3.0

Sử dụng URLSession:

 let url = URL(string:"Download URL")!
 let req = NSMutableURLRequest(url:url)
 let config = URLSessionConfiguration.default
 let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)

 let task : URLSessionDownloadTask = session.downloadTask(with: req as URLRequest)
task.resume()

Cuộc gọi đại biểu URLSession:

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

}


func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, 
didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
                   print("downloaded \(100*writ/exp)" as AnyObject)

}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){

}

Sử dụng Khối GET / POST / PUT / DELETE:

 let request = NSMutableURLRequest(url: URL(string: "Your API URL here" ,param: param))!,
        cachePolicy: .useProtocolCachePolicy,
        timeoutInterval:"Your request timeout time in Seconds")
    request.httpMethod = "GET"
    request.allHTTPHeaderFields = headers as? [String : String] 

    let session = URLSession.shared

    let dataTask = session.dataTask(with: request as URLRequest) {data,response,error in
        let httpResponse = response as? HTTPURLResponse

        if (error != nil) {
         print(error)
         } else {
         print(httpResponse)
         }

        DispatchQueue.main.async {
           //Update your UI here
        }

    }
    dataTask.resume()

Làm việc tốt cho tôi .. hãy thử đảm bảo 100% kết quả


15

Sự cố này là do URLSession có hai phương thức dataTask

open func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask
open func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask

Loại thứ nhất có URLRequesttham số và loại thứ hai có URLtham số, vì vậy chúng ta cần chỉ định loại nào sẽ gọi, ví dụ: tôi muốn gọi phương thức thứ hai

let task = URLSession.shared.dataTask(with: url! as URL) {
    data, response, error in
    // Handler
}

đã có ý nghĩa. Cảm ơn
iBug

10

Trong trường hợp của tôi, lỗi là ở NSURL

let url = NSURL(string: urlString)

Trong Swift 3, bạn phải viết chỉ URL :

let url = URL(string: urlString)

3

Đã kiểm tra xcode 8 phiên bản ổn định; Cần sử dụng var requestbiến với URLRequest()Withs, bạn có thể dễ dàng sửa lỗi đó ( lỗi )

var request = URLRequest(url:myUrl!)

let task = URLSession.shared().dataTask(with: request as URLRequest) { }

Làm việc tốt Cảm ơn các bạn, tôi nghĩ giúp nhiều người. !


1
Điều này không có ý nghĩa gì khi chuyển từ URLRequest sang URLRequest
Leo Dabus

var request = URLRequest(url: url); let task = URLSession.shared().dataTask(with: request) { ... }
Leo Dabus

sharedlà một thuộc tính chứ không phải là một chức năng trong Swift 3 (không có dấu ngoặc đơn).
vadian

@vadian không phải lúc tôi đăng bình luận
Leo Dabus

3

Đối với Swift 3 và Xcode 8:

      var dataTask: URLSessionDataTask?

      if  let url = URL(string: urlString) {
            self.dataTask = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

                if let error = error {
                    print(error.localizedDescription)
                } else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
                     // You can use data received.
                    self.process(data: data as Data?)
                }
            })
        }
     }

// Lưu ý: Bạn luôn có thể sử dụng trình gỡ lỗi để kiểm tra lỗi


3

Trong swift 3 trình biên dịch bị nhầm lẫn bởi chữ ký hàm. Chỉ định nó sẽ xóa lỗi. Đồng thời chuyển đổi chuỗi url để nhập URL. Các mã sau đây làm việc cho tôi.

   let urlString = "http://bla.com?batchSize="
   let pathURL = URL(string: urlString)!
   var urlRequest = URLRequest(url:pathURL)

    let session = URLSession.shared
    let dataTask = session.dataTask(with: urlRequest as URLRequest) { (data,response,error) in

3

Câu trả lời ngắn gọn và súc tích cho Swift 3:

guard let requestUrl = URL(string: yourURL) else { return }

let request = URLRequest(url:requestUrl)
URLSession.shared.dataTask(with: request) {
    (data, response, error) in
    ...

}.resume()

2
 // prepare json data
        let mapDict = [ "1":"First", "2":"Second"]

        let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
        let jsonData : NSData = NSKeyedArchiver.archivedData(withRootObject: json) as NSData

        // create post request
        let url = NSURL(string: "http://httpbin.org/post")!
        let request = NSMutableURLRequest(url: url as URL)
        request.httpMethod = "POST"

        // insert json data to the request
        request.httpBody = jsonData as Data


        let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
            if error != nil{
                return
            }
            do {
                let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]

                print("Result",result!)

            } catch {
                print("Error -> \(error)")
            }
        }

        task.resume()

2

Để tải dữ liệu qua yêu cầu GET, bạn không cần bất kỳ URLRequest(và không có dấu chấm phẩy)

let listUrlString =  "http://bla.com?batchSize=" + String(batchSize) + "&fromIndex=" + String(fromIndex)
let myUrl = URL(string: listUrlString)!
let task = URLSession.shared.dataTask(with: myUrl) { ...

2
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data,response,error in
        if error != nil{
            print(error!.localizedDescription)
            return
        }
        if let responseJSON = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? [String:AnyObject]{
            if let response_token:String = responseJSON["token"] as? String {
                print("Singleton Firebase Token : \(response_token)")
                completion(response_token)
            }
        }
    })
    task.resume()

2

Xcode 10.1 Swift 4

Điều này làm việc cho tôi:

let task: URLSessionDataTask = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
...

Chìa khóa đã được thêm vào trong URLSessionDataTaskkhai báo loại.


1

Đối với tôi, tôi làm điều này để tìm,

let url = URL(string: urlString)
URLSession.shared.dataTask(with: url!) { (data, response, error) in ...}

Không thể sử dụng

"let url = NSURL(string: urlString)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.