處理 ASIHTTPRequest 多個請求 (Handling ASIHTTPRequest Multiple Requests)


問題描述

處理 ASIHTTPRequest 多個請求 (Handling ASIHTTPRequest Multiple Requests)

I've been struggling with this problem for over a week. And I really need some help.

I am using ASIHTTPRequest to handle three different download requests. The first download request will download from an online .txt file a timestamp. According to that timestamp, it must process how the application will launch.

It will check if a timestamp has been previously saved in NSUserDefaults, if not then this is the first time the app is launched and it will download a JSON feed (using ASIHTTPRequest) and then parse it into Core Data. 

If the stored timestamp matches the online one, then nothing happens since the data is up to date.

If the stored timestmap is older than the online timestamp, then the database will be cleared and redownloaded.

My problem is that in ASIHTTPRequest, before requestFinished gets executed, application:didFinishLaunchingWithOptions gets executed to the end. Now in the beginning of application:didFinishLaunchingWithOptions, I ask ASIHTTPRequest to download the online timestamp. Before application:didFinishLaunchingWithOptions is over, I need to have the online timestamp downloaded and ready to be use. How would I do that? Problem with ASIHTTPRequest is that it starts executing after application:DidFinishLaunchingWithOptions is over.

‑‑‑‑‑

參考解法

方法 1:

Without some code to look at, our answers have to be fairly general. But it sounds to me like you need to change your startup flow completely.

If it's important that your http requests happen in order, you need to call them in order‑‑nested in each other's completion delegate methods. You can use ASIHTTPRequest's .userInfo field to identify the different types of request you're firing.

Your didFinishLaunching method should just do enough to get your first request started (and maybe bring up a "loading" view), then the rest of the app launching work needs to be done in the various requestDidFinish methods.

If you're in control of the website side of things too, you might see how much of this work you can offload to the server code. I prefer to do my work on the biggest iron I can find, which means I usually do my data manipulation in my web app, and just send the results out to the phone.

EDIT: Here's some code to describe what I mean by "nested in each other's completion methods". Note that I just typed this right here, so don't just copy and paste this and expect anything like sensible behavior.

// inside didFinishLaunching
ASIHTTPRequest *myInitialRequest = [ASIHTTPRequest requestWithURL:myNSURL];
myInitialRequest.userInfo = [NSDictionary dictionaryWithObject:@"initial" forKey:@"type"];
myInitialRequest.delegate = self;
[myInitialRequest startAsynchronous];
// and then NOT other setup stuff that depends on this data.


‑requestDidFinish:(ASIHTTPRequest *)request
{
    if ([[request.userInfo objectForKey:@"type"] isEqualToString:@"initial"]) {
        //you just used the userinfo field to differentiate this from other requests
        //do whatever here, and then make your next request HERE.

        ASIHTTPRequest *nextRequest = [ASIHTTPRequest requestWithURL:myNextURL];
        nextRequest.delegate = self;
        nextRequest.userInfo = [NSDictionary dictionaryWithObject:@"next" forKey:@"type"];
        [nextRequest startAsynchronous];
    }
    if ([[request.userInfo objectForKey:@"type"] isEqualToString:@"next"]) {
        // so now you know this is your "next" type request coming back to you.

        // ... so do whatever you do with this, and then HERE do the rest of your
        // app setup and launch business.
    }
}

So you set up a request with a userInfo field that identifies it, and then differentiate the handling of its response based on that field. That's basic to using more than one ASIHTTPRequest in a view controller anyway.

And then your next request is based on the response of the first one‑‑you're launching a second request after learning what you needed to learn from the first one's response content.

By the way, you can also specify the completion handler method, or use the block interface to specify what ASIHTTPRequest does on completion. But I think loading your requests up with identifying userInfo fields and then handling your responses all in one place is the cleanest approach.

方法 2:

You can't do it that way.  The problem you are having is that the request is asynchronous.  You can't change it to be synchronous because if there are any network delays, iOS will terminate the app for taking too long to load.

Put the rest of the application startup code in the completion handler of the request.  When the request is completed, it will call the completion handler.

方法 3:

As Jim rightly pointed, the issue is with asynchronous request to your server. "application:didFinishLaunchingWithOptions" method continues its execution after making a asynchronous server call. Your server request might take some time and by that time "application:didFinishLaunchingWithOptions" method might be out of its loop. So only solution for this to make a synchronous call to the server and make "application:didFinishLaunchingWithOptions" to wait until server respond back with the response and then continue executing the next instruction. You can achieve this using the "startSynchronous" method of ASIHTTPRequest.

(by darkskyDan RayJimSubhash)

參考文件

  1. Handling ASIHTTPRequest Multiple Requests (CC BY‑SA 3.0/4.0)

#asihttprequest #objective-c #iphone #nsurlconnection #ipad






相關問題

遠程服務器上的請求總是失敗 (Request always fail on distant server)

ASIHTTPRequest 緩存我的數據。我不想要任何類型的緩存 (ASIHTTPRequest caches my data. I don't want any kind of cache)

在調用之前釋放了 didFinishSelector ASIHTTPRequest 的自定義委託類 (Custom delegate class for didFinishSelector ASIHTTPRequest being deallocated before called)

Android:在後台上傳/下載文件數量的最佳方式 (Android: best way to upload/download number of files in background)

Ghi giá trị bài đăng trong ASIFormDataRequest (Log Post Value in ASIFormDataRequest)

ASIHTTPRequest - 下載問題 (ASIHTTPRequest - download problem)

ASIHTTPRequest 離線模式連接失敗 (ASIHTTPRequest offline mode connection failure)

ASIHttpRequest 請求:didReceiveBytes:未按預期工作 (ASIHttpRequest request:didReceiveBytes: not working as expected)

如何讓 Ruby on Rails 與 ASIHTTPRequest 一起使用? (How do I get Ruby on Rails to work with ASIHTTPRequest?)

可以指定一個 NSObject 作為多個 ASIHTTPRequests 的代表嗎? (OK to assign one NSObject as the delegate of multiple ASIHTTPRequests?)

需要幫助將 NSXMLParser 與 ASIHTTPRequest 一起使用 (need help using NSXMLParser with ASIHTTPRequest)

處理 ASIHTTPRequest 多個請求 (Handling ASIHTTPRequest Multiple Requests)







留言討論