Question

Below is the code that I've employed to activate a NSTimer that should run forever. However, when I actually run the code, the loop only executes once. This may have to do with the fact that the activation for the timer is nested in the success and failure operation of the AFHTTPRequestOperation, a part of the AFNetworking API. Why wouldn't it run through multiple times, and not just stop on the first run?

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSDictionary *parameters = @{@"size": size, @"city": city, @"delay": delay, @"evacuation": evacuation, @"evacuation_time": evacuation_time, @"serialNumber": serialNumber};
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    [manager.requestSerializer setValue:@"Content-Type" forHTTPHeaderField:@"application/json"];
    [manager POST:@"INSERT_WEBSITE_HERE" parameters:parameters
    success:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         NSLog(@"%@", responseObject[@"identifier"]);

         _active.title = [NSString stringWithFormat:@"Activated"];
         _help.title = [NSString stringWithFormat:@"Cancel"];

         // start timer after authentication is given
         [self checkForAuthenticationTimerRun];
     }
    failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         NSLog(@"Error: %@", error);

         // DELETE AFTER CONFIRMATION OF TEXT WORKING
         [self checkForAuthenticationTimerRun];
         // DELETE AFTER CONFIRMATION OF TEXT WORKING

         _active.enabled = YES;
         _active.title = [NSString stringWithFormat:@"Activate"];

//         _seconds.hidden = YES;
//         _secondsToAlert.hidden = YES;

//         _directions.hidden = NO;
//         _magnitudeDirectionsLabel.hidden = NO;
//         _magnitudeSlider.hidden = NO;
//         _delayDirectionsLabel.hidden = NO;
//         _delaySlider.hidden = NO;
//         _locationDirectionsLabel.hidden = NO;
//         _locationDirectionsButton.hidden = NO;
//         _evacuationDirectionsLabel.hidden = NO;
//         _evacuationControl.hidden = NO;
//         _evacuationTimerDirectionsLabel.hidden = NO;
//         _evacuationTimerSlider.hidden = NO;
//         _dataLabel.hidden = NO;
//         _magnitudeDataLabel.hidden = NO;
//         _locationDataLabel.hidden = NO;
//         _delayDataLabel.hidden = NO;
//         _evacuationDataLabel.hidden = NO;
//         _evacuationTimerDataLabel.hidden = NO;
//         _magnitudeLabel.hidden = NO;
//         _locationLabel.hidden = NO;
//         _delayLabel.hidden = NO;
//         _evacuationLabel.hidden = NO;
//         _evacuationTimerLabel.hidden = NO;

         UIAlertView *failureAlert = [[UIAlertView alloc]
                                      initWithTitle:@"Failure"
                                      message:@"The application failed to connect to the server."
                                      delegate:nil
                                      cancelButtonTitle:nil
                                      otherButtonTitles:@"Ok", nil];

         [failureAlert show];
     }];
}

- (void)checkForAuthenticationTimerRun
{
    int delay = self->delayTime;

    _seconds.text = [NSString stringWithFormat:@"%d", delay];
    NSLog(@"%d", delay);

    delay = delay - 1;
}

- (void)checkForAuthenticationSetTimer
{
    // runs through code every 1 second(s)
    missionCompleteTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkForAuthenticationTimerRun) userInfo:nil repeats:YES];
}

EDIT: For those of you asking, this is how I declared missionCompleteTimer in the .h file:

{
    NSTimer *missionCompleteTimer;
}
Était-ce utile?

La solution

@user3386109 is probably right here. You're calling checkForAuthenticationTimerRun in the success block where you probably mean to call checkForAuthenticationSetTimer. You're seeing it run once because you're calling the checkForAuthenticationTimerRun method directly (not from the timer).

Using better names may help you avoid problems like this in the future. For example, in this case, I would call the timer checkForAuthenticationTimer, and use three methods:

- (void)makeCheckForAuthenticationTimer
- (void)killCheckForAuthenticationTimer
- (void)checkForAuthenticationTimerFired:(NSTimer*)timer

Then each method is clear and clearly linked to the timer variable. Note also the checkForAuthenticationTimerFired method takes the timer as a parameter. This lets you verify that the correct timer fired.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top