5
\$\begingroup\$

I am wanting to constantly check a URL http://www.example.co.uk/untitled.php which will either return 1 or 0 on my app.

Is the most efficient way to do it by repeatedly requesting the URL every second like this?

Function to return content of URL

-(void)getOnline{
    if(connected==0){
        NSString *uuid = @"59xxxfb6d-4659-gdsf-sfsdf";

        NSString *URL = [NSString stringWithFormat:@"%@%@", @"http://www.example.co.uk/untitled.php?=", uuid];
        NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        [[aSession dataTaskWithURL:[NSURL URLWithString:URL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            if (((NSHTTPURLResponse *)response).statusCode == 200) {
                if (data) {
                    NSString *contentOfURL = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                    if([contentOfURL isEqual: @"1"]){
                        //do stuff
                    }
                }
            }
        }] resume];
    }
}

Function on load to repeatedly call the function above

[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(getOnline) userInfo:nil repeats:YES];
\$\endgroup\$
1
  • \$\begingroup\$ You may want to look into long polling, as you wouldn't have to send a request every time. Send a request, and wait for PHP to return. Event based. \$\endgroup\$ Commented Aug 9, 2015 at 0:59

1 Answer 1

6
\$\begingroup\$

If you want a UUID, generate one. What you have isn't a UUID. It's just a string of random numbers.

If you want to reuse a once-generated UUID multiple times, you can do that.

static NSString * const uuid = [NSUUID UUID].UUIDString;

If you're calling a variable URL, it should actually be a NSURL object and not an NSString object.

And nesting the method call that actually wraps it into an NSURL doesn't do anything but reduce readability.

So perhaps, we really want something like this:

static NSString * const uuid = [NSUUID UUID].UUIDString;
static NSString * urlString = [NSString stringWithFormat:@"%@%@", @"http://www.example.co.uk/untitled.php?=", uuid];
static NSURL * url = [NSURL URLWithString:URL];

Finally, we have a problem with our timer here.

Here's the timer code you show:

[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(getOnline) userInfo:nil repeats:YES];

The problem is that this timer repeats, and it's firing an asynchronous task.

Now, I'd certainly look into JavaProphet's comment about long polling versus sending repeated requests, but I do want to address the issue you have here.

What happens if it takes the second more than one second to reply to a request? More importantly, what if the server replies to three requests in a row in under one second, the fourth takes over two seconds, and the fifth goes back to taking less than a second?

We can easily get the responses out of order because we're not waiting around for the server to tell us.

Rather than a repeating timer, we need a timer that is rescheduled after every fire. We don't want to ask the server every single second. We simply want to wait for one second since the last poll before we ask again.

Any time we're using a repeating timer, we must stop and answer this question:

Do we really want this event to fire every , or do we actually want this event to fire since the end of the last event?

Importantly, when we pick the latter, it makes it impossible for two (or several more) of the events to be going at the same time. So when we stop the timer, the most amount of asynchronous events that could be out in some background waiting to come back is just one. Using your approach, the number of events that could still fire back after we invalidate the timer is only a function of however long the timeout is.

If the server suddenly stopped responding and you had a 5 minute time out, and you waited until the first "The server timed out" response before you stopped the timer, there'd be 5 minutes-worth of these events still off in a background thread waiting for the server's reply, so you'd get hit with the "The server timed out" response 300 times before it was actually fully stopped.

\$\endgroup\$
1

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.