Iphone connecting to a web server, design issues/questions - ios

Currently I am working on building an iOS app that asynchronously connects to a web server. I make about 5 different calls to the web service, depending on which view controller I am in. On a lot of the views, I end up making the same calls, so I have a lot of identical/similar code. Do you guys have any suggestions on how I can limit the amount of code reuse I am making. I was thinking about creating a special class that has the method/code for all these asynchronous calls, then on each View controller, I can just instantiate the special class and invoke whatever methods I want. The problem with this is that since I am making asynchronous calls, how will I know which view controller to send the data back to (via a callback). I know there should be a simple, elegant way to achieve this but I am just new to this way of thinking so help would be greatly appreciated.

Usually what I do is a class that is responsible for the requests (or part of them depending on the amount of requests you have and how they are logically related).
Imagine that you have a NetworkManager. In this manager you can have a singleton if you need to persist state or just use class methods. All methods should have at least a completion block that will be called when the async method that you use for your server has the response.
The block can be defined with a typedef:
typedef void (^NetworkCompletionBlock)(NSError *error, NSArray* data);
Then you call methods like this:
+(void) requestInfoFromServerOnCompletion:(NetworkCompletionBlock)onComplete;
Then, on your method, you call your async functions and when they are complete you call the onComplete block with the parameters he requests, like this:
if(onComplete)
onComplete(yourError, yourDataArray);
To call this class method just do:
[NetworkManagerrequestInfoFromServerOnCompletion:^(NSError *error, NSArray* data)){
if(error)
NSLog(#"Ops, an error ocurred");
else
NSLog(#"Received data: %#", data);
}];
You can also have two blocks, one for error and one for completion.
Depending on how you are doing your requests you might need to save the block in the NetworkManager. Imagine that you use a NSURLConnection with delegates. You had to save your block in a networkManager singleton and then call it when the request is complete.
To do this you need to declare a property on your singleton:
#property (nonatomic, copy) NetworkCompletionBlock onRequestCompletedBlock;
And then on your method you do:
self.onRequestCompletedBlock = onComplete;
When the request is completed you can call with:
self.onRequestCompletedBlock(requestError, requestDataArray);
Note that if you do this you need to be careful with retain cycles.

Related

Closures in Swift, blocks in Objective-C: their usefulness and when to use

I've found an Objective-C SocketIO library and am trying to implement it in my first Swift app. Here's the code I'm trying to port:
__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^()
{
weakSelf.socketIsConnected = YES;
[weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
};
From my limited understanding ^() {} is a block in Objective C. I've looked into it and closures seem to be a loose equivalent Swift. My first obvious question is how do I get the same result in Swift?
I've tried the following but get the error fatal error: unexpectedly found nil while unwrapping an Optional value (lldb):
self.socket.onConnect = { () -> Void in
println("Connected!")
}
Also, behind the scenes what's happening here? An asynchronous callback function would seem appropriate but wasn't used and I'd like to understand why.
UPDATE
As pointed out by #jtbandes, socket was in fact Nil as this code was running outside of the connection callback (I know, a very silly mistake). Solution to first question:
SIOSocket.socketWithHost(server) { (socket: SIOSocket!) in
self.socket = socket
self.socket.onConnect = { () -> Void in
println("Connected!")
}
}
Objective-C blocks and Swift closures are more than loose equivalents. They are direct equivalents.
A block/closure is an anonymous function that inherits it's enclosing scope.
I'm still working in Objective-C, so I'm used to its terminology. I'll use those terms
Blocks are useful in lots of ways.
Completion code is one example.
Without blocks, if you're setting up an async networking class, you might give it a delegate property, and define a protocol with callbacks that the class uses to notify it's delegate about events like download complete, errors, etc.
This makes for a lot of message handling infrastructure in lots of different places. You have to define a protocol. You have to add a delegate property to the networking class. You have to implement a set of delegate messages in the client class. You may have to pass context information to the callbacks, etc.
With blocks, you invoke a method that asks for a networking service, and provide a completion block. When the service is complete, it invokes the provided code block. You might add parameters to the completion block like a pointer to the data, a success boolean, or whatever is appropriate. The code block can have access to all the variables defined in its enclosing scope, which can be very helpful.
You can also save blocks into collections, you can use blocks in sort methods, and int lots of other cases.
The code you posted simply sets a block property on the object in question, self.socket. It looks like it is a block of code that gets called after a socket connection is established.
There are direct equivalents to this in Swift. I've only poked around in Swift however, so I'll leave it to others to help you with the translation.
I suggest browsing through Apple's classes for ideas on how to use blocks. Take a look at NSURLConnection and NSURLSession if you're interested in async networking. Take a look at the block-based view animation methods that take an animation block and a completion block. Those will give you an idea of the ways you can use blocks for handling async events, or passing code to a class to get work done.
Another interesting use of blocks is in handling collections like arrays. There are methods that take an NSComparator block and sort an array, and there are methods that will enumerate through an array, performing a block of code on each element and/or selecting a subset of the elements and returning an index set of the array indexes.
Duncan

Preferable design pattern for model with background networking

I'm developing a model class that provides data parsed from the web. Of course, I'd like my application to be responsive and thus networking should be done on separate thread/queue.
That leads to the question: how should I design the #interface of my class?
The main requirements are:
It should deliver data from Model to Viewcontroller :) ;
It shouldn't block the main (UI) thread;
It should be easy to understand and follow by other developers.
From what I've learned from WWDC2012 video, "Building Concurrent User Interfaces on iOS" Apple recommends to move the concurrent code to the class itself that uses model.
Let's say we have Posts class (Posts.h/.m) that should provide ViewController with latest posts in NSArray* format.
Option I -- concurrency is in class users
The class itself is not concurrent, but the users are:
//Posts.h:
#interface Posts : NSObject
- (NSArray*)getPostsForUser:(NSString*)user;
#end
//ViewController.m
#implementation ViewController
- (void)someFunctionThatUpdatesUI
{
//<...>
NSOperationQueue *q = [[NSOperationQueue alloc] init];
[q addOperationWithBlock:^{
NSArray *currentPosts = [Posts shared] getPostsForUser:#"mike";
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//UI should be updated only on main thread
[self updateUIWithPosts:currentPosts];
}];
}];
//<...>
}
The main disadvantage of this approach is the necessity to repeat almost the same code in every ViewController. What if there are dozens of them?
Option II -- concurrency with completion handlers pattern
Second option that I currently use in my app is a completion handler pattern. As the completion handler is called only after some long networking is performed, it doesn't block the main thread:
//Posts.h:
#interface Posts : NSObject
- (NSError*)getPostsForUser:(NSString*)user
withCompletionHandler:(void(^)(NSArray*))handler;
#end
#implementation Posts
- (NSError*)getPostsForUser:(NSString*)user
withCompletionHandler:(void(^)(NSArray*))handler
{
//<...>
dispatch_async(dipatch_get_global_queue(0, 0), ^{
//Do some may-be-long networking stuff here,
//parse, etc and put it into NSArray *result
dispatch_async(dipatch_get_main_queue(), ^{
handler(result);
});
});
//<...>
}
//ViewController.m
- (void)someFunctionThatUpdatesUI
{
//<...>
[Posts shared] getPostsForUser:#"mike"
withCompletionHandler:^(NSArray* posts){
//updateUI with posts
}];
}
From my point of view, this way is good but the #interface is rather complicated, the method names are long and (from my point of view) obfuscated.
Option III -- delegate pattern
Another option that I see is the delegate pattern. What bothers me is that only one ViewController may be the delegate, thus it leads to necessity to set every VC as delegate in - viewWillAppear, which is easy to forget.
//Posts.h:
#protocol PostUpdate<NSObject>
- (void)updateUIWithPosts:(NSArray*)posts FromUser:(NSString*)user;
#end
#interface Posts
- (NSError*)updatePostsFromUser:(NSString*)user;
#property(nonatomic, weak) id<PostUpdate> delegate;
#end
//ViewController.m:
#implementation ViewController<PostUpdate>
- (void)viewWillAppear
{
//<...>
[Posts shared].delegate = self;
}
- (IBAction)getLatestsPostButtonPressed:(id)sender
{
[[Posts shared] updatePostsFromUser:#"mike"];
}
// protocol PostUpdate
- (void)updateUIWithPosts:(NSArray*)posts FromUser:(NSString*)user
{
//updating UI with posts
}
#end
So here are the questions:
What else patterns fit the requirements to deliver data from Model to Controllers in non-blocking way?
What option would you recommend based on your experience, practise or theoretical knowledge?
Short answer
I recommend going with option-II as it's the most suitable solution in your case.
Long answer
First of all, none of the three solutions is wrong, but we are only trying to figure out the best one among them for your case.
• The problem with option-I is that it's always synchronous and will block the calling thread while you need it to be asynchronous, and therefore, you'll find yourself always calling it from a background thread which means there will be a lot of repeated code that will make maintenance harder (This option can be a good solution if you need the method to be asynchronous sometimes and synchronous most of the time).
• The option-II solves the problem by providing a way to notify the caller thread when the data is ready, and the added parameter isn't really a disadvantage compared to the easiness of use and flexibility it gives. And if you think you will not really need the added parameter in some cases, you can simply make another synchronous version of the method without that parameter:
- (NSArray *)fetchPostsForUser:(NSString*)user; /// Synchronous
- (void)fetchPostsForUser:(NSString*)user /// Asynchronous
completion:(CompletionHandler)completion;
CompletionHandler is defined as following:
typedef void (^CompletionHandler)(NSArray *result, NSError *error);
• The third option isn't really a good solution for your problem. Delegates should be used to deliver events about the class itself, not to deliver responses to previously called methods. Also, notice than you can only have one delegate and this means you can't call such method from two different controllers at the same time.
Option 1 is bad for the reason you mention.
Option 3 is bad because you may have network data returned in a different order than requested if you have 2 network requests going at the same time. This may make it more difficult than necessary to update your UI properly, depending on your data. (For example, items could appear out of order.)
Option 2 seems ideal. It has the benefits of Option 3, plus you get the scope-capturing benefit of Objective-C blocks. You may want to look at the networking library AFNetworking, which approximately follows this pattern. One additional consideration is that you should keep your data networking & serialization in a separate class from data persistence / processing. For example, one class should download data, turn it into an array of Post objects, and send it to the callback block. That callback block could be a view controller, or it could be a separate class that caches the data to disk (using NSCoder or Core Data, for example.) This approach will keep your code as flexible as possible.

How keep things DRY with afnetworking

I'm writing a ios app which has to send and receive data from the API at various screens in the app. Currently each view controller is calling this code
// AFAppDotNetAPIClient is a subclass of AFHTTPClient, which defines the base URL and default HTTP headers for NSURLRequests it creates
[[AFAppDotNetAPIClient sharedClient] getPath:#"stream/0/posts/stream/global" parameters:nil success:^(AFHTTPRequestOperation *operation, id JSON) {
NSLog(#"App.net Global Stream: %#", JSON);
} failure:nil];
I want to keep things DRY and so I created a requested builder and response handler to create request and parse responses. I also want to move all the API calls to one class but since it uses blocks I don't know how do this.
Can someone explain how this is done so I call one method with a enum and some params for request and I probably just get a NSDictionary back without having API calls and blocks in all view controllers. Thanks
This is a concern for the Model part of your MVC architecture. The example project has a good implementation of this:
Post.h
+ (void)globalTimelinePostsWithBlock:(void (^)(NSArray *posts, NSError *error))block;
Define class methods on the model that take care of making requests (translating any method parameters into request params) and serializing objects from the response.
Define your new interface to include your enum, parameters and a block. Define the block to have a BOOL (status) and an NSDictionary (result). This is basically just simplifying and abstracting the interface away from the client, path and operation. Then in the success and failure blocks you can call the outer block with appropriate parameters.
The block is required to maintain the asynchronous nature of the interface. You could use a target and selector but that will be more code and less flexible. You can't have the method just return the resulting dictionary.
There are obviously many other options for what parameters to pass to the method and in the block.

How to replace async calls with mocks and predefined answers?

I have simple class for perform network stuff. It's a singleton and it encapsulates NSOperationQueue inside it. When class' user calls some method to getting data from network, this class creates proper instance of operation class inherited from NSOperation sets up it and adds to queue for performing. Obviously, that performing is making asynchronously in separated threads. After getting data from network NSOperation inherited object notifies my network class and it notifies interested delegates about data getting finished or error.
Question is, how can I make unit tests for checking network class' logic? Also, I don't actually want to test server side behavior. I just want to replace actual async call to server with mock and predefined answers to after test handlers' behavior. I want to check how are my classes work, not server side. I understand commonly logic for testing stuff like that but I little bit confused with using OCMock for it.
Best answer will be code example. I'm using OCUnit and OCMock in my project for unit testing.
Also any articles or github links will be perfect.
If all the asynchronous calls go through an internal method in your class, you can simply create a partial mock on your object and use stub/expect on that method. You can then call the public methods as normal and use the mock to verify that the internal method is called. Using the partial mock stops the real implementation from being called, so no network activity should occur.
As to the other half, the call-backs from the asynchronous operation, simply call the method that would be called directly from your tests, then check that your class does the right thing, either by checking its state with OCUnit asserts, or, if it in turn uses callbacks, with another mock.
So I know this is regarding OCMock... but I thought I'd put it out there that I do this successfully with Kiwi and it looks like this.
it(#"should refresh the client's temporary API key if it is stale before sending the request", ^{
ISLDataServiceAdd *addRequest = [ISLDataServiceAdd withRecord:#{ISLFieldContact_FirstName: #"Jason"} table:ISLTableContact];
[[clientMock shouldEventually] receive:#selector(apiKey) andReturn:VALID_API_KEY];
[[clientMock shouldEventually] receive:#selector(hasTemporaryAPIKey) andReturn:theValue(YES)];
[[clientMock shouldEventually] receive:#selector(isTemporaryAPIKeyStale) andReturn:theValue(YES)];
[[clientMock shouldEventually] receive:#selector(refreshTemporaryAPIKeyAndWait:)];
[addRequest sendRequestUsingClient:clientMock completion:nil failure:nil];
});
sendRequestUsingClient:completion:failure: is an asynchronous call, so by using shouldEventually with Kiwi, it knows that it needs to wait some time (default is 1 second) before those selectors will be called.

What is the use of storing the block in an instance variable

I am aware that blocks are one of the latest feature added in ios. But I am really finding a
tough time learning it .
I have seen people doing the following
typedef void(^CallBackBlk) (NSString *);
#property(copy,nonatomic)CallBackBlk block;
and in .m class
-(void)doSomething:(CallBackBlk )cb{
self.block=cb;
}
I never understood what is the use of assigning it to cb here. Can't I simply do the following
-(void)doSomthing{
block(#"my string");
}
I am really not getting the purpose of storing the block in instance variable. Can any help
me with an example. Any help is greatly appreciated
In your doSomething method, where does block come from?
Answer that, and you'll have your reason.
Ah -- the commentary makes the question clear. Snark served a purpose (snark and too lazy to type out a real answer on my iPhone at 7AM :).
An instance variable is just a slot to put things. Nothing is in that slot to start with.
In your case, you could implement:
-(void)doSomething:(CallBackBlk )cb{
cb();
}
However, typically, a callback is used when you do something asynchronously. For example, you might do:
[myObject doSomething:^{
NSLog(#"did something");
}];
And then:
-(void)doSomething:(CallBackBlk)cb {
dispatch_async(... global concurrent queue ..., ^{
... do some work ...
cb();
});
}
That is, doSomething: will return as soon as the dispatch_async() happens. The callback block is used to callback to let you know that asynchronous operation is done.
Of course, still no need for an instance variable. Take that class that does something a bit further; make it some kind of relatively complex, state transitioning, engine. Say, like your average internet downloader or compute heavy simulation engine. At that point, lumping all your background work into a single method would be overly complex and, thus, shoving the callback block(s) (there may likely be more than one; a progress updater, a completion block and/or an error block, for example) into instance variables allow the class's implementation to be subdivided along lines of functionality more cleanly.
What is the use of storing the block in an instance variable
Perhaps to be able to access it later?
You would do that if you want to invoke the block later, after the method that assigns it has already returned.
Consider for example an object that manages a download. You might want to have a block that gets invoked when the download completes (e.g. to update the UI), but you don't want the download method to have to wait until that happens (because it might take a long time).
maybe and example of use will help..
one use for storing it as a variable i have found is if you have multiple views that all access another view (for me it was a map on the next view) i used blocks that were setup by the previous view (set the default location for the map, initialise markers and so forth) then passed it through to the next view, where it would run it, setting up the map. it was handy having the block use the local variables of the previous view to access certain attributes. it wasnt the only way to do it, but i found it was a nice clean way of going about it.
and here is an example of what gets run in the viewDidLoad of the mapview
if(setupMap){
setupMap(mapView);
}
if(gpsUpdate){
gpsUpdate(mapView);
}
if(addMarker){
addMarker(mapView);
}
now if those blocks were assigned (the if statement check if they are nil), it would run them and do the appropriate setup for the map. not every view needed to do those, so they would only pass to the map view what needed to be done. this keeps the map view very general purpose, and code gets reused a lot. write once use lots!
To use the block, you call your doSomething: method:
CallBackBlk laterBlock = ^(NSString *someString) {
NSLog(#"This code is called by SomeClass at some future time with the string %#", someString);
};
SomeClass *instance = [[SomeClass alloc] init];
[instance doSomething:laterBlock];
As you code the implementation of your class, it will presumably reach some condition or finish an action, and then call the laterBlock:
if (someCondition == YES) {
self.block("Condition is true");
}

Resources