Can we set a custom delegate object for NSURLSessionTaskDelegate - nsurlsession

In NSURLSession, we add tasks to a session by methods like
dataTaskWithRequest:
dataTaskWithRequest:completionHandler:
As far as I understand, if we use the one without completionHandler or use nil for completionHandler, self will be used automatically as the delegate and we can expect delegate methods to be called. Do I understand correctly?
Is there possible to specify different delegate (other than self ) for each task?
I checked sessionWithConfiguration:delegate:delegateQueue and I think that delegate is a NSURLSessionDelegate.

Answer my own question. We actually can use sessionWithConfiguration:delegate:delegateQueue to setup delegate. According to apple's URL Loading System Programming Guide,
if you need to handle authentication or caching in a nondefault
manner, you must provide a delegate that conforms to the session
delegate protocol, one or more task delegate protocols, or some
combination of these protocols. This delegate serves many purposes

Related

Prism IDisposable Autofac and Lifetime Scope

I am using Prism to navigate between views in my WPF application. One view in particular I've implemented with the IRegionMemberLifetime.KeepAlive => returns false; to create a new instance of the view every time we navigate to the view (we need to do this for display reasons). This view also hosts a custom win32 control that I need to do some cleanup in using IDisposable.Dispose. When I navigate to my view and then away from it, I'd expect Dispose to get called (to run cleanup). I was able to achieve this by implementing a custom region behavior as discussed here, https://github.com/PrismLibrary/Prism/issues/7. All this is working fine except everything gets marked for disposal but the GC doesn't actually get rid of anything. I'm using Autofac as my IOC container and after doing some research I've concluded the reason comes down to Autofac and lifetime scopes of IDisposables, https://nblumhardt.com/2011/01/an-autofac-lifetime-primer/. Basically Autofac holds references to the IDisposable and the GC won't get rid of the old view because of this. For instance I'm registering my view in the Module as _container.RegisterTypeForNavigation(); I'm not able to register this with any sort of lifetime and I'm not sure how I'd resolve this with a lifetime specified? When I call RegionManager.RequestNavigate I don't see any sort of overloads to specify lifetime? Any ideas would be appreciated.
RegisterTypeForNavigation essentially does builder.RegisterType(type).Named<object>(name); which you can do yourself, too, of course and apply any lifetime you desire. There's no magic in registering for navigation, RegisterTypeForNavigation is just a shorthand.
To make Autofac ignore the IDisposables, one can write
builder.RegisterType<SomeView>().Named<object>(typeof(SomeView).Name).ExternallyOwned();
From the docs:
Disabling Disposal
Components are owned by the container by default and will be disposed by it when appropriate. To disable this, register a component as having external ownership:
builder.RegisterType<SomeComponent>().ExternallyOwned();
The container will never call Dispose() on an object registered with external ownership. It is up to you to dispose of components registered in this fashion.
So extending #Haukinger answer. This is what finally worked for me:
//builder.RegisterTypeForNavigation<SomeView>();
builder.RegisterType<SomeView>().Named<object>
(typeof(SomeView).Name).ExternallyOwned();
That ExternallyOwned() signals to autofac that the user is going to handle calling dispose and that autofac shouldn't track the IDisposable.

How feasible is to use other delegates in app delegate file in iOS 4.2?

How feasible is it to use other delegates in app delegate file .
e.g.
#interface AppDelegate : UIResponder <UIApplicationDelegate, UIAlertViewDelegate>{
BOOL LoadingForFirstTime;
}
Is this recommended?
In short, Yes it is feasible, No it is not recommended.
Typically the AppDelegate should handle system notifications, core data setup and not a whole lot more. Check out Table 2.1 here:
Apple Docs
I am guessing, from the BOOL you are defining, that you are checking if this is the first load. This might work, but it isn't recommended practice.

Sharing code between NSDocument and UIDocument

