Understanding When http Requests (GETs) on ios

Asked 1 years ago, Updated 1 years ago, 133 views

I'm a beginner in the program.
I would like to call the getFlag method in viewDidLoad, retrieve information from the server asynchronously, and use the value in viewWillAppear, but the code below sets the value to isFlag.
The timing is slow and the viewWillAppear does not run in time.
What should I do in this case?

@interfacehogeViewController(){
    BOOL isFlag; 
}

- (void) viewDidLoad{
    superviewDidLoad;

    self getFlag;
}

-(void)viewWillAppear:(BOOL)animated{
    super viewWillAppear: animated;

    if(isFlag){
        ...
    } else {
        ...
    }
}

-(void)getFlag{
    NSUserDefaults* defaults = NSUserDefaults standardUserDefaults;

    NSSstring* serverInfo_=nil;
    serverInfo_= [NSString stringWithFormat:@"https://%@", WebServerInfo];
    NSSstring*mediaApi=[serverInfo_stringByAppendingFormat:@"/api/hoge/";

    NSURL*url_= NSURL URLWithString: mediaApi;
    [request setHTTPMethod:@"GET";

    NSURLConnection sendAsynchronousRequest:request
                                    queue —NSOperationQueue mainQueue
                        completionHandler:^(NSURLResponse*response, NSData*data, NSError*error){
                            if(data){
                                isFlag = true;
                            }
                        }];
}

ios xcode objective-c

2022-09-30 21:32

2 Answers

Hello!

I think the wrong approach is to use asynchronous, i.e., data in viewWillAppear that you don't know when to return.As you know, viewWillAppear is a method called just before the view is displayed, so it doesn't wait for getFlag to finish.

If you really want to use viewWillAppear, I think you have no choice but to synchronize instead of asynchronous!


2022-09-30 21:32

Nice to meet you.Like Kosuke Ogawa, I think it would be desirable to complete data retrieval before displaying hogeView, but sometimes hogeView is the first view that the application started.
So, I thought about two ways to change the behavior with the value from the server without changing the current source as much as possible.

  • The first is how to retrieve data in synchronization.

This can be done by modifying -(void)getFlag and

 - (void) getFlag
{
    NSSstring* serverInfo_=nil;
    serverInfo_= [NSString stringWithFormat:@"https://%@", WebServerInfo];
    NSSstring*mediaApi=[serverInfo_stringByAppendingFormat:@"/api/hoge/";

    NSURL*url_= NSURL URLWithString: mediaApi;
    NSData*data=[NSDataDataWithContentsOfURL:url];

    if(data)
    {
        // Data is not empty
    }
    else
    {
        // When data is empty
    }// end if data
}// end-(void)getFlag
  • Another way to wait for the synchronization process to complete

This is the first method, but the waiting time is the same, so let's get used to asynchronous transfer.
Of course, it's more troublesome than the former.

First, prepare a flag for the member variable to indicate whether the transfer is complete and initialize it.

@interfacehogeViewController(){
    BOOL isFlag; 
    BOOL getDataDone;// Flag to wait for transfer completion
}

- (void) viewDidLoad{
    superviewDidLoad;

    getDataDone=NO;// Initialize transfer completion flag before retrieving data
    self getFlag;
}

Next, set this flag when the asynchronous completion handler completes data retrieval.

[NSURLConnection sendAsynchronousRequest:request]
                                queue —NSOperationQueue mainQueue
                    completionHandler:^(NSURLResponse*response, NSData*data, NSError*error){
                        if(data){
                            isFlag = true;
                        }
                        getDataDone=YES; // Flag Transfer Completion at the End of the Completion Handler
                    }];

Then wait for the completion handler to finish in viewWillAppear

-(void)viewWillAppear:(BOOL)animated{
    super viewWillAppear: animated;

        // The process of waiting for the transfer to complete.
    while(!getDataDone)
    {
        NSThread sleepTimeInterval:0.1;
    } // end while getDataDone become true
         // If getDataDone is YES, proceed to the next line.
    if(isFlag){
        ...
    } else {
        ...
    }
}

I'm sorry, but I haven't checked the operation, so please add a __block declaration to the variable if necessary


2022-09-30 21:32

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.