0

I'm new to Objective-C, just wondering how to use NSArray object outside from JSON.

For example:

NSURL *url = [NSURL URLWithString:@"http://acumen-locdef.elasticbeanstalk.com/service/countries"];


NSURLRequest *request = [NSURLRequest requestWithURL:url];

NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response,
                                           NSData *data, NSError *connectionError)
 {
     if (data.length > 0 && connectionError == nil)
     {
         NSMutableArray *greeting = [NSJSONSerialization JSONObjectWithData:data
                                                             options:0
                                                               error:NULL];


         for (NSDictionary *countryList in greeting) {

             [myFinalListArray addObject:countryList[@"name"]];

         }

     }

     NSLog(@"%@",myFinalListArray); //(This one showing all results..)

 }];

 NSLog(@"%@",myFinalListArray); //(This one giving empty result)

I have defined myFinalListArray and added objects in for loop.

If you use NSLog inside the loop or outside the loop it will show you results. But if I use this after }]; (after the code is ending.), it's giving me empty array.

Larme
  • 24,190
  • 6
  • 51
  • 81
Aamir Munir
  • 93
  • 1
  • 9
  • Because sendAsynchronousRequest runs on a separate thread and as you can see it's using a block. myFinalListArray is populated inside the block. – Sreejith Sep 02 '15 at 07:31
  • The code inside is called asynchronously. So when you call NSLog below the async request it is possible that the request isn't finished yet. You have to wait until the asynchronous call has finished. – Bernhard Harrer Sep 02 '15 at 07:32
  • Many thanks for your help, is there any possible solution? actually i really want to use this outside from the block? – Aamir Munir Sep 02 '15 at 07:35
  • You need to learn what *asynchronous* means and how it's implemented in Objective-C projects. Only you can do that. – trojanfoe Sep 02 '15 at 07:37
  • the block execute in second thats why you are get empty value – Anbu.Karthik Sep 02 '15 at 07:38

6 Answers6

0

The block of code associated with sendAsynchronousRequest isn't executed until the network fetch has completed; this takes some time. While the network fetch is happening your code continues to execute, starting with the line immediately after sendAsynchronousRequest which is NSLog(@"%@",myFinalListArray); - but because the network operation hasn't completed you get an empty array.

In the block you need to include the code that you need to process the array, update your user interface or whatever (If you update UI make sure you dispatch the operation on the main thread)

Paulw11
  • 108,386
  • 14
  • 159
  • 186
0

This will work. You can try with this.

- (void)viewDidLoad {
[super viewDidLoad];

NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];
//Pass here the reference the a array. It will return you the array of you county when downloaded complete.
[self getURLResponse:&myFinalListArray];
NSLog(@"countryArray:%@",myFinalListArray);
}


-(void)getURLResponse:(NSMutableArray**)countryArray{
NSURL *url = [NSURL URLWithString:@"http://acumen-locdef.elasticbeanstalk.com/service/countries"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];

NSURLResponse *response;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:
                request returningResponse:&response error:&error];
NSMutableArray *greeting = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
for (NSDictionary *countryList in greeting) {
    [myFinalListArray addObject:countryList[@"name"]];
}
*countryArray = [[NSMutableArray alloc]initWithArray:myFinalListArray copyItems:YES];
}
Jamil
  • 2,977
  • 1
  • 13
  • 23
0

If you are accessing myFinalListArray in tableview then you can reload tableview inside the block after fetching data.

Or if you are accessing this array in some other task then you have to make notification call (have to add observer) and then post notification that will call some other method and access your array there and do your further stuff.

Community
  • 1
  • 1
Chetan Prajapati
  • 2,249
  • 19
  • 24
0
-(void)sendRequest
{    
    NSURL *url = [NSURL URLWithString:@"http://acumen-locdef.elasticbeanstalk.com/service/countries"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];
    [NSURLConnection sendAsynchronousRequest:request
                               queue:[NSOperationQueue mainQueue]
                   completionHandler:^(NSURLResponse *response,
                                       NSData *data, NSError *connectionError) {
     if (data.length > 0 && connectionError == nil)
     {
         NSMutableArray *greeting = [NSJSONSerialization JSONObjectWithData:data
                                                         options:0
                                                           error:NULL];

        if( !myFinalListArray )
        {
            myFinalListArray=[[NSMutableArray alloc]init];
        }
         for (NSDictionary *countryList in greeting) {

             [myFinalListArray addObject:countryList[@"name"]];

         }

     }

     [self printArray];

    }];
}

//create method that will execute after response
-(void) printArray
{
    NSLog(@"%@",myFinalListArray); //(This one showing all results..)
}
MD.
  • 1,157
  • 11
  • 18
0

Use
__block NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];

This should work.

Happy Coding.

shoan
  • 1,303
  • 15
  • 22
0

sendAsynchronousRequest runs asynchronously, meaning that the code below is already performed while the request is still running, so the NSLog is logging the empty array. Only when the request finishes, the array is filled up but your outer NSLog was already performed.

MarkHim
  • 5,686
  • 5
  • 32
  • 64