Why Apple suggests use your own NSFileManager when you use NSFileManagerDelegate? - ios

In apple docs of defaultManager they say:
This method always returns the same file manager object. If you plan to use a delegate with the file manager to receive notifications about the completion of file-based operations, you should create a new instance of NSFileManager (using the init method) rather than using the shared object.
I just want to know that why they suggest to use a new instance of NFileManager when you use a delegate of the file manager?What's wrong if I use the shared file manager to do this?
The only thing I can see is that your delegate object will receive a lot of notifications that you don't want to know, is anything else?

Your last paragraph is pretty much it. If you set the delegate on the shared file manager, your delegate ends up getting called way more than you want. By creating a specific instance of NSFileManager and setting that instance's delegate, then you know the delegate methods are only being called for that specific use of the file manager and not all of the default uses.
Keep in mind that the default file manager instance could be used by a lot more than your own code. Lots of other libraries and frameworks will be using it as well.

Related

What is best approach in iOS for message passing, NSNotification or Delegation?

I am new to iOS. I have come to know about these two approaches for message passing but I am unable to choose between them.
Conceptually, a delegate is a helper or an object that does part of the work for some other object that it can't do by itself. Frequently there will be a protocol involved and the object that has a reference to the delegate expects it to behave in a predefined way or, at least, in a way that's specific to the needs of the calling class.
Example: All the methods defined for a UITableViewDelegate are specific to table activity.
Notifications are more about state changes. The object sending the notification doesn't need help to do its work, it just lets other objects know about a change in case they want to react. If nothing else cares about the change, that's OK.
Example: An object that receives a UIApplicationDidBecomeActiveNotification may do whatever the developer needs at that time, not just things related to the UIApplication.
Delegate Patterns are mostly used because of delegate Object knows in which class delegate methods are implement. Delegate Object contains the references for object of that Class where you want to perform you task.
In Notification Patterns , simply a notification is broadcast over the entire classes and each class is search for the observer methods implementations So it took more time to search observer methods as compare to Delegate pattern.

Where is the correct place to make HTTP requests in iOS?

I have an app that fetches data from a server using NSURLSessionDataTask. As of right now I am starting my HTTP GET Request in the init method of the UIViewController that displays the data. Is this the best/smartest place to kick off an HTTP request? If not, where should I do it?
I'm asking this question because when I exit my app and it goes into the background (and is not killed) and then re-open my application, the HTTP request is not fired off (because it is in the UIViewControllers init method) and the data being displayed is not up to date with what's on the server. I've tried putting it in viewDidLoad but this method is not called upon entering the foreground, neither is viewWillAppear nor viewDidAppear.
Should I be doing all of my HTTP requests in one of the UIApplications life cycle methods in my appDelegate?
In short, where is the best place to make HTTP requests in iOS?
Thank you, I can post code or explain more if needed.
first off, this is a huge question and probably impossible to answer fully here, but hopefully I can point you in the right direction so you can learn how to fish. :)
To stick to the Model-View-Controller paradigm, you will want to create a separate object for making your HTTP requests. An HTTP request would be considered part of your model. The benefit of this is being able to use your model in other iOS apps you create, for example.
As for where to put all of this stuff and what's the best design.... One thing that strikes me in your question is you want the data being displayed in your app to be up to date with what is on the server. On a high level, a really good way to do this is to use iOS's ability to multitask and perform functions for you when you app is in the background. You would need to register with the OS as an app that performs fetches to a server in the background.
According to Apple's documentation, "In Xcode 5 and later, you declare the background modes your app supports from the Capabilities tab of your project settings. Enabling the Background Modes option adds the UIBackgroundModes key to your app’s Info.plist file." From there you would need to research the UIApplicationDelegate's protocol methods – application:performFetchWithCompletionHandler: and -application:handleEventsForBackgroundURLSession:completionHandler:.
Also, you will need to look into NSURLSession a little more. If you want to use background fetching, NSURLSessionDataTask is not supported. You will need to use NSURLSessionDownloadTask, save the response to a file and process it however you need to. Also, as the app delegate method name above implies, you will need to read the NSURLSessionConfiguration Class Reference, specifically about backgroundSessionConfiguration.
The really cool thing about all of this is, after you have implemented it, your app UI will be up to date for the user – even if your app was killed by the user or by the OS. Pretty nifty.
Good luck and hope this all helps. I hope I didn't miss any other big pieces here.
I think it a personal preference. So I personally do it on the model objects. Lets say I have a Car object and a ShowroomViewController. I always declare a class method to Car object to call service to get all the cars.
#interaface Car
+(void)fetchCarsWithCompletionHandler:(void (^)(NSArray* cars, NSError *error ))handler;
-(void)getDetailsWithCompletionHandler:(void (^)(Car* car, NSError *error ))handler;
#end
Then call the class method on viewWillAppear(If I need to update the cars very often) or viewDidload(If I need to call the service once).
The other trick I mostly do is define a flag in the view controller like
#interface ShowroomViewController
#property(assign)BOOL needsModelUpdate;
#end
and I update the modal conditionally.
#implementation ShowroomViewController
-(void)viewWillAppear:(BOOL)animated{
if(self.needsModelUpdate){
[self fetchModel]
}
}
-(void)fetchModel{
__block __weak ShowroomViewController *weakRef=self;
[Car fetchCarsWithCompletionHandler:^(NSArray *cars, NSError *error) {
[weakRef setCars:cars];
[weakRef.tableView reloadData];
}];
}
#end
The reason I define this flag is I can change it somewhere else lets say applicationDidEnterBackground: method the change the flag. Or you can use KVO but I always find it overkill .
Do it however you want.
Personally, I create a class specifically for all communication with the server. Actually, my App has around 20 classes for different parts of the communication process. But yours is probably less complicated.
Add an instance of the class as an object in an xib file or else create an instance of it inside the app delegate's init method.
Use didEnterForeground to tell the other class that it needs to do it's stuff, but still use the init method to create an instance of the class.

