I have an app with tabbarcontroller. As of now when an async request is being sent on one of the tabs, the user cannot move to another tab. I want my app to function such that when the request is being sent, user is able to move to other tabs and the async request stays is progress still timeout. How can I achieve this?
If you are sending an async request from a view controller, the user will be able to move to another tab. That's the default behaviour. So unless you have built in logic to change that behaviour (i.e. waiting for an async until it has finished). If that's the case, then you should obviously remove that logic.
If that's not the case i suspect you are currently sending a synchronous request (and not an async request as stated in the question). Sending a synchronous request from a view controller would result in the behaviour as described in your issue. So if that's the case, you should rewrite that and make it an async request.
And if you are still unsure, just post your code!
Related
I have a requirement. Some of the screens are not account based. So the users can view them without login. But when they click the "favorite" button. The user will be asked to login in login page. After login, if the user does login, the previous favorite action should be continued. And if the user did not login, the previous action should be stopped.
So I think this an asynchronously login case. The usual synchronous way can not handle this. So my idea is to pass in a login completion block. Like this:
typedef void (^LoginComplete)(NSString *userID);
- (void)getUserIDWithCompletion:(LoginComplete)loginComplete;
Am I right? Or how do u guys usually handle this kind of case?
Usually, all networking is done asynchronously from the developers perspective, aka, completion closures. This is however a synchronous operation for the user, since they are blocked from viewing the rest of the content until the operation continues.
Either way, your approach is good.
I have an iOS app that authenticates to a remote API. The server gives back a token that is used for all the next requests. The authentication call is a simple POST to /api/auth.
My question is: where should I make this call in the app ?
I don't know if I should use it in the AppDelegete (willEnterForeground or didBecomeActive), because it may slow down the app launch. Moreover, this is asynchronous and if I try to make other requests in some controllers while the token hasn't returned, there will be errors.
So I thought about doing it in the root controller, but in the case the app was in the background for a long time and comes to foreground in another controller it doesn't work...
The last option would be to watch errors on every call, and re-authenticate when the server responds with a 'token expired' error. In that case I should probably have a special class for HTTP requests and error handling ?
I don't know what option is the best...
I have a WatchOS2 app which displays data on the watch after calling NSURLSession. Since response takes some time, if the user opens another interface controller another call goes to
- (void)session:(WCSession *)session didReceiveMessageData:(NSData *)messageData replyHandler:(void(^)(NSData *replyMessageData))replyHandler
But if previous api output comes then it returns data through reply. Again the second data output should also be send. So this is giving a crash and my app hangs.
Is there a way to stop the previous reply from being sent by closing the request?
No, there is no way to cancel the previous request. It sounds like you are making the "currently visible interface controller" be the delegate of the WCSession, which would be mixing a lot of responsibilities. Instead I'd suggest adding something like a singleton class that is the permanent delegate of WCSession; and it persists and notifies, or dispatches incoming data to the right place.
I'm trying to call multiple request from the share extension.
The request flow is follows
1. call request one - returns id
2. call request two using request one id
3. call request three using request two id
To make this work, I only have to dismiss the extension sheet after the request three completion.
As per apple documentation we can't hold the extension sheet for a long time. So we have to use the background session for each request and dismiss the extension sheet immediately.
But in my case the requests depends on its previous request completion. So if we dismiss the extension sheet then the OS kills the extension from memory and the request two and three calls never be made.
Is there any way to call these request one by one?
Any suggestion will be helpful. Thanks in advance.
I have an app. In this app, a user can like/unlike something. If the user tap the button like, it would change text to unlike, vice versa.
To make the like/unlike event run seamlessly to user, i change the text first, and then make request to my API, saying that the user like/unlike this. The API decides whether the action is liking or unliking depends on value at database. The API then returns a message stating the action made ("liked"/"unliked"). The app receives it, and then update the UI according to the result, in case the action intended by user fails.
If all runs smoothly, the user won't detect the changes made by API result.
This is the flow of liking something
user like -> button text changes to "unlike"
-> app make a request -> request is queued to operation queue
-> request run -> API decides whether that something is liked/unliked by the user
-> API returns action (in this case, "liked") -> app updates button text ("unlike")
Now my question are:
How do I handle rapid button tap by user?
How do I handle failed requests (internet disconnected, or no signal) while handling the problem no. 1?
nb: I don't want to disable the button (the app has to run seamlessly. Facebook app don't do it either, i just checked). Oh, and I use AFHTTPRequestOperationManager and set its maxConcurrentOperationCount to 1.
I resolved my problem using this answer
with a bit modification. The first time user click the button, I set a request flag to false, so that even if the user click the button many times, request won't be made before the first request is done.