Best way to store a collection of objects - objective-c

I have several objects that I want to store in an array. What is the way to do this in objective-c? I have been looking into NSMutableDictionary but have had no luck.
In my code below, I am iterating through an array of strings, making a network call for each string, and getting an object back for each string. I want to store my objects in a list that I can access later.
-(void) setPictures {
for(id item in self.phraseWordsArray) {
AFNetworkingAPIClient *netowrkingObject = [[AFNetworkingAPIClient alloc] init];
[netowrkingObject getPhotoForWord:item success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"responseObject=%#",responseObject);
self.test = responseObject;
[self printOutJSON];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error=%#",error);
}];
}
}

It looks like NSMutableArray is what you need, am i correct?

You can store your response objects into an NSMutableArray that is a property on the UIViewController calling this code, or elsewhere. See the following for an example scenario:
// In your interface...
#property (nonatomic,strong) NSMutableArray *responseObjects;
// ... Later in code
self.responseObjects = [NSMutableArray array];
- (void)setPictures {
for(id item in self.phraseWordsArray) {
AFNetworkingAPIClient *netowrkingObject = [[AFNetworkingAPIClient alloc] init];
[netowrkingObject getPhotoForWord:item success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"responseObject=%#",responseObject);
self.test = responseObject;
[self printOutJSON];
if (responseObject) {
[self.responseObjects addObject:responseObject];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error=%#",error);
}];
}
}

Related

NSRangeException while deleting UICollectionView cells

I'm trying to remove cells from UICollectionView in for.. in loop and every time I get NSRangeException. I can't understand why does it happen because firstly I sort my array and then trying to remove. So the problem is that I firstly try to send request to the server and only if response is succes my UICollectionView cells and array elements are removes. Here is my code:
Pass elements through the loop:
- (IBAction)deletePictures:(id)sender {
int i = 0;
if (selectedPhotosURL.count>0){
loadCount = (int)selectedPhotosURL.count;
//sorting an array (it works fine)
NSArray *indexPaths = sortMediaCollection.indexPathsForSelectedItems;
NSMutableArray *pathes = [NSMutableArray arrayWithArray:indexPaths];
NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:#"self" ascending:NO];
[pathes sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];
[selecedCellsArray sortUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
return [str2 compare:str1 options:(NSNumericSearch)];
}];
NSLog(#"selectedCElls %#",selecedCellsArray);
for(NSIndexPath *indexPath in pathes) {
NSLog(#"indexPath in pathes is %ld",(long)indexPath.row);
AVMSMCell *cell = (AVMSMCell *)[sortMediaCollection cellForItemAtIndexPath:indexPath];
AVMDataStore *oneItem = [smArray objectAtIndex:indexPath.row];
NSString *contentId = oneItem.fileId;
if (i<selectedPhotosURL.count){
NSLog(#"indexPath second loop is %ld",(long)indexPath.row);
[self deleteUserPhotos:contentId : indexPath.row : cell]; // send request to the server it's ok too.
i++;
}
}
} else {
[self selectAtLeastOneFirst];
}
}
For example here I select 6 cells and my array sort with right order from up to down (5,4,3,2,1,0). Then I pass this elements in method with this order.
Request send method:
-(void)deleteUserPhotos : (NSString *)contentId : (NSInteger )pathRow : (AVMSMCell *) cell{
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)pathRow];
if (([selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]]) )
{
cell.selectedBG.backgroundColor = DANGER;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *token = [defaults objectForKey:#"token"];
NSString *header = [NSString stringWithFormat:#"Bearer %#",token];
NSDictionary *params = #{#"lang": #"en",#"content_id":contentId,#"project_id":[defaults objectForKey:#"project_id"]};
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:header forHTTPHeaderField:#"Authorization"];
[manager POST:#"http://example.com/api/project/delete-content" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"JSON: %#", responseObject);
if ([[responseObject objectForKey:#"result"] isEqualToString:#"success"]){
#try{
NSLog(#"pathRow in TRY %ld",(long)pathRow); // HERE I get wrong number after two or three elements already passed
[smArray removeObjectAtIndex:(unsigned int)pathRow];
[selecedCellsArray removeObject:[NSString stringWithFormat:#"%ld",(long)pathRow]];
cell.selectedBG.hidden = YES;
[sortMediaCollection reloadSections:[NSIndexSet indexSetWithIndex:0]];
loadCount--;
}
} #catch (NSException *e){
NSLog(#"something is bad %#",e);
[SVProgressHUD dismiss];
if (smArray.count<pathRow-1){
[smArray removeObjectAtIndex:(unsigned int)pathRow-1];
}
} #finally {
cell.selectedBG.hidden = YES;
[sortMediaCollection reloadSections:[NSIndexSet indexSetWithIndex:0]];
}
} else {
NSLog(#"can't delete photo!");
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"Error: %#", error);
errorEndSpinner
}];
}
}
So in method above I get wrong element number after two or three elements already passed i.e frist element is 5,then 4, then 2, 3,1,0.
And at this moment my #catch handle exception and trying to remove element with [smArray removeObjectAtIndex:(unsigned int)pathRow-1]; and then I get NSRangeException and my app crashing. What I do wrong?
I solved my problem with this answer and little bit modified my code.
I've got an NSRangeException because I removed my UICollectionView items through the loop. Instead I should better use multiple deleting instantly like this:
// Delete the items from the data source.
[self deleteItemsFromDataSourceAtIndexPaths:selectedItemsIndexPaths];
// Now delete the items from the collection view.
[sortMediaCollection deleteItemsAtIndexPaths:selectedItemsIndexPaths];
So now my code looks like:
Pass through the loop:
- (IBAction)deletePictures:(id)sender {
int i = 0;
if (selectedPhotosURL.count>0){
[SVProgressHUD showWithStatus:#"Deleting" maskType:SVProgressHUDMaskTypeBlack];
loadCount = (int)selectedPhotosURL.count;
NSArray *indexPaths = sortMediaCollection.indexPathsForSelectedItems;
NSMutableArray *pathes = [NSMutableArray arrayWithArray:indexPaths];
NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:#"self" ascending:NO];
[pathes sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];
[selecedCellsArray sortUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
return [str2 compare:str1 options:(NSNumericSearch)];
}];
for(NSIndexPath *indexPath in pathes) {
AVMSMCell *cell = (AVMSMCell *)[sortMediaCollection cellForItemAtIndexPath:indexPath];
AVMDataStore *oneItem = [smArray objectAtIndex:indexPath.row];
NSString *contentId = oneItem.fileId;
if (i<selectedPhotosURL.count){
[self deleteUserPhotos:contentId : indexPath.row : cell pathes:pathes]; //pass array with pathes into 'deleteUserPhotos'
i++;
}
}
} else {
[self selectAtLeastOneFirst];
}
}
Main method:
-(void)deleteItemsFromDataSourceAtIndexPaths:(NSArray *)itemPaths {
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
for (NSIndexPath *itemPath in itemPaths) {
[indexSet addIndex:itemPath.row];
}
[smArray removeObjectsAtIndexes:indexSet];
}
-(void)deleteUserPhotos : (NSString *)contentId : (NSInteger )pathRow : (AVMSMCell *) cell pathes:(NSMutableArray*)selectedItemsIndexPaths{
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)pathRow];
if (([selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]]))
{
cell.selectedBG.backgroundColor = DANGER;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *token = [defaults objectForKey:#"token"];
NSString *header = [NSString stringWithFormat:#"Bearer %#",token];
NSDictionary *params = #{#"lang": #"en",#"content_id":contentId,#"project_id":[defaults objectForKey:#"project_id"]};
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:header forHTTPHeaderField:#"Authorization"];
[manager POST:#"http://example.com/api/project/delete-content" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"JSON: %#", responseObject);
if ([[responseObject objectForKey:#"result"] isEqualToString:#"success"]){
#try{
[selecedCellsArray removeObject:[NSString stringWithFormat:#"%ld",(long)pathRow]];
loadCount--;
if (loadCount==0){ //only there remove items from collectionview
// Delete the items from the data source.
[self deleteItemsFromDataSourceAtIndexPaths:selectedItemsIndexPaths];
// Now delete the items from the collection view.
[sortMediaCollection deleteItemsAtIndexPaths:selectedItemsIndexPaths];
[selectedPhotosURL removeAllObjects];
}
} #catch (NSException *e){
NSLog(#"something is bad %#",e);
[SVProgressHUD dismiss];
if (smArray.count<pathRow-1){
[smArray removeObjectAtIndex:(unsigned int)pathRow-1];
}
} #finally {
cell.selectedBG.hidden = YES;
[sortMediaCollection reloadSections:[NSIndexSet indexSetWithIndex:0]];
}
} else {
NSLog(#"can't delete photo!");
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"Error: %#", error);
errorEndSpinner
}];
}
}
Hope this will be helpful for somebody.
I was getting the same error but found that it had to do with a different class having a mirrored copy of the array, and that class accessing a deleted index.
You can add an Exception Breakpoint to see exactly where the exception is coming from. Useful for differentiating errors in your code with errors coming from the iOS SDK: NSRangeException when deleting last UICollectionViewCell

How can I refactor duplicated codes for error?

I'm using block for my APIs and the API class throws error via block like below code.
[HJHLifeAPI deletePlantWithIdentifier:identifier completionHandler:^(NSError *error) {
if (error) {
[[error alertView] show];
return ;
}
[self refresh:self.refreshControl];
}];
But the problem is that I use this pattern of codes in several places. As a result, I should write several duplicated codes for error handling. Is there any way to refactor this code? I think exception can be one solution, but I think Apple don't encourage developers to use it.
It's up to How your HJHLifeAPI is designed.
I usually use AFNetworking for API things and here's an example.
// This is the method like deletePlantWithIdentifier:
// It actually invoke __requestWitPath:
- (void)requestSomethingWithId:(NSString *)memId done:(NetDoneBlock)done
{
NSMutableDictionary *param_ = #{#"key":#"id"};
[self __requestWithPath:#"/apiPath.jsp" parameter:param_ done:done];
}
#pragma PRIVATE
- (void)__requestWithPath:(NSString *)apiPath parameter:(NSDictionary *)parameter done:(NetDoneBlock)done
{
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:SERVER_URL]];
AFHTTPRequestOperation *operation = [manager POST:apiPath parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
done();
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Error Handle Here
}];
[operation start];
}
You can handle all errors in one __request....
Create the block
void(^errorHandler)(NSError *error) = ^(NSError *error) {
if (error) {
[[error alertView] show];
return ;
}
[self refresh:self.refreshControl];
}
Save it somewhere (don't forget to copy it)
self.errorHandler = errorHandler;
Reuse it everywhere:
[HJHLifeAPI deletePlantWithIdentifier:identifier completionHandler:self.errorHandler];

Threads Using Managed Objects Between Contexts

I am at that point where I am losing hair on this so I figured I'd reach out to the great minds here who have had experience using Objective C with Threads and core data. I am having issues with managed objects inserted in on thread in a NSPrivateQueue Context being accessed from the main thread. So at a high level I am using AFNetworking to generate a thread to make requests to retrieve JSON data from a server and then insert the values into my persistent store core data. After this is done I have another thread for downloading some binary data using AFNetworking as well. I have set up 2 managed contexts for this as shown below:
(NSManagedObjectContext *)masterManagedContext {
if (_masterManagedContext != nil) {
return _masterManagedContext;
}
NSPersistentStoreCoordinator *coord = [self coordinator];
if (coord != nil) {
_masterManagedContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_masterManagedContext.stalenessInterval = 0.0;
[_masterManagedContext performBlockAndWait:^{
[_masterManagedContext setPersistentStoreCoordinator:coord];
}];
}
return _masterManagedContext;
}
// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)backgroundManagedContext {
if (_backgroundManagedContext != nil) {
return _backgroundManagedContext;
}
NSManagedObjectContext *masterContext = [self masterManagedContext];
if (masterContext != nil) {
_backgroundManagedContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_backgroundManagedContext.stalenessInterval = 0.0;
[_backgroundManagedContext performBlockAndWait:^{
[_backgroundManagedContext setParentContext:masterContext];
}];
}
return _backgroundManagedContext;
}
As is shown above I am using a child context and the parent context. When I make I call to fetch the json data I have something like below:
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
//Initially delete all records in table. This will change
[[Singleton sharedInstance]removeEntityObjects:className];
for (int x=0; x < [JSON count]; x++) {
NSMutableDictionary *curDict = [JSON objectAtIndex:x];
[[CoreDatam sharedinstance] insertEmployeesWithDictionary:curDict];
}else {
/* do nothing */
}
}
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error,id JSON) {
[delegate performSelector:#selector(didNotCompleteSync:) withObject:className];
}];
[operations addObject:operation];
}
[self.AFClient enqueueBatchOfHTTPRequestOperations:operations progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
NSLog(#"Currenlty downloaded table data %d of %d!",numberOfCompletedOperations,totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
if (_syncInProgress) {
[[CoreDatam sharedInstance]updateEmpForId];
[self downloadAllFiles];
}
}];
}`
for the insert function I have something like below:
insertEmployeesWithDictionary:curDict {
[[self backgroundManagedContext]performBlockAndWait:^{
Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:#"Employee"
inManagedObjectContext:[self backgroundManagedContext]];
/* Issues saving null into core data based on type.*/
[emp setFirst:[dictCopy objectForKey:#"first"]];
[emp setLast:[dictCopy objectForKey:#"last"]];
NSError *error = nil;
BOOL saved;
saved = [[self backgroundManagedContext] save:&error];
if (!saved) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
[self saveMasterContext];
}];
}
The issue is below where I am trying to access the managed objects in the method that is in the completion block above:
updateEmpId {
[self.backgroundManagedContext performBlockAndWait:^{
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Employee"];
[request setSortDescriptors:[NSArray arrayWithObject:
[NSSortDescriptor sortDescriptorWithKey:#"last" ascending:YES]]];
myEmps = [self.backgroundManagedContext executeFetchRequest:request error:nil];
for (Employee *moEmp in myEmps) {
[[self backgroundManagedContext]refreshObject:moEmp mergeChanges:YES];
moEmp.photo = #'default.pic';
}
NSError *saveError = nil;
if (![self.backgroundManagedContext save:&saveError]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
[self saveMasterContext];
}
The issue is that I am getting very inconsistent behavior when looking at the managed objects that are modified in the main thread. Is it still necessary to pass managed objectIds when using a parent child context relation? if so how can I do so for the above example? Any help greatly appreciated.
You should pass NSManagedObjectIDs or re-fetch in the main thread context, yeah. If you pass object IDs, get the IDs from the background context after saving the new Employee objects, and use existingObjectWithID:error: in the parent context to instantiate them there. Or just re-do the fetch request from your updateEmpId code block in the masterManagedContext.

AFNetwork with ASP.net Web service

I call my webservice using the getPath method like so:
[[AFTwitterAPIClient sharedClient] getPath:#"GetWineCategoryList"
parameters:parameters success:^(AFHTTPRequestOperation *operation, id JSON) {
NSLog(#"JSON = %#",JSON);
NSMutableArray *mutableTweets = [NSMutableArray arrayWithCapacity:[JSON count]];
for (NSDictionary *attributes in mutableTweets) {
Tweet *tweet = [[Tweet alloc] initWithAttributes:attributes];
[mutableTweets addObject:tweet];
}
if (block) {
block([NSArray arrayWithArray:mutableTweets], nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block([NSArray array], error);
}
}];
It always outputs as NSData. If I convert this NSData to a string I get a JSON String.
JSON = <5b7b2243 61746567 6f72794e 616d6522 3a224f54 48455222 7d2c7b22 43617465 676f7279 4e616d65 223a2252 4544227d 2c7b2243 61746567 6f72794e 616d6522 3a22524f 5345227d 2c7b2243 61746567 6f72794e 616d6522 3a225748 49544522 7d5d>
Why won't it convert to an NSArray?
You can use the NSJSONSerialization Class to convert your NSData object to an NSArray.
NSArray *array = (NSArray*)[NSJSONSerialization JSONObjectWithData:JSON
options:0
error:&error];
This assumes you know that your JSON is of array type and not dictionary type.

AFNetworking Synchronous Operation in NSOperationQueue on iPhone

My app is working this way :
- create an album and take pictures
- send them on my server
- get an answer / complementary information after picture analysis.
I have some issue with the sending part. Here is the code
#interface SyncAgent : NSObject <SyncTaskDelegate>
#property NSOperationQueue* _queue;
-(void)launchTasks;
#end
#implementation SyncAgent
#synthesize _queue;
- (id)init
{
self = [super init];
if (self) {
self._queue = [[NSOperationQueue alloc] init];
[self._queue setMaxConcurrentOperationCount:1];
}
return self;
}
-(void) launchTasks {
NSMutableArray *tasks = [DataBase getPendingTasks];
for(Task *t in tasks) {
[self._queue addOperation:[[SyncTask alloc] initWithTask:t]];
}
}
#end
and the SyncTask :
#interface SyncTask : NSOperation
#property (strong, atomic) Task *_task;
-(id)initWithTask:(Task *)task;
-(void)mainNewID;
-(void)mainUploadNextPhoto:(NSNumber*)photoSetID;
#end
#implementation SyncTask
#synthesize _task;
-(id)initWithTask:(Task *)task {
if(self = [super init]) {
self._task = task;
}
return self;
}
-(void)main {
NSLog(#"Starting task : %#", [self._task description]);
// checking if everything is ready, sending delegates a message etc
[self mainNewID];
}
-(void)mainNewID {
__block SyncTask *safeSelf = self;
[[WebAPI sharedClient] createNewPhotoSet withErrorBlock:^{
NSLog(#"PhotoSet creation : error")
} andSuccessBlock:^(NSNumber *photoSetID) {
NSLog(#"Photoset creation : id is %d", [photoSetID intValue]);
[safeSelf mainUploadNextPhoto:photoSetID];
}];
}
-(void)mainUploadNextPhoto:(NSNumber*) photoSetID {
//just admit we have it. won't explain here how it's done
NSString *photoPath;
__block SyncTask *safeSelf = self;
[[WebAPI sharedClient] uploadToPhotosetID:photoSetID withPhotoPath:photoPath andErrorBlock:^(NSString *photoPath) {
NSLog(#"Photo upload error : %#", photoPath);
} andSuccessBlock:^(NSString *photoPath) {
NSLog(#"Photo upload ok : %#", photoPath);
//then we delete the file
[safeSelf mainUploadNextPhoto:photoSetID];
}];
}
#end
Every network operations are done using AFNetworking this way :
-(void)myDummyDownload:(void (^)(NSData * data))successBlock
{
AFHTTPClient* _httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://www.google.com/"]];
[_httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
NSMutableURLRequest *request = [_httpClient requestWithMethod:#"GET" path:#"/" nil];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:(NSURLRequest *)request
success:^(AFHTTPRequestOperation *operation, id data) {
if(dataBlock)
dataBlock(data);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Cannot download : %#", error);
}];
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
NSLog(#"Request time out");
}];
[_httpClient enqueueHTTPRequestOperation:operation];
}
My problem is : my connections are made asynchronously, so every task are launched together without waiting fo the previous to finish even with [self._queue setMaxConcurrentOperationCount:1] in SyncAgent.
Do I need to perform every connection synchronously ? I don't think this is a good idea, because a connection never should be done this way and also because I might use these methods elsewhere and need them to be performed in background, but I cannot find a better way. Any idea ?
Oh and if there is any error/typo in my code, I can assure you it appeared when I tried to summarize it before pasting it, it is working without any problem as of now.
Thanks !
PS: Sorry for the long pastes I couldn't figure out a better way to explain the problem.
EDIT: I found that using a semaphore is easier to set up and to understand : How do I wait for an asynchronously dispatched block to finish?
If you have any control over the server at all, you should really consider creating an API that allows you to upload photos in an arbitrary order, so as to support multiple simultaneous uploads (which can be quite a bit faster for large batches).
But if you must do things synchronized, the easiest way is probably to enqueue new requests in the completion block of the requests. i.e.
// If [operations length] == 1, just enqueue it and skip all of this
NSEnumerator *enumerator = [operations reverseObjectEnumerator];
AFHTTPRequestOperation *currentOperation = nil;
AFHTTPRequestOperation *nextOperation = [enumerator nextObject];
while (nextOperation != nil && (currentOperation = [enumerator nextObject])) {
currentOperation.completionBlock = ^{
[client enqueueHTTPRequestOperation:nextOperation];
}
nextOperation = currentOperation;
}
[client enqueueHTTPRequestOperation:currentOperation];
The following code works for me, but I am not sure of the drawbacks. Take it with a pinch of salt.
- (void) main {
NSCondition* condition = [[NSCondition alloc] init];
__block bool hasData = false;
[condition lock];
[[WebAPI sharedClient] postPath:#"url"
parameters:queryParams
success:^(AFHTTPRequestOperation *operation, id JSON) {
//success code
[condition lock];
hasData = true;
[condition signal];
[condition unlock];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure code
[condition lock];
hasData = true;
[condition signal];
[condition unlock];
}];
while (!hasData) {
[condition wait];
}
[condition unlock];
}