Reputation: 13
Return type of method is NSArray, so when I call this method I get nil or empty array. Here it's below my method implementation:
- (NSArray *)startParsing {
__block NSArray *array;
allProductsID = [[NSMutableArray alloc] init];
NSString *string = [NSString stringWithFormat:@"http://%@:@%@",kPrestaShopAPIKey, kPrestaShopURLString];
NSURL *url = [NSURL URLWithString:string];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
[manager GET:@"categories/21" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSXMLParser *parser = (NSXMLParser *)responseObject;
[parser setShouldProcessNamespaces:YES];
parser.delegate = self;
[parser parse];
//NSLog(@"First response %@", responseObject);
for (int i = 0; i< [[self.xmlShop objectForKey:@"product"] count]; i++) {
//NSLog(@"Second ID --> %@", [self.xmlShop objectForKey:@"product"][i]);
NSString *productID = [NSString stringWithFormat:@"products/%@", [[self.xmlShop objectForKey:@"product"][i] objectForKey:@"id"]];
[allProductsID addObject:productID];
}
array = [allProductsID copy];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error occured %@", [error localizedDescription]);
}];
return array;
}
Can anyone help me with this problem?
Upvotes: 1
Views: 3580
Reputation: 379
Method which shoud return value of enum
- (RXCM_TroubleTypes) logic_getEnumValueOfCurrentCacheProblem
{
RXCM_TroubleTypes result = RXCM_HaveNotTrouble;
NetworkStatus statusConnection = [self network_typeOfInternetConnection];
RXCM_TypesOfInternetConnection convertedNetStatus = [RXCM convertNetworkStatusTo_TypeOfInternetConnection:statusConnection];
BOOL isAllowed = [self someMethodWith:convertedNetStatus];
if (isAllowed){
return RXCM_HaveNotTrouble;
}else {
return RXCM_Trouble_NotSuitableTypeOfInternetConnection;
}
return result;
}
Method which calls delegate's method with block. And waits answer from it. Here I use while loop. Just check every 0.5sec answer from block
- (BOOL) isUserPermissioned:(RXCM_TypesOfInternetConnection)newType
{
__block BOOL isReceivedValueFromBlock = NO;
__block BOOL result = NO;
__block BOOL isCalledDelegateMethod = NO;
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_sync(aQueue,^{
while (!isReceivedValueFromBlock) {
NSLog(@"While");
if (!isCalledDelegateMethod){
[self.delegate rxcm_isAllowToContinueDownloadingOnNewTypeOfInternetConnection:newType
completion:^(BOOL isContinueWorkOnNewTypeOfConnection) {
result = isContinueWorkOnNewTypeOfConnection;
isReceivedValueFromBlock = YES;
}];
isCalledDelegateMethod = YES;
}
[NSThread sleepForTimeInterval:0.5];
}
});
return result;
}
Delegate's method in ViewController
- (void) rxcm_isAllowToContinueDownloadingOnNewTypeOfInternetConnection:(RXCM_TypesOfInternetConnection)newType
completion:(void(^)(BOOL isContinueWorkOnNewTypeOfConnection))completion
{
__weak ViewController* weak = self;
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert"
message:@"to continue download on the new type of connection"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completion(YES);
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"NO" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completion(NO);
}];
[alert addAction:cancel];
[alert addAction:ok];
[weak presentViewController:alert animated:YES completion:nil];
});
}
Upvotes: 0
Reputation: 7876
You can't.
In your case, the block is executed asynchronously. It means that your method may already have returned when the block is executed.
You need to call another method or send a NSNotification from your blocks to pass your array.
Upvotes: 2
Reputation: 57184
As Quentin already mentioned, you can not directly do that because you are internally performing an asynchronous request. That means that your program starts the request and then continues its next statements and does not wait for the request to finish. What you should do is either
startParsing
method (the same way blocks are used for the actual request callbacks)That would loke for example like the following:
- (void)startParsing:(void (^)(NSArray*))parsingFinished {
allProductsID = [[NSMutableArray alloc] init];
NSString *string = [NSString stringWithFormat:@"http://%@:@%@",kPrestaShopAPIKey, kPrestaShopURLString];
NSURL *url = [NSURL URLWithString:string];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
[manager GET:@"categories/21" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
// do your parsing...
parsingFinished([allProductsID copy]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
parsingFinished([[NSArray alloc] init]);
// or return nil or provide a parsingFailed callback
}];
}
which you would then call like
[yourObject startParsing:^(NSArray *parsedData) {
// do something with the parsed data
}];
Upvotes: 7