Swift 关闭 API 连接

Swift close API connection

如果我使用这种方式连接到 API,是否会创建一个连接会话?以及如何关闭它以便下次运行时不会花费太多时间,因为还有另一个会话打开?!

do {
    let data = try String(contentsOf: url)
    if !data.isEmpty {
        // use data
    }
} catch {
    print("Log \(error)")
}

更新

我的会话将从 API 中检索新闻,并根据这些新闻的经纬度在地图上绘制标记。 API 请求总是需要大约一秒钟,但在绘制标记之后需要不同的时间。当我导航到另一个视图然后返回到地图视图时,应用程序向 API 发送一个新请求并获取新的响应新闻标记。每次我导航回地图时,都需要更多时间来绘制标记这些是应用程序从开始 API 请求到标记完全绘制所花费的时间差:

第一次用时:7 秒

第二次用时:18 秒

第 3 次用时:30 秒

第 4 次用时:38 秒

第 5 次用时:49 秒

我试过task.suspend()task.cancel()session.invalidateAndCancel(),但结果还是一样。

如何解决这个计时问题?

func getData() {
    let urlString = URLFactory()
    DispatchQueue.global(qos: .background).async {
        // Set up the URL request
        guard let url = URL(string: urlString.getWebserviceURL()) else {
            NSLog("Log Error: cannot create URL")
            self.processData()
            return
        }
        let urlRequest = URLRequest(url: url)

        if self.task != nil {
            NSLog("Log suspend task")
            self.task!.suspend()
        }

        // make the request
        self.task = self.session.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in
            NSLog("Log start task")
            // check for any errors
            guard error == nil else {
                NSLog("Log error calling GET on webservice/getAllData: \(error!)")
                self.processData()
                return
            }
            // make sure we got data
            guard let responseData = data else {
                NSLog("Log Error: did not receive data")
                self.processData()
                return
            }
            // parse the result as JSON, since that's what the API provides
            do {
                guard let stringResponse = String(data: responseData, encoding: String.Encoding.utf8) else {
                    self.processData()
                    return
                }
                let json = JSON(parseJSON: stringResponse)
                if (json["data"].arrayObject != nil) {
                    self.parse(json: json)
                }
                self.processData()
            }
        })

        self.task!.resume()
    }
}

private func processData() {
    DispatchQueue.main.async {
        if(!self.newsObj.isEmpty) {
            self.drawMarker { () -> () in
                self.stopActivityIndicator()
                NSLog("Log Finished loading markers")
            }
        } else {
            self.showToast(message: "No data found")
        }
    }
}

private func parse(json: JSON) {
    newsObj.removeAll()
    for data in json["data"].arrayValue {
        // parse news data to newsObject
        newsObj.append(news)
    }
}

private func drawMarker(completion: (() -> ())) {
    if mapView != nil {
        mapView.clear()
        startActivityIndicator("Loading Markers...")
        for news in newsObj {
            let marker = GMSMarker()
            let listLatLng = news.getLatlong()
            for latlng in listLatLng {
                // Do stuff ...
                }
            }
            marker.map = self.mapView
        }
        completion()
    } 
}

除非 url 只是一个本地文件,否则您真的不应该使用此方法。您应该在 URLSession 中执行此操作,方法如下:

let task = URLSession().dataTask(with: URL.init(string: "")!, completionHandler: {data, response, error in
    if error != nil{
        print("Log \(error)")
        return //Stops the function
    }
    guard let data = data else{
        return
    }
    guard let stringResponse = String(data: data, encoding: String.Encoding.utf8) else{
        return
    }
    print("Log \(stringResponse)")
})

task.resume()

在上面的示例中,stringResponse 将数据保存为来自 URL 的字符串。

还要确保您使用的是 HTTPS,而不是 HTTP