ios - Background location updates not resuming after device wakes from hibernation -


i have issue app registering background location updates receives until device hibernates, after device resumes hibernation location updates not resume.

the app very simple test measure effect of location updates on battery life.

i created app using single view application template and:

  • added code posted below app delegate (that's it, no other code)
  • added location updates background mode
  • added corelocation.framework

when launch app move background didupdatelocations: continues called continuously 15-20 minutes , getdatausage() executes every few seconds.

then after 15-20 minutes device hibernates (i'm monitoring activity on organizer's console). after waking device app never receives didupdatelocations: calls.

- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {     self.locationmanager = [[cllocationmanager alloc] init];     self.locationmanager.delegate = self;     self.timethatdatamonitoringstarted = [nsdate date];     self.initialdatavaluesset = no;      cllocationdegrees degreesfilter = 0.1;     [self.locationmanager setheadingfilter: degreesfilter];     self.locationmanager.desiredaccuracy = kcllocationaccuracybest;     self.locationmanager.distancefilter = 10;     [self.locationmanager startupdatinglocation];      [self getdatausage];      return yes; }  - (void) locationmanager:(cllocationmanager *)manager didupdatelocations:(nsarray *)locations {     nslog(@"******************** location didupdatelocations ***************");     static nsdate* previousdate;     static int count = 0;     if (previousdate)     {         nstimeinterval timeinterval = [[nsdate date] timeintervalsincedate:previousdate];         nslog(@" location: count: %d time since last update: %f", ++count, timeinterval);     }     previousdate = [nsdate date]; }  - (void) getdatausage {     nstimeinterval elapsedtime = [[nsdate date] timeintervalsincedate: self.timethatdatamonitoringstarted];     nslog(@"********* getting data usage. elapsed time: %f **************",elapsedtime);     nsarray *data = [self getdatacounters];      nsnumber *wifisentsinceboot = (nsnumber*)data[0];     nsnumber *wifireceivedsinceboot = (nsnumber*)data[1];     nsnumber *wwansentsinceboot = (nsnumber*)data[2];     nsnumber *wwanreceivedsinceboot = (nsnumber*)data[3];      int wifisentsincebootasint      = [wifisentsinceboot intvalue];     int wifireceivedsincebootasint  = [wifireceivedsinceboot intvalue];     int wwansentsincebootasint      = [wwansentsinceboot intvalue];     int wwanreceivedsincebootasint  = [wwanreceivedsinceboot intvalue];      static int initialwifisent;     static int initialwifireceived;     static int initialwwansent;     static int initialwwanreceived;     if (!self.initialdatavaluesset)     {         self.initialdatavaluesset    = yes;         initialwifisent     = wifisentsincebootasint;         initialwifireceived = wifireceivedsincebootasint;         initialwwansent     = wwansentsincebootasint;         initialwwanreceived = wwanreceivedsincebootasint;     }      int wifisentsincelastretrieval     = wifisentsincebootasint - initialwifisent;     int wifireceivedsincelastretrieval = wifireceivedsincebootasint - initialwifireceived;     int wwansentsincelastretrieval     = wwansentsincebootasint - initialwwansent;     int wwanreceivedsincelastretrieval  = wwanreceivedsincebootasint - initialwwanreceived;      uint dataused = wifisentsincelastretrieval + wifireceivedsincelastretrieval + wwansentsincelastretrieval + wwanreceivedsincelastretrieval;     nslog(@"total data: %d", dataused);     [self performselector:@selector(getdatausage) withobject:nil afterdelay:3]; }   - (nsarray *) getdatacounters {     bool   success;     struct ifaddrs *addrs;     const struct ifaddrs *cursor;     const struct if_data *networkstatisc;      int wifisent = 0;     int wifireceived = 0;     int wwansent = 0;     int wwanreceived = 0;      nsstring *name=[[nsstring alloc]init];      success = getifaddrs(&addrs) == 0;     if (success)     {         cursor = addrs;         while (cursor != null)         {             name=[nsstring stringwithformat:@"%s",cursor->ifa_name];             //   nslog(@"ifa_name %s == %@\n", cursor->ifa_name,name);             // names of interfaces: en0 wifi ,pdp_ip0 wwan              if (cursor->ifa_addr->sa_family == af_link)             {                 if ([name hasprefix:@"en"])                 {                     networkstatisc = (const struct if_data *) cursor->ifa_data;                     wifisent+=networkstatisc->ifi_obytes;                     wifireceived+=networkstatisc->ifi_ibytes;                     //  nslog(@"wifisent %d ==%d",wifisent,networkstatisc->ifi_obytes);                     //  nslog(@"wifireceived %d ==%d",wifireceived,networkstatisc->ifi_ibytes);                 }                  if ([name hasprefix:@"pdp_ip"])                 {                     networkstatisc = (const struct if_data *) cursor->ifa_data;                     wwansent+=networkstatisc->ifi_obytes;                     wwanreceived+=networkstatisc->ifi_ibytes;                     //  nslog(@"wwansent %d ==%d",wwansent,networkstatisc->ifi_obytes);                     //  nslog(@"wwanreceived %d ==%d",wwanreceived,networkstatisc->ifi_ibytes);                 }             }              cursor = cursor->ifa_next;         }          freeifaddrs(addrs);     }      return [nsarray arraywithobjects:[nsnumber numberwithint:wifisent], [nsnumber numberwithint:wifireceived],[nsnumber numberwithint:wwansent],[nsnumber numberwithint:wwanreceived], nil]; } 

note i'm using term "hibernation" not refer app state device state. if observe device activity in organizer's console after while device whole starts shut down. i'm calling hibernation don't know actual ios term is, , hibernation don't mean auto-lock , screen sleeping. separate activity after that, i'm presuming telephony , gps chips etc. powering down. anyway after "hibernation" phase has been reached, if resume activity on device when not getting didupdatelocations.

you need move getdatausage method call app delegate method:

- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions 

to cllocationmanager delegate:

- (void) locationmanager:(cllocationmanager *)manager didupdatelocations:(nsarray *)locations 

since everytime location update happens (above delegate called), getdatausage called.

trying use pseudo "for loop" using performselector bad design , cause unpredictable result when app in background mode. need remove line:

[self performselector:@selector(getdatausage) withobject:nil afterdelay:3]; 

i make sure app registered background mode if intend have app run in background.

i @ more details in answer here: ios7 core location not updating


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -