0

I am rather new to Objective-C development so please be patient!

I am trying to take data from a user & send that information to an external database. I have managed to work out how to push the data rather easily, but the issue is; due to the nature of my application, there is a high probability that the user will have no mobile connectivity while they're using it. How can I continuously check that the user has mobile connectivity, and then send the data when it's connected? My code for the action is below:

(Just to clarify, the action takes 10 readings of signal over 5 seconds, appends them to an array, calculates the average and the updates the location. In turn, the locationManager sends the data to a cloud service including the average signal reading.

    - (IBAction)buttonPressed:(id)sender {

            // Make Manager Delegate & Set Accuracy
            manager.delegate = self;
            manager.desiredAccuracy = kCLLocationAccuracyBest;

            // Call Timer
            myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                                       target:self
                                                     selector:@selector(arrayBuild)
                                                     userInfo:nil
                                                      repeats:YES];

            // Initialise Array
            resultsArray = [[NSMutableArray alloc]init];

    }




    #pragma mark CLLocationManagerDelegate Methods

    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {

            NSLog(@"Error: %@", error);
            NSLog(@"Failed to get location!");

    }


    -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

            NSLog(@"Location: %@",newLocation);

            if (curentLocation != nil) {

                // Code below uses a third party utility to submit data
                PFObject *Object = [PFObject objectWithClassName:@"Issue"];
                Object[@"Latitude"] = [NSString stringWithFormat:@"%.8f",curentLocation.coordinate.latitude];
                Object[@"Longitude"] = [NSString stringWithFormat:@"%.8f",curentLocation.coordinate.longitude];
                Object[@"Signal"] = [NSString stringWithFormat:@"%@",_avgNumber];
                [Object saveInBackground];

                // Update Text Fields
                self.latitude.text = [NSString stringWithFormat:@"%.8f",curentLocation.coordinate.latitude];
                self.longitude.text = [NSString stringWithFormat:@"%.8f",curentLocation.coordinate.longitude];
                self.signal.text = [NSString stringWithFormat:@"%@",_avgNumber];

            }

        // Stop the Location Update
        [manager stopUpdatingLocation];

    }

- (void)arrayBuild {

        loopCount++;

        if (loopCount >= 11) {

            // Find Average
            NSNumber *avg = [resultsArray valueForKeyPath:@"@avg.self"];
            _avgNumber = avg;

            // Change Text of Label to Average & Log
            self.signal.text = [NSString stringWithFormat:@"%@",_avgNumber];
            NSLog(@"%@",_avgNumber);

            // Update Location
            [manager startUpdatingLocation];

            // Invalidate Timer
            [myTimer invalidate];
            myTimer = nil;

        }else{

            // Declare Signal Strength
            float signalstrength = CTGetSignalStrength();

            // Individual Result & Convert to Integer
            NSString *result = [NSString stringWithFormat:@"%f", signalstrength];
            NSInteger resultInt = [result integerValue];

            // Add Object
            [resultsArray addObject:[NSNumber numberWithFloat:resultInt]];

            // Change Text of Label Each Second
            self.signal.text = [NSString stringWithFormat:@"%d",loopCount];
            NSLog(@"%f",signalstrength);

        }

    }
B-B.
  • 183
  • 1
  • 3
  • 14

2 Answers2

3

What you need is called "Network Reachability Monitoring". Once you subscribe to it, your will be notified when there are changes to network connectivity state, i.e. device became online or offline, and even type of current connection (WLAN or WWAN).

There is a sample project from Apple and third-party networking libraries (such as AFNetworking) often provide a convenience class for better experience.

EDIT:: Easier solution is to is to use Parse SDK and their saveEventually method instead of saveInBackground. This will, according to documentation, take care of situations when network is not accessible.

Andrey
  • 1,541
  • 9
  • 12
  • Thank you for the information. I guess the real question is that I'm unsure how to invoke a post action once the device has connection. I do not want to simply use an if/else statement & lose the data if we are not connected. – B-B. Aug 22 '14 at 10:03
  • Typically you would cache data locally, and once there is a network connection you will submit it and delete local copy. However, since you are using Parse, it might be possible their SDK does that for you. Not sure as I never worked with it. – Andrey Aug 22 '14 at 10:07
  • 1
    After looking at their docs, it seems that you can use [`saveEventually`](http://parse.com/docs/ios/api/Classes/PFObject.html#//api/name/saveEventually) and it should handle network inaccessibility for you :) – Andrey Aug 22 '14 at 10:10
  • After reading the Parse docs you were absolutely right. Can't believe I missed it. Thank you very much. *Edit* Just saw your comment :P – B-B. Aug 22 '14 at 10:13
0

There are many question on forum addressing this issue. Apple provides Reachability class for this purpose. You may check This or this question for further clarification.

Community
  • 1
  • 1
Gandalf
  • 2,164
  • 2
  • 13
  • 19