Registering setup code in objective-c

Is there a standard mechanism with Objective C and the iOS runtime to register setup code?
Why?
The advantage of this is that you can decouple your code nicely.
If a subsystem needs particular setup, the set up stays in that subsystem.
If a group of files need to register that they should all be offered as a particular service, that can be encapsulated in individual files that offer the service and there is no need for a separate configuration file to be kept up to date.
Getting the code to run isn't especially important – I can do that myself with various entry points. What I need is for the compiler or linker or run time or magic to be able to collect up anything that I've registered in different parts of a program, and let me have it when I need it.
How to in c++
With c++, I've typically arranged for this with static instances that are constructed before main() is called. I could use objective-c++, but I'd much prefer to use a standard mechanism.
Thanks.
I would look up:
+ (void)initialize
This method is called whenever a message is first sent to the class meta-object, such as, for example, when alloc-ing an object of that class.
Registering Code
Use the class method +(void) load for components that need to self register themselves.
Note that the load method is run on all subclasses and all categories. This is nothing like the the normal method calling behaviour.
Creating a Registry
If components need to register themselves in some kind of container, use the class method +(void) initialise to create a container to hold the components that are going to register themselves. It seems from my limited testing that initialize can be called before load when a load method uses a class with an initialize method, which is pretty cool if reliable.
Running Registered Code
If the components should do something at some specific entry point of your App, then at that entry point, grab the registered components from the registry and do that thing. Eg, you might extend you UIApplicationDelegate's -(BOOL) application:didFinishLaunchingWithOptions: to actually perform the setup stages the components registered.
In my case, I actually want the registered code to get run every time a specific kind of object is constructed, so I call the registered methods there and let them have the object being constructed.
More references on load and initialise
Thank you for the answers and comments that let me put this answer together.
Quite a lot of detail from Mike Ash, although I was initially put off by his statements about load being "tricky because it runs so early".
A very helpful S.O. question on load and initialize.

ios: dynamically loading functions on app delegate

Is it possible in IOS to dynamically load/create a function on a class at runtime?
I'm specifically thinking for example of adding a class the the app delegate at runtime, but I'm not sure it is even possible in the language?
For instance, this is used for push notifications, but could it be added dynamically by a Push framework behind the scenes at runtime?
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
....
}
As an alternative, could it simply be defined in the framework, outside the app delegate file, but still a part of the app delegate logic?
Both are options.
Dynamically adding methods, is via a C function called class_addMethod. You can even change an existing method (and still use the original!), it's called method swizzling. You can read the Apple documentation, or google for other examples. Note that you will need something in the program to at least touch your library to get it loaded (if you put the swizzling in your class's +initialize method), and it's probably easiest overall to just have the user initialize your library with something along the lines of [MYLibrary applicationLaunchedWithDelegate:self launchOptions:launchOptions].
If you know the class you need to add the method to, you can use a category.
you can put your self as app delegate and bypass all received delegates to old one for backward compatibility.here is a pseudo code.
1)by default we have this wiring:
ios -> appdelegate.m
now you need to put your self in the middle like :
ios -> framework -> appdelegate.m
2)so you can do it by set old delegate to another variable like:
(in your framework delegate)
self.oldDelegate = [UIApplication sharedApplication].delegate;
and set yourself as application delegate:
[[UIApplication sharedApplication] setDelagate:self];
3)for backward compatibility you need to bypass all delegates to oldDeleagete
4)warning:this is pseudo code to give you the idea but remember you need to take care of multi threading of your app may be there is another framework like you and both are changing app delegates but will get wrong oldDelegate and your wiring will not work .so pay more attention to these kind of stuffs.look at this

Asynchronous download of multiple images

I am new to ios app development.could you please tell me how to download two or more images asynchronously using NSURLconnection. I can do it for one one image but seeks some help to do it for two or more images.
To do this I usually have a helper class which downloads an image given a URL that calls me back when it's done. I've actually released that code as part of my MJGFoundation project. Take a look at the class called MJGImageLoader.
Essentially it's very straight forward and what I do is wrap all the NSURLConnection handling into a single class which you then start by passing a block which will be run on completion. I suggest you either take my code there and use it or look at how I've done it and replicate it yourself according to your needs.
create a separate class lets say - ConnectionManager having NSURLconnection complete implementation. create a protocol in the same class.
in the controller, make object of ConnectionManager pass delegate as self and start downloading one file. on completion, ConnectionManager can trigger your delegate and can deliver you the downloaded data.
to download multiple files simultaneously, you need to make multiple objects of ConnectionManager and start your requests. With that you will also require to handle the delegate as to recognize, which request is triggering your delegate.
hope it'll help somewhat.

Resources