ios - NSURLSession URL Response is not cached when larger than a few kilobytes -
ios - NSURLSession URL Response is not cached when larger than a few kilobytes -
i pretty new programming in ios cocoa , using swift. fetch info json api using nsurlsession info session custom delegate, not closures. reason using custom delegate have basic authentication , inject custom cache-control header command caching behavior (my api doesn’t include caching related headers in response @ all).
all works requests urlsession:datatask:didreceivedata: method called once. larger responses (some 20-30kbytes) phone call didreceiveddata method several times, urlsession:datatask:willcacheresponse:completionhandler: method doesn’t called @ all, , hence response doesn’t cached. re-issuing same request within 5 minutes issue request server again, doesn’t happen requests responses phone call didreceivedata 1 single time. urlsession:task:didcompletewitherror: method correctly called , proceeded in cases.
the documentation of urlsession:datatask:willcacheresponse:completionhandler: method (https://developer.apple.com/library/ios/documentation/foundation/reference/nsurlsessiondatadelegate_protocol/index.html#//apple_ref/occ/intfm/nsurlsessiondatadelegate/urlsession:datatask:willcacheresponse:completionhandler:) says method called if nsurlprotocol handling request decides so, don’t understand create happen.
any feedback , ideas welcome!
this code issues http request:
allow config = nsurlsessionconfiguration.defaultsessionconfiguration() config.urlcache = nsurlcache.sharedurlcache() //config.urlcache = nsurlcache(memorycapacity: 512000000, diskcapacity: 1000000000, diskpath: "urlcache") allow urlstring = apiurlforfilter(filter, withmode: mode, withlimit: limit, withoffset: offset) allow url = nsurl(string: urlstring) var policy: nsurlrequestcachepolicy? if ignorecache == true { policy = .reloadignoringlocalcachedata } else { policy = .useprotocolcachepolicy } allow request = nsurlrequest(url: url!, cachepolicy: policy!, timeoutinterval: 20) allow session = nsurlsession(configuration: config, delegate: self, delegatequeue: nil) allow task = session.datataskwithrequest(request) task.resume()
i have next delegate functions implemented:
urlsession:didreceivechallenge:completionhandler: handle ssl certificate trust, urlsession:task:didreceivechallenge:completionhandler: handle basic authentication urlsession:datatask:didreceiveresponse:completionhandler: read specific headers , save them instance variablesadditionally, of import ones code:
urlsession:datatask:didreceivedata: accumulate info arrives larger http request responses:
func urlsession(session: nsurlsession, datatask: nsurlsessiondatatask, didreceivedata data: nsdata) { if receiveddata == nil { receiveddata = nsmutabledata() } receiveddata!.appenddata(data) println("did receive data: \(receiveddata!.length) bytes") }
urlsession:datatask:willcacheresponse:completionhandler: inject own cache-control header:
func urlsession(session: nsurlsession, datatask: nsurlsessiondatatask, willcacheresponse proposedresponse: nscachedurlresponse, completionhandler: (nscachedurlresponse!) -> void) { println("willcacheresponse called") allow response: nsurlresponse = proposedresponse.response allow httpresponse = response nshttpurlresponse var headers = httpresponse.allheaderfields var modifiedheaders = headers modifiedheaders.updatevalue("max-age=300", forkey: "cache-control") allow modifiedresponse = nshttpurlresponse(url: httpresponse.url!, statuscode: httpresponse.statuscode, httpversion: "http/1.1", headerfields: modifiedheaders) allow cachedresponse = nscachedurlresponse(response: modifiedresponse!, data: proposedresponse.data, userinfo: proposedresponse.userinfo, storagepolicy: proposedresponse.storagepolicy) completionhandler(cachedresponse) }
urlsession:task:didcompletewitherror: check finish response errors , phone call callback closure class gets initialization farther proceed result data:
func urlsession(session: nsurlsession, task: nsurlsessiontask, didcompletewitherror error: nserror?) { session.finishtasksandinvalidate() if error != nil { var string: string? if errorstring != nil { string = errorstring } else { string = helpers.nsurlerrordomainerrorforcode(error!.code) } errorcallback(string!) homecoming } if receiveddata == nil { errorcallback("the query returned empty result") homecoming } var jsonerror: nserror? allow results: anyobject! = nsjsonserialization.jsonobjectwithdata(receiveddata!, options: nsjsonreadingoptions.allowfragments, error: nil) if results == nil { errorcallback("the info returned not valid json") homecoming } allow jsonparsed = jsonvalue.fromobject(results) if allow parsedapierror = jsonparsed!["error"]?.string { errorcallback("api error: \(parsedapierror)") homecoming } callback(jsonparsed!, self.servertime!) }
ios cocoa swift nsurlsession
Comments
Post a Comment