URLSession cache only - swift

Sometimes I want to get data from the cache only when using URLSession. For example when quickly scrolling in a UITableView, I would like to show images that are already in the cache, but do not fire any HTTP requests. Images are just an example could be anything.
So I'm currently looking into URLSession's CachePolicy but it doesn't support an option to only get valid (not expired, etc) data from cache.
I can look into the URLCache myself, but this also of course returns data that might be expired. Is there some API that can validate a CachedURLResponse? Because then I can do it myself. Or do I have to implement the validating myself.

That's a fairly unusual request. Normally, you're either writing code to operate in an offline mode (in which case you want to pull from the cache whether the cached results are still valid or not) or you are online (in which case you want to fetch new data if it isn't valid).
I would encourage you to really think long and hard about whether you really want to force cache validation if you aren't firing network requests.
That said, if you really want that behavior, there are two ways you can do it:
Use NSURLRequestReturnCacheDataDontLoad and validate the age of the cached response yourself.
Perform the request in a custom session, use NSURLRequestUseProtocolCachePolicy, and in that session, install a custom NSURLProtocol subclass that overrides initWithTask:cachedResponse:client: and startLoading, and calls URLProtocol:didFailWithError: on the provided client at the top of its startLoading method.
The second approach is probably the best option, because you don't have to worry about knowing all the esoteric rules for cache validation. By making the actual load fail, the cache will work normally, but as soon as it actually would start making a network request, your custom protocol prevents that from happening. And because you'll register the protocol only in that specific session (via the protocolClasses array on the session configuration), it won't break networking in other sessions.

Related

Ability to fail macOS endpoint extension from within the extension process

I'd like to protect against unauthorised system extension teardown that are triggered by
the container application following this command:
self.deactivationRequest =
OSSystemExtensionRequest.deactivationRequest(
forExtensionWithIdentifier: extensionIdentifier, queue: .main)
self.deactivationRequest!.delegate = self
OSSystemExtensionManager.shared.submitRequest(self.deactivationRequest!)
Is there a callback in the endpoint extension code, that can be invoked upon this deactivation request, and may block/allow it ?
thanks
There is no public API to control the system extension deactivation with EndpointSecurity or inside sysext itself (activation and deactivation management, I think, is a job for some daemon, like sysextd).
I could advice to try two approaches for your case:
You may still be able to deny deactivation with EndpointSecurity, just not in direct way. To deactivate sysext the responsible processes would do a lot of stuff, including opening some specific files, reading them, etc. In case you are lucky, you may be able to fail the deactivation process by blocking one of such operations before it really deativated. However, the context of operation (how do you know the target is your extension) may vary and be less than you need.
You may intercept the OSSystemExtensionManager.shared.submitRequest call inside your application, and add some condition to really call original method from interception method. The interception for submitRequest will be a swizzling.
Or you can place an old good hook on something deeper, like xpc_* stuff, and filter your deactivation request by some unique string from request, also calling original method only on some condition.
Both ways are not bulletproof from perspective of tampering protection ofc, but nothing really is, we just requesting additional efforts from hacker.
If you haven't disabled library validation for your app, there are two ways of tampering it: either turning SIP off, or using some 0-day system breach.
You can't really protect your app from such treats: 0-days are new, you don't know what it may be, and with SIP off the one may unload/disable/alter all possible kinds of protection stuff.

Global exception handling for REST calls in Ember-CLI

In my ember-cli app I use a token based approach to communicate with a secured REST interface on the server side. As tokens expire after some time, I would like to realize the following behaviour:
As soon as the client tries to access the REST service with an expired token, I would like the user to be redirected to the login screen.
Right now I use the 'catch' function on the store's find method while fetching data in the route's model callback. This works quite well. As a matter of fact, there are more REST invocations than the ones that refer to the model store.
What would be the best practice to deal with this situation? In what place should I implement the (exception) handling? As this seems to be a crosscutting concern, I'd like to implement it in a central place.
I prefer to follow an optimistic approach, thus not checking the validity of the token on each and every transition. It will be sufficient if the redirect will take place the moment the application tries to communicate with the REST interface (ie as soon as it gets the error message from the server).
Thanks
You may want to consider the global jquery hooks so you can respond to an Auth fail uniformly. See:
http://api.jquery.com/category/ajax/global-ajax-event-handlers/
It's up to you if you want to set window.location or lookup your application controller and use transitionToRoute() for switching to the login route. Make sure that if you use Ember functions to put your code in an Ember.run.once() from your jquery hook function so it occurs on the Ember run loop.
You could also consider using Ember SimpleAuth (which kind of locks you into its paradigm) or even better and a safer long term priposal IMO, doing it from scratch by first following these tutorials:
- http://coderberry.me/blog/2013/07/08/authentication-with-emberjs-part-1/
- http://coderberry.me/blog/2013/07/08/authentication-with-emberjs-part-2/
And then this which is newer and incorporates the above tutorials:
- http://webcloud.info/blog/2014/04/07/emberjs-authentication-the-right-way-javascript-version/

Backbone sync request sequence

I've got a Backbone web application that talks to a RESTful PHP server. For PUT and POST it matters in which order the requests arrive at the server and for GET it matters in which order the responses arrive at the client.
The web application does not need to be used concurrently by multiple users, but what might happen is that the user changes its name twice really fast. Then the order in which the server processes PUT /name/Ann and PUT /name/Bea determines whether the name is set to Ann or Bea.
Backbone.Safesync and Backbone.Sync.AjaxQueue are two libraries that try to solve this problem. Doesn't Safesync only solve the problem with GET? Sync.AjaxQueue is outdated, but might serve as inspiration to implement a custom queued sync function. Making sync synchronous would solve the problem. If a request is only sent after the previous response is received, then only one request is processed at a time.
Any advice on how to proceed?
BTW: I don't think using PATCH requests would solve anything, because in my example the same attribute is changed twice.
There's a few ways to solve this, here's two:
add a timestamp to all requests, store it in the DB as "modified" and let the server check whether the timestamp of the new request is later than the one in the DB in order to be valid
use Promises to delay the second request from being made before the first one is responded on, there's a promise/deferred mechanism built into jquery, but you can also use a 3rd party one, for instance Q or when
If you can afford the delay, an easy approach is to set the async option to false when you call whatever method you're calling that results in the Backbone.sync. For example, in the appropriate model(s) simply override the default sync method to include the additional option.

Multiple request with AFNetworking

I'm trying to do multiple request in background to download many jsons and check data from them but I don't know how to use AFNetworking in that case.
I tried to do like Wiki explaings but when it's going to download the second file then the app breaks. I want to do all the process in background.
Thanks
AFNetworking will definitely handle this. We use it for exchanging data with a RESTful set of services. The things to keep in mind:
An operation (eg. AFHTTPRequestOperation) can only be used once.
An operation is asynchronous.
Put your operations in an NSOperationQueue, or use AFHTTPClient (suggested) to manage the operations for you.
When sending multiple requests, always assume that the responses will come back in a random sequence. There is no guarantee that you will get the responses in the same sequence as the requests.
Hope this helps to point you towards a solution to your problem. Without more detail in your question, it's difficult to give you a specific answer.
Check out AFHTTPClient's
enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:, which lets you enqueue multiple requests operations at once with the added bonus of having a completion handler that is called when all of those requests have finished, as well as a block for tracking the progress. Also note, that every single operation can still have its own completion handler (useful if you have to process the results of a request, for example).
If you don't need to customize the request operation (and don't need individual completion blocks), you can also use enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:, which allows you to pass an array of NSURLRequest directly without having to build the operations yourself.

How to determine if NSURLConnection:sendSynchronousRequest is returning cached data or not

Wanted to know, because side effect of this could be to alert user that new data was available if didn't get cached data. Bad idea? Was hoping not to have to compute checksum on data and store that for later comparison purposes (although I might be able to use the http response's "last-modified" date instead of a checksum).
The NSURLConnectionDelegate protocol has a connection:willCacheResponse: method. This method is invoked when a NSURLConnection receives and subsequently caches a response. It therefore provides you with a hook in which you could set a flag indicating that a cache is in use. Alternatively if you want to disable caching altogether you can return nil from your implementation.
A point worth noting is that if your delegate manages multiple NSURLConnections you will need to determine which one was the source of the response using the connection: parameter.