I have created a document-based app that uses Core Data. I created the mac version first, and now that it's working properly, I am moving on to create an iOS version of it.
I just can't get my head around how to maximize code reuse between the iOS/mac versions, with respect to the Core data bit, since they don't use the same classes.
My document class that handles saving and such is a subclass of NSPersistentDocument. My intention is that a well-designed model class should work in both environments, especially since I don't do all that much fancy stuff with regards to Core data.
Now, since NSPersistentDocument isn't available in iOS, I hit a wall. I tried to get around this by using #if TARGET_OS_MAC and TARGET_OS_IPHONE and in that manner make it a subclass of UIManagedDocument in the iOS version. That obviously would have been convenient, but I can't seem to make it work like that. And it's really looks quite messy, since there are a lot of other stuff that has to be conditionalized as well.
I also tried building the classes atop of NSDocument/UIDocument instead, implementing the Core data hooks myself, but it also looks quite messy, leaving me thinking it's not the right way to go.
The question:
To me, it seems like a good idea to reuse the same document class between the iOS/mac versions, but maybe I'm being naive.
What's the best way to do this?
Should I forget about the code sharing and create a separate document class for the iOS version that emulates all the methods present in the mac version?
Am I right that the code you're wanting to share is model-related? I suggest refactoring that code to a separate object, which both an NSDocument and UIDocument contain (as rickster suggested above).
I use a DocumentRoot Core Data entity with its own NSManagedObject subclass, but if there are no properties you want to manage using Core Data, you can just subclass NSObject.
This may sound strange, but NSDocument and UIDocument are actually controller classes. (To be specific, they're part of the model-controller.) Their jobs are to load the model, set up windows, and save the model. If you need to provide an interface for higher-level access to model objects, it could be in a document root or model helper class instead.
Similarly NSPersistentDocument's job is to configure the managed object context and the persistent store and handle loading and saving. It doesn't necessarily need to provide a complete interface for accessing the model.
(Bringing this over from my comment.)
In general, the situation where you have two classes which must inherit from different superclasses but which also want to share a lot of code is composition. Put the shared code in a separate class; your NSDocument and UIDocument subclasses can each keep an instance of that class, and message it whenever they need to invoke that shared code. (Though as #noa mentions, you might want to consider whether all of that code belongs in your document class to begin with.)
Of course, then you might end up writing a bunch of methods that read like:
- (id)doSomething {
return [sharedController doSomething]
}
That can get to be a pain... so you might want to look into Objective-C's message forwarding system.

NSURLConnection methods no more available in IOS5

I was looking at the NSURLConnection class which could be used to establish a sync or async connection to an URL and then retrieve its data... a lot of changes have been made to this class with IOS 5 and I've seen they introduced some formal protocols related to authentication or download, but I don't see, for example, if the connection:didReceiveResponse: message (that was previously sent to the delegate and that it is no more available) is still available in some protocols.. How do you implement an async connection and retrieve, for example, HTTP headers as soon as the Response is received? I'm sure there is a way better than using NSURLConnection along with the connection:didReceiveResponse: message.. methods like stringWithContentsOfURL do always load content synchronously? What do you use to implement async downloads in your apps avoiding deprecated methods and reacting to events such as _http response received_m etc ? Do you launch synchronous downloads in background tasks, if possible?
NSURLConnectionDelegate has become a formal protocol (it was an informal protocol in previous versions). In this protocol, the following (non-deprecated) methods are declared:
connection:didFailWithError:
connectionShouldUseCredentialStorage:
connection:willSendRequestForAuthenticationChallenge:
Furthermore, there are two subprotocols that conform to NSURLConnectionDelegate:
NSURLConnectionDataDelegate is used for delegates that load data to memory, and declares the following methods, some of which I’m sure you’ll find familiar:
connection:willSendRequest:redirectResponse:
connection:didReceiveResponse:
connection:didReceiveData:
connection:needNewBodyStream:
connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:
connection:willCacheResponse:
connectionDidFinishLoading:
NSURLConnectionDownloadDelegate is used for delegates that store data directly to a disk file, and declares the following methods:
connection:didWriteData:totalBytesWritten:expectedTotalBytes:
connectionDidResumeDownloading:totalBytesWritten:expectedTotalBytes:
connectionDidFinishDownloading:destinationURL:
As you can see, you can still use your previous delegates, possibly with some minor modifications.
For more information, see the iOS 4.3 to iOS 5.0 API Differences document and NSURLConnection.h in your local Xcode installation. When a new SDK version is released, it’s not uncommon for the documentation inside the header files to be more reliable than the documentation available on the developer library. It takes a while for the latter to be up-to-date.
I just encountered this same issue. Looks like sending an asynchronous request is more simplified with blocks and NSOperationQueue.
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
This means that the delegate is now only used for authentication and failure issues.
NO!
They are NOT limited to use for authentication and failure issues if you look carefully through the Apple's library.
Since introducing +(void)sendAsynchronousRequest:queue:completionHandler: to NSConnection class object, Many things which can perform as many NSConnectionDelegate method as before can now be used in formal protocols called "NSConnectionDataDelegate" & NSConnectionDownloadDelegate, opening a new room to add more feature to NSURLConnection methods. (from iOS5 on)
So I think it is an improvement, not limiting their use.
Even I havent found the documentation on the Apple website
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html
https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/Reference/Reference.html
It should have been available over here

Loading data into a Cocoa view before the application loads

I want to load some data from mysql into my cocoa application view before the application starts.
I am sure that this should happen in the controller so that it can send the required data to the view.
I am looking for a method or common technique that is used for this sort of thing.
Many Thanks
Sounds like you're looking for the awakeFromNib function.
http://www.cocoadev.com/index.pl?AwakeFromNib
Cocoa gives you many places to perform tasks before and after objects are loaded from a nib, but it's important to read the documentation carefully to make sure things are happening in the order you expect. Usually I use the following strategy when I'm working on a Cocoa application:
Where appropriate I implement the
+(void)initialize method, which is called before any instances of a class are created. I'll probably set the app's default preferences here, for example.
In my application controller (app delegate), I implement the applicationDidFinishLaunching: delegate method to load my data file. If this works okay, I then create the window controller(s) and display any windows I want to show at launch.
In the window/view controllers, I override windowDidLoad: or loadView to perform tasks involving objects loaded from a nib. If I need to create any instance variables that don't involve the nib, I also override the init method and do that there.
If I need to do anything in my view objects after they're loaded from a nib, I'll override awakeFromNib.
You can use the - applicationDidFinishLaunching: or - applicationWillFinishLaunching: delegate messages, by implementing one of them in your application delegate/controller, and do whatever initialization you want there.

Resources