0

I'm trying to get the size in Ko of an image which is placed in a remote server and check this to know if it is necessary to download it. I tried a lot of examples i found in this forum but nothing work for me with Xcode 8 and swift 4. First, i try to get the header like this:

func getHeader() {
    for (index, item) in imgUrlArray.enumerated() {
        let session = URLSession.shared
        session.dataTask(with: item) {
            (data, response, error)->Void in

            if let responseData = data {
                do {
                    let json =  try

                    JSONSerialization.jsonObject(with: responseData,
                        options: JSONSerialization.ReadingOptions.allowFragments)
                    print(json)
                } catch {
                    print("Could not serialize")
                }
            }
        }.resume()
    }
}

imgUrlArray is an array with remote URLs like: http://www.test.com/image.jpg

In this case data is nil. Where is my mistake?

David
  • 4,027
  • 10
  • 50
  • 102
jordy
  • 31
  • 4
  • Have a look to NSURLConnection : https://stackoverflow.com/questions/9328364/ios-get-files-metadata – CZ54 Jul 13 '18 at 09:59
  • I am working on MacOs and NSURLConnection does not work with me. I tried. If you have some example, it will be with pleasure . – jordy Jul 15 '18 at 10:17

2 Answers2

1

i have found this solution after few days of search:

    func getHeaderInformations (myUrl: URL, completion: @escaping (_ content: String?) -> ()) {

    var request = URLRequest(url: myUrl)
    request.httpMethod = "HEAD"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
    guard error == nil, let reponse = response as? HTTPURLResponse, let contentType = reponse.allHeaderFields["Content-Type"],let contentLength = reponse.allHeaderFields["Content-Length"]

        else{
            completion(nil)
            return
    }
        let content = String(describing: contentType) + "/" + String(describing: contentLength)

            completion(content)
    }
    task.resume()
}

Usage is like this:

getHeaderInformations(for: url, completion: { content in

print(content ?? 0)

})

I hope this answer could help someone.

jordy
  • 31
  • 4
0

You should use that code example of the HEAD request that you posted, but instead of using two functions and two web requests, make 1 function called getHeaders that returns request.allHeaderFields. Then you can make a method that calls getHeaders and if the Content-Length and Content-Type are what you expect, then perform a GET request to actually download the data.

This approach would be more efficient for the user and the server because they’d only do 1 HEAD request instead of 2.

Nate
  • 2,364
  • 1
  • 10
  • 16
  • Hi, it doesn't work. I can not find a parameter for .allHeaderFields to return the type and the length or all. Can you give me an example? – jordy Jul 18 '18 at 04:21