0

I'm triyng to get array from server. But it doesn't work. I'm mean in the function everything is okay with my array but out of it it's null. How to fix?

for(int i=1; i<5; i++){

    NSString *category = [NSString stringWithFormat:@"%d",i];
    NSString *encrypt = @"encrypt=93mrLIMApU1lNM619WzZje4S9EeI4L2L";
    NSString *latitude = @"latitude=32.794044";
    NSString *longtitude = @"longitude=34.989571";
    NSString *params = [NSString stringWithFormat:@"%@&category=%@&%@&%@&area=CENTER",
                    encrypt,category,latitude,longtitude];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:@"http://admin.t-club.co.il/api/get-buissness"]];
    NSData *postBody = [params dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:postBody];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError)
    {
    if(!connectionError)
    {
        _myDict =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        _tmpArray = [_myDict objectForKey:@"result"];
        NSLog(@"my array %@",_tmpArray);//here array isn't null
    }

    }];

    [_myArray addObjectsFromArray:_tmpArray];

     }

NSLog(@"my array %@",_tmpArray);//here is null

2 Answers 2

1

It looks like what you're aiming for is to make several async requests in sequence. This can be done by adding a little abstraction.

First, a method that makes just one request and provides a dictionary in response of the parsed JSON result...

- (void)makeRequestWithParams:(NSString *)params completion:(void (^)(NSDictionary *, NSError *))completion {
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:@"http://admin.t-club.co.il/api/get-buissness"]];
    NSData *postBody = [params dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:postBody];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
         if(!connectionError) {
             NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
             completion(dictionary, nil);
         } else {
             completion(nil, connectionError);
         }
     }];
}

Please note that the NSURLConnnection methods have been replaced by NSSession, so this code will need to change to that soon.

Now something that calls that first method over and over. This one takes an array of request parameters as input, fills a mutable array with the dictionary results, and calls a completion block when its done...

- (void)makeManyRequestsWithParams:(NSArray *)arrayOfParams fillingArray:(NSMutableArray *)result completion:(void (^)(BOOL))completion {

    if (arrayOfParams.count == 0) return completion(YES);

    NSString *nextParams = arrayOfParams[0];
    [self makeRequestWithParams:nextParams completion:^(NSDictionary *dictionary, NSError *error) {
        if (!error && dictionary) {
            [result addObject:dictionary];
            NSArray *remainingParams = [arrayOfParams subarrayWithRange:NSMakeRange(1, arrayOfParams.count-1)];
            [self makeManyRequestsWithParams:remainingParams fillingArray:result completion:completion];
        } else {
            completion(NO);
        }
    }];
}

Finally, your original loop's job is now limited to just assembling the parameters. Once those are in an array, call to make the requests...

- (void)test {
    NSMutableArray *arrayOfParams = [NSMutableArray array];
    for(int i=1; i<5; i++){

        NSString *category = [NSString stringWithFormat:@"%d",i];
        NSString *encrypt = @"encrypt=93mrLIMApU1lNM619WzZje4S9EeI4L2L";
        NSString *latitude = @"latitude=32.794044";
        NSString *longtitude = @"longitude=34.989571";
        NSString *params = [NSString stringWithFormat:@"%@&category=%@&%@&%@&area=CENTER",
                            encrypt,category,latitude,longtitude];
        [arrayOfParams addObject:params];
    }
    NSMutableArray *result = [NSMutableArray array];
    [self makeManyRequestsWithParams:arrayOfParams fillingArray:result completion:^(BOOL success) {
        if (success) {
            NSLog(@"all done, result is %@", result);
        } else {
            NSLog(@"sadness");
        }
    }];

    // don't expect results to be ready here.  they won't be.
    // see how they are logged above in the completion block?
}
Sign up to request clarification or add additional context in comments.

Comments

1

NSURLConnection sendAsynchronousRequest is asynchronous meaning it will be moved to a background thread and execution will continue without waiting for the task to complete. So by the time it gets to your bottom NSLog, the request will still be processing and the value of _tmpArray will be null.

You can use sendSynchronousRequest to have the request complete before moving on.

http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/#synchronous

3 Comments

how can I make delay until array will be full?
I like your original answer, but not the edit. Don't block the main with sendSynchronousRequest, especially in a loop. The OP needs advice on how to preform these requests asynchronously AND serially.
@DenisWindover - don't block! It makes users confused and mad :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.