IOS How to 'PUT' text from UIText, and using blocks - ios

I am very new to IOS. With the help of another managed to 'get' data from a third-party API and display in my table view, but now l want to write a number of strings from UIText fields, format based on the API docs and write to the server. The existing code that l have uses blocks. Can anyone provide a very simple example?
Below serves as a rough stab in the dark at decomposing what would be required:
Class 1 - VC class:
//User input from UIText field
I am assuming that l need to write the strings to a NSDictionary- object and key pairs, and using a block?
Call a method which resides in Class 2, which will request the data from the block in Class 1?
Class 2 - Model class:
//Format the data as per the API dictates
//'PUT' the string to the server
Here is what l have thus far:
URLOUTViewController.h Class
//
// URLOUTViewController.h
// URLOUT
//
// Created by Gregory Arden on 21/11/2013.
// Copyright (c) 2013 Not Defined. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "URLOUT_Model.h"
#interface URLOUTViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *firstName;
#property (strong, nonatomic) IBOutlet UITextField *secondName;
- (IBAction)submitButton:(id)sender;
#end
URLOUTViewController.m
//
// URLOUTViewController.m
// URLOUT
//
// Created by Gregory Arden on 21/11/2013.
// Copyright (c) 2013 Not Defined. All rights reserved.
//
#import "URLOUTViewController.h"
#import "URLOUT_Model.h"
#interface URLOUTViewController ()
//Private properties
#property (strong, nonatomic) URLOUT_Model *modelNewDroplet;
#property (strong, nonatomic) NSDictionary *userInput;
#end
#implementation URLOUTViewController
#synthesize userInput;
#synthesize firstName;
#synthesize secondName;
- (URLOUT_Model *) modelNewDroplet
{
if (!_modelNewDroplet) _modelNewDroplet = [[URLOUT_Model alloc]init];
return _modelNewDroplet;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[URLOUT_Model createDropletWithCompletion:^(NSDictionary *userInput) {
self.modelNewDroplet = userInput;
}];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)submitButton:(id)sender {
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:
self.firstName.text, #"firstName", self.secondName.text, #"secondname",nil];
NSLog(#"%#", [dic objectForKey:#"firstName, secondName"]);
}
#end
URLOUT_Model.h
//
// URLOUT_Model.h
// URLOUT
//
// Created by Gregory Arden on 21/11/2013.
// Copyright (c) 2013 Not Defined. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "URLOUTViewController.h"
typedef void (^NSDictionayBlock)(NSDictionary * params);
#interface URLOUT_Model : NSObject
+ (void)createDropletWithCompletion:(NSDictionary *) params;
#end
URLOUT_Model.m
//
// URLOUT_Model.m
// URLOUT
//
// Created by Gregory Arden on 21/11/2013.
// Copyright (c) 2013 Not Defined. All rights reserved.
//
#import "URLOUT_Model.h"
#implementation URLOUT_Model
+ (void)createDropletWithCompletion:(NSDictionary *) params;
{
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:#{params: firstName, secondName, nil}];
[urlRequest setHTTPMethod:#"PUT"];
[urlRequest setCachePolicy:NSURLCacheStorageNotAllowed];
[urlRequest setTimeoutInterval:30.0f];
[urlRequest addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){
NSError *serializationError = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingAllowFragments
error:&serializationError];
}];
}
#end

Creating a HTTP PUT request is simple:
Create an instance of NSMutableURLRequest.
Set the HTTP method to #"PUT" using the -setHTTPMethod: method.
Set the header fields and body using appropriate methods (-setValue:forHTTPHeaderField:, -setHTTPBody:, etc.)
Send the request using an instance of NSURLConnection.
Where the data that you send in the request comes from (text fields, data files, random number generator...) really doesn't make a difference in the creation of the request. You really shouldn't be storing data in your views, though. Generally speaking, your text views and such should trigger an action in a view controller when they change, and the view controller should update the data model. When you want to send data to some server, pull the data from the model, not from UI components.

Related

UITableView is being reset when I use Custom Class

I have a UITableView with 2 text field and a button. If I run the simulator without use custom class, I can see the text fields and button:
But when i use a custom class, my UITable view only display a lot of lines without content:
Here is how I've created my properties:
LoginSceneController.h
#import <UIKit/UIKit.h>
#interface LoginSceneController : UITableViewController
#property (nonatomic, strong) IBOutlet UITextField *email;
#property (nonatomic, strong) IBOutlet UITextField *password;
- (IBAction)doLogin;
#end
LoginSceneController.m
#import "LoginSceneController.h"
#interface LoginSceneController ()
#end
#implementation LoginSceneController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)doLogin {
NSURL *url = [NSURL URLWithString:#"http://rest-service.guides.spring.io/greeting"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSDictionary *greeting = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
self.email.text = [[greeting objectForKey:#"id"] stringValue];
self.password.text = [greeting objectForKey:#"content"];
}
}];
}
#end
The problem happens when I use a custom class (or referencing outlet or add a send event on button).
What is wrong?
edit: I think that I need populate my interface using my custom class because the static content is being lost. Is it possible to be the cause of content being lost?
You have two options when it comes to UITableView and Interface Builder. You can have a dynamic table view (pretty common) where your code overrides UITableViewController methods like "numberOfRowsInSection" and "cellForRowAtIndexPath". The other option is a static tableview, and that seems like what you want to do (especially since you haven't overridden the two aforementioned methods, and leads to your blank table). My guess is you need to select "static" for the tableview as shown in the third screenshot in this tutorial.

Memory leak when making NSURLSession calls and loading images to NSImage

I've built a small demo-application which allows the user to choose a color, which is sent to a basic (for now localhost) node.js server (using NSURLSessionDataTask), which uses the color name to get a fruit name and image URL, and return a simple 2 property JSON object containing the two.
When the application receives the JSON response, it creates a sentence with the color name and fruit name to display in the GUI, and then spawns another NSURLSession call (this time using NSURLSessionDownloadTask) to consume the image URL and download a picture of the fruit to also display in the GUI.
Both of these network operations use [NSURLSession sharedSession].
I'm noticing that both the JSON call and more noticeably the image download are leaking significant amounts of memory. They each follow a similar pattern using nested blocks:
Initialize the session task, passing a block as the completion handler.
If I understand correctly, the block is run on a separate thread since the communication in NSURLSession is async by default, so updating the GUI has to happen in the main, so within the completeHandler block, a call to dispatch_async is made, specifying the main thread, and a short nested block that makes a call to update the GUI.
My guess is that either my use of nested blocks, or nesting of GCD calls is causing the issue. Though it's entirely possible my problem is multi-faceted.
Was hoping some of you with more intimate knowledge of how Obj-C manages memory with threads and ARC would be greatly helpful. Relevant code is included below:
AppDelegate.m
#import "AppDelegate.h"
#import "ColorButton.h"
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSImageView *fruitDisplay;
#property (weak) IBOutlet NSTextField *fruitNameLabel;
#property (weak) IBOutlet ColorButton *redButton;
#property (weak) IBOutlet ColorButton *orangeButton;
#property (weak) IBOutlet ColorButton *yellowButton;
#property (weak) IBOutlet ColorButton *greenButton;
#property (weak) IBOutlet ColorButton *blueButton;
#property (weak) IBOutlet ColorButton *purpleButton;
#property (weak) IBOutlet ColorButton *brownButton;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
proxy = [[FruitProxy alloc] init];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
// Insert code here to tear down your application
}
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
return YES;
}
/*------------------------------------------------------------------*/
- (IBAction)colorButtonWasClicked:(id)sender
{
ColorButton *btn = (ColorButton*)sender;
NSString *selectedColorName = btn.colorName;
#autoreleasepool {
[proxy requestFruitByColorName:selectedColorName
completionResponder:^(NSString* fruitMessage, NSString* imageURL)
{
[self fruitNameLabel].stringValue = fruitMessage;
__block NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]];
__block NSURLSession *imageSession = [NSURLSession sharedSession];
__block NSURLSessionDownloadTask *imgTask = [imageSession downloadTaskWithRequest:req
completionHandler:
^(NSURL *location, NSURLResponse *response, NSError *error)
{
if(fruitImage != nil)
{
[self.fruitDisplay setImage:nil];
fruitImage = nil;
}
req = nil;
imageSession = nil;
imgTask = nil;
response = nil;
fruitImage = [[NSImage alloc] initWithContentsOfURL:location];
[fruitImage setCacheMode:NO];
dispatch_async
(
dispatch_get_main_queue(),
^{
[[self fruitDisplay] setImage: fruitImage];
}
);
}];
[imgTask resume];
}];
}
}
#end
FruitProxy.m
#import "FruitProxy.h"
#implementation FruitProxy
- (id)init
{
self = [super init];
if(self)
{
return self;
}
else
{
return nil;
}
}
- (void) requestFruitByColorName:(NSString*)colorName
completionResponder:(void( ^ )(NSString*, NSString*))responder
{
NSString *requestURL = [self urlFromColorName:colorName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestURL]];
session = [NSURLSession sharedSession];
#autoreleasepool {
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:
^(NSData *data, NSURLResponse *response, NSError *connectionError)
{
NSString *text = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSDictionary *responseObj = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSString *fruitName = (NSString*)responseObj[#"fruitName"];
NSString *imageURL = (NSString*)responseObj[#"imageURL"];
NSLog(#"Data = %#",text);
dispatch_async
(
dispatch_get_main_queue(),
^{
responder([self messageFromColorName:colorName fruitName:fruitName], imageURL);
}
);
}];
[task resume];
}
}
- (NSString*)urlFromColorName:(NSString*)colorName
{
NSString *result;
result = #"http://localhost:9000/?color=";
result = [result stringByAppendingString:colorName];
return result;
}
- (NSString*)messageFromColorName:(NSString*)colorName
fruitName:(NSString*)fruitName
{
NSString *result = #"A ";
result = [[[[result stringByAppendingString:colorName]
stringByAppendingString:#"-colored fruit could be "]
stringByAppendingString:fruitName]
stringByAppendingString:#"!"];
return result;
}
#end
Where does "fruitImage" come from in AppDelegate.m? I don't see it declared.
the line:
__block NSURLSessionDownloadTask *imgTask
is a bit weird because you're marking imgTask as a reference that can change in the block, but it's also the return value. That might be part of your problem, but in the very least it's unclear. I might argue that all the variables you marked __block aren't required to be as such.
typically a memory leak in these situations is caused by the variable capture aspect of the block, but I'm not seeing an obvious offender. The "Weak Self" pattern might help you here.
Using "leaks" might help you see what objects are leaking, which can help isolate what to focus on, but also try to take a look at your block's life cycles. If a block is being held by an object it can create cycles by implicitly retaining other objects.
Please follow up when you figure out exactly what's going on.
reference:
What does the "__block" keyword mean?
Always pass weak reference of self into block in ARC?

Subclassing NSURLConnection gives error: unrecognized selector sent to instance

i'm trying to make a subclass of NSURLConnection where i have an additional property (in this case "connectionName") to help me distinguish between 2 different connections.
i created the subclass, named it CustomURLConnection and gave it the property "connectionName".
then in my file ImagesViewController.m (which is an UICollectionView) i import the header CustomURLConnection and try to give the connections a name and retrieve it afterwards, but it doesn't work, as soon as i enter this collection view the app crashes and gives me the following error:
-[NSURLConnection setConnectionName:]: unrecognized selector sent to instance 0x1090a40f0
Here is some code: (if you want, here's a CLEARER IMAGE)
CustomURLConnection.h
#import <Foundation/Foundation.h>
#interface CustomURLConnection : NSURLConnection
#property (strong, nonatomic) NSString *connectionName;
#end
ImagesViewController.h
#import <UIKit/UIKit.h>
#interface ImagesViewController : UICollectionViewController<NSURLConnectionDelegate>
#property (strong, nonatomic) UIImageView *imageView;
#end
ImagesViewController.m
...
#import "CustomURLConnection.h"
#interface ImagesViewController (){
NSArray *contentStrings;
NSMutableData *contentData; // Holds data from the initial load
NSMutableData *contentImageData; // Holds data when the user scrolls up/down in the collection view
}
#end
...
-(void)loadInitialData{ // Loads data from page
NSString *hostStr = #"http://www.website.com/example";
NSURL *dataURL = [NSURL URLWithString:hostStr];
NSURLRequest *request = [NSURLRequest requestWithURL:dataURL];
CustomURLConnection *connectionData = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self]; // Make connection
connectionData.connectionName = #"InitialData"; // Give it a name
}
...
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
// Do some stuff
NSString *hostStr = #"http://www.website.com/example2";
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,100,100)];
[imageCell addSubview:_imageView]; // Adds an image view to each collection cell
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:hostStr]];
CustomURLConnection *connectionImg = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self]; // Make connection
connectionImg.connectionName = #"ImageData"; // Give it a different name than before
// Do some stuff
return imageCell;
}
...
// Here are the main methods for the connections
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
if([((CustomURLConnection *)connection).connectionName isEqualToString:#"InitialData"]){
contentData = [[NSMutableData alloc] init];
}
else{
contentImageData = [[NSMutableData alloc] init];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if([((CustomURLConnection *)connection).connectionName isEqualToString:#"InitialData"]){
[contentData appendData:data];
}
else{
[contentImageData appendData:data];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
if([((CustomURLConnection *)connection).connectionName isEqualToString:#"InitialData"]){
// Do some stuff
}
else{
UIImage *image = [[UIImage alloc] initWithData:contentImageData];
_imageView.image = image;
}
}
am i missing something? i came across this error many times before but the causes are never the same and this time i can't seem to find a solution on my own.
hopefully you can see what i'm doing wrong and help me :)
thanks.
EDIT: turns out there is a better way to achieve my goal, have a look here
Thank again to everyone for the help :)
CustomURLConnection *connectionImg = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self]; // Make connection
creates an NSURLConnection object. Casting to CustomURLConnection does not change
the class of this object. Replace that line with
CustomURLConnection *connectionImg = [CustomURLConnection connectionWithRequest:request delegate:self]; // Make connection
to create an instance of your subclass.
In your delegate methods change NSURLConnection by CustomURLConnection, for instance :
- (void)connection:(CustomURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
and when you create it just do :
CustomURLConnection *connectionImg = [[CustomURLConnection alloc] initWithRequest:request delegate:self];
connectionImg.connectionName = #"ImageData"; // Give it a different name than before
In this line:
CustomURLConnection *connectionData = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self];
you are creating an instance of NSURLConnection, not CustomURLConnection. So, when you cast the result to CustomURLConnection * you are lying to the compiler.
Later, at runtime, when you try to use a feature of CustomURLConnection you get an exception because your connection is the wrong class type and doesn't implement the method.
You need to instantiate CustomURLConnection, not NSURLConnection.
Adding to the other good answers here, your CustomURLConnection class should override +connectionWithRequest:delegate: to return an instance of CustomURLConnection, like this:
+(CustomURLConnection*)connectionWithRequest:(NSURLRequest*)request delegate:(id)delegate
{
return [[CustomURLConnection alloc] initWithRequest:request delegate:delegate];
}
That lets you use the same style you had:
CustomURLConnection *connectionData = [CustomURLConnection connectionWithRequest:request delegate:self]; // Make connection
More importantly, a user of your code (most likely the future you) might assume that sending +connectionWithRequest:delegate: to CustomURLConnection would return an instance of CustomURLConnection. Without the override, they'll get an instance of NSURLConnection instead, and that's a difficult bug to spot.

iOS POST to Google Froms (Spreadsheet)

I am trying to set up a very simple app, that takes in a number from an input field, and then POSTS using an NSMutableURLRequest to a Google Spreadsheet, using the action URL from the Google Form.
So far I have a simple text box and button, and this code. The field name I am using is:
name="entry.931001663"
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *inputField;
- (IBAction)submit:(id)sender;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)submit:(id)sender {
NSString *bodyData = self.inputField.text;
NSLog(#"Input = %#", bodyData);
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://docs.google.com/forms/d/1rGpFfI2ebyn_SbuDVVUg7Q4yuvKzd3RRXb0vRxeIDxc/formResponse"]];
[postRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[postRequest setHTTPMethod:#"POST"];
[postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];
}
#end
I am not sure about the error, but Google's Sample Code can help you. You can also use GData Objective C Client to use it.

how to unit testing AFNetworking request

i am making a GET request to retrieve JSON data with AFNetworking as this code below :
NSURL *url = [NSURL URLWithString:K_THINKERBELL_SERVER_URL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
Account *ac = [[Account alloc]init];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"GET" path:[NSString stringWithFormat:#"/user/%#/event/%#",ac.uid,eventID] parameters:nil];
AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *error = nil;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
if (error) {
}
[self.delegate NextMeetingFound:[[Meeting alloc]init] meetingData:JSON];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error){
}];
[httpClient enqueueHTTPRequestOperation:operation];
the thing is i want to create a unit test based on this data, but i dont want that the test will actually make the request. i want a predefined structure will return as the response. i am kind'a new to unit testing, and poked a little of OCMock but cant figure out how to manage this.
Several things to comment about your question.
First of all, your code is hard to test because it is creating the AFHTTPClient directly. I don't know if it's because it's just a sample, but you should inject it instead (see the sample below).
Second, you are creating the request, then the AFHTTPRequestOperation and then you enqueue it. This is fine but you can get the same using the AFHTTPClient method getPath:parameters:success:failure:.
I do not have experience with that suggested HTTP stubbing tool (Nocilla) but I see it is based on NSURLProtocol. I know some people use this approach but I prefer to create my own stubbed response objects and mock the http client like you see in the following code.
Retriever is the class we want to test where we inject the AFHTTPClient.
Note that I am passing directly the user and event id, since I want to keep things simple and easy to test. Then in other place you would pass the accout uid value to this method and so on...
The header file would look similar to this:
#import <Foundation/Foundation.h>
#class AFHTTPClient;
#protocol RetrieverDelegate;
#interface Retriever : NSObject
- (id)initWithHTTPClient:(AFHTTPClient *)httpClient;
#property (readonly, strong, nonatomic) AFHTTPClient *httpClient;
#property (weak, nonatomic) id<RetrieverDelegate> delegate;
- (void) retrieveEventWithUserId:(NSString *)userId eventId:(NSString *)eventId;
#end
#protocol RetrieverDelegate <NSObject>
- (void) retriever:(Retriever *)retriever didFindEvenData:(NSDictionary *)eventData;
#end
Implementation file:
#import "Retriever.h"
#import <AFNetworking/AFNetworking.h>
#implementation Retriever
- (id)initWithHTTPClient:(AFHTTPClient *)httpClient
{
NSParameterAssert(httpClient != nil);
self = [super init];
if (self)
{
_httpClient = httpClient;
}
return self;
}
- (void)retrieveEventWithUserId:(NSString *)userId eventId:(NSString *)eventId
{
NSString *path = [NSString stringWithFormat:#"/user/%#/event/%#", userId, eventId];
[_httpClient getPath:path
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *eventData = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:NULL];
if (eventData != nil)
{
[self.delegate retriever:self didFindEventData:eventData];
}
}
failure:nil];
}
#end
And the test:
#import <XCTest/XCTest.h>
#import "Retriever.h"
// Collaborators
#import <AFNetworking/AFNetworking.h>
// Test support
#import <OCMock/OCMock.h>
#interface RetrieverTests : XCTestCase
#end
#implementation RetrieverTests
- (void)setUp
{
[super setUp];
// Put setup code here; it will be run once, before the first test case.
}
- (void)tearDown
{
// Put teardown code here; it will be run once, after the last test case.
[super tearDown];
}
- (void) test__retrieveEventWithUserIdEventId__when_the_request_and_the_JSON_parsing_succeed__it_calls_didFindEventData
{
// Creating the mocks and the retriever can be placed in the setUp method.
id mockHTTPClient = [OCMockObject mockForClass:[AFHTTPClient class]];
Retriever *retriever = [[Retriever alloc] initWithHTTPClient:mockHTTPClient];
id mockDelegate = [OCMockObject mockForProtocol:#protocol(RetrieverDelegate)];
retriever.delegate = mockDelegate;
[[mockHTTPClient expect] getPath:#"/user/testUserId/event/testEventId"
parameters:nil
success:[OCMArg checkWithBlock:^BOOL(void (^successBlock)(AFHTTPRequestOperation *, id))
{
// Here we capture the success block and execute it with a stubbed response.
NSString *jsonString = #"{\"some valid JSON\": \"some value\"}";
NSData *responseObject = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
[[mockDelegate expect] retriever:retriever didFindEventData:#{#"some valid JSON": #"some value"}];
successBlock(nil, responseObject);
[mockDelegate verify];
return YES;
}]
failure:OCMOCK_ANY];
// Method to test
[retriever retrieveEventWithUserId:#"testUserId" eventId:#"testEventId"];
[mockHTTPClient verify];
}
#end
The last thing to comment is that the AFNetworking 2.0 version is released so consider using it if it covers your requirements.

Resources