你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS若何堅持法式在後台長時光運轉

iOS若何堅持法式在後台長時光運轉

編輯:IOS開發綜合

IOS 為了讓裝備盡可能省電,削減不用要的開支,堅持體系流利,因此對後台機制采取墓碑式的“假後台”。除體系官方少少數法式可以真後台,普通開辟者開辟出來的運用法式後台遭到以上限制:

1.用戶按Home以後,App轉入後台停止運轉,此時具有180s後台時光(IOS7)或許600s(IOS6)運轉時光可以處置後台操作

2.當180S或許600S時光曩昔以後,可以告訴體系未完成義務,須要請求持續完成,體系同意請求以後,可以持續運轉,但總時光不會跨越10分鐘。

3.當10分鐘時光到以後,不管怎樣向體系請求持續後台,體系會強迫掛起App,掛起一切後台操作、線程,直到用戶再次點擊App以後才會持續運轉。

固然iOS為了特別運用也保存了一些可以完成“真後台”的辦法,摘取比擬經常使用的:

1.VOIP

2.定位辦事

3.後台下載

4.在後台一向播放無聲響樂(輕易遭到德律風或許其他法式影響,所以暫未斟酌)

5….更多

個中VOIP須要綁定一個Socket鏈接並聲名給體系,體系將會在後台接收這個銜接,一旦遠端數據過去,你的App將會被叫醒10s(或許更少)的時光來處置數據,跨越時光或許處置終了,法式持續休眠。

後台如今是iOS7引入的新API,網上完成的代碼比擬少,博主也沒有仔細去找。

因為博重要做的App須要在後台一向運轉,每隔一段時光給辦事器自動發送新聞來堅持帳號上岸狀況,因此必需確保App不被體系墓碑限制。

博主最早測驗考試了許多辦法,包含同伙發來的一個Demo,每180s後台時光過時就燒毀本身然後再創立一個後台義務,然則現實測試只要10分鐘時光。最初由於斟酌到VOIP對辦事端修改太年夜,時光又太緊,所以選擇了定位辦事的辦法來堅持後台。

要啟動定位辦事:

1.須要引入頭文件:#import

2.在AppDelegate.m中界說CLLocationManager * locationManager;作為全局變量便利掌握

3.在法式啟動早期對定位辦事停止初始化:

locationManager = [[CLLocationManager alloc] init];locationManager.delegate =self;
//or whatever class you have for managing location

​4.在法式轉入後台的時刻,啟動定位辦事

[locationManager startUpdatingLocation];(第一次運轉這個辦法的時刻,假如之前用戶沒有應用過App,則會彈出能否許可地位辦事,關於用戶能否許可,前面代碼中有斷定)

如許在定位辦事可用的時刻,法式會赓續刷新後台時光,現實測試,發明後台180s時光赓續被刷新,到達久長後台的目標。

然則如許應用也有一些成績,在部門機械下面,定位辦事即便翻開也能夠不克不及刷新後台時光,須要完整停止法式再運轉。穩固性不曉得是由於代碼緣由照樣體系某些機制緣由。

上面貼上代碼:

留意:代碼中包括同伙給的demo中,180s時光後燒毀本身再創立本身的後台辦法,我本身完成進程中參加了定位辦事來確保後台可以或許一向在線。

源碼參考部門來自網上,由於翻了Google,找了許多英文方面的博文,在此感激原作者分享。

斷定用戶能否翻開了定位辦事,能否禁用了該法式的定位權限:

if(![CLLocationManager locationServicesEnabled] || ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied))//斷定定位辦事能否翻開
{
   [InterfaceFuncation ShowAlertWithMessage:@"毛病"AlertMessage:@"定位辦事未翻開\n堅持在線須要後台定位辦事\n請到 設置-隱私 中翻開定位辦事"ButtonTitle:@"我錯了"];
   return;
}

​AppDelegate.m源碼:

@property(assign, nonatomic) UIBackgroundTaskIdentifier bgTask;
@property(strong, nonatomic) dispatch_block_t expirationHandler;
@property(assign, nonatomic)BOOL jobExpired;
@property(assign, nonatomic)BOOL background;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
  UIApplication* app = [UIApplication sharedApplication];
  __weak NSUAAAIOSAppDelegate* selfRef =self;
  self.expirationHandler = ^{ //創立後台自叫醒,當180s時光停止的時刻體系會挪用這外面的辦法
    [app endBackgroundTask:selfRef.bgTask];
     selfRef.bgTask = UIBackgroundTaskInvalid;
     selfRef.bgTask = [app beginBackgroundTaskWithExpirationHandler:selfRef.expirationHandler];
     NSLog(@"Expired");
     selfRef.jobExpired =YES;
     while(selfRef.jobExpired)
     {
       // spin while we wait for the task to actually end.
       NSLog(@"期待180s輪回過程的停止");
       [NSThreadsleepForTimeInterval:1];
     }
     // Restart the background task so we can run forever.
     [selfRef startBackgroundTask];
   };
   // Assume that we're in background at first since we get no notification from device that we're in background when
   // app launches immediately into background (i.e. when powering on the device or when the app is killed and restarted)
   [selfmonitorDosBat target=_blank class=infotextkey>BatteryStateInBackground];
   locationManager = [[CLLocationManager alloc] init];
   locationManager.delegate =self;
   //[locationManager startUpdatingLocation];
   returnYES;
}
- (void)monitorDosBat target=_blank class=infotextkey>BatteryStateInBackground
{
   self.background =YES;
   [selfstartBackgroundTask];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
   // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
   NSLog(@"App is active");
   [UIApplication sharedApplication].applicationIconBadgeNumber=0;//撤消運用法式告訴腳標
   [locationManager stopUpdatingLocation];
   self.background =NO;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
   // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
   // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
   //if([self bgTask])
   if(isLogined)//當上岸狀況才啟動後台操作
   {
      self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:self.expirationHandler];
      NSLog(@"Entered background");
      [selfmonitorDosBat target=_blank class=infotextkey>BatteryStateInBackground];
    }
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError*)error//當定位辦事弗成用失足時,體系會主動挪用該函數
{
   NSLog(@"定位辦事失足");
   if([error code]==kCLErrorDenied)//經由過程error的code來斷定毛病類型
   {
      //Access denied by user
      NSLog(@"定位辦事未翻開");
      [InterfaceFuncation ShowAlertWithMessage:@"毛病"AlertMessage:@"未開啟定位辦事\n客戶端堅持後台功效須要挪用體系的地位辦事\n請到設置中翻開地位辦事"ButtonTitle:@"好"];
   }
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations//當用戶地位轉變時,體系會主動挪用,這裡必需寫一點兒代碼,不然後台時光刷新不論用
{
    NSLog(@"地位轉變,必需做點兒工作能力刷新後台時光");
    CLLocation *loc = [locations lastObject];
    //NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining];
    //NSLog(@"Background Time Remaining = %.02f Seconds",backgroundTimeRemaining);
    // Lat/Lon
    floatlatitudeMe = loc.coordinate.latitude;
    floatlongitudeMe = loc.coordinate.longitude;
}
- (void)startBackgroundTask
{
    NSLog(@"Restarting task");
    if(isLogined)//當上岸狀況才進入後台輪回
    {
      // Start the long-running task.
      NSLog(@"登錄狀況後台過程開啟");
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          // When the job expires it still keeps running since we never exited it. Thus have the expiration handler
          // set a flag that the job expired and use that to exit the while loop and end the task.
          NSIntegercount=0;
          BOOLNoticeNoBackground=false;//只告訴一次標記位
          BOOLFlushBackgroundTime=false;//只告訴一次標記位
          locationManager.distanceFilter = kCLDistanceFilterNone;//任何活動均接收,任何活動將會觸發定位更新
          locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;//定位精度
          while(self.background && !self.jobExpired)
          {
              NSLog(@"進入後台過程輪回");
              [NSThreadsleepForTimeInterval:1];
              count++;
              if(count>60)//每60s停止一次開啟定位,刷新後台時光
              {
                  count=0;
                  [locationManager startUpdatingLocation];
                  NSLog(@"開端地位辦事");
                  [NSThreadsleepForTimeInterval:1];
                  [locationManager stopUpdatingLocation];
                  NSLog(@"停滯地位辦事");
                  FlushBackgroundTime=false;
               }
               if(!isLogined)//未登錄或許失落線狀況下封閉後台
               {
                  NSLog(@"堅持在線過程掉效,加入後台過程");
                  [InterfaceFuncation ShowLocalNotification:@"堅持在線掉效,登錄已被刊出,請從新登錄"];
                  [[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
                  return;//加入輪回
               }
               NSTimeIntervalbackgroundTimeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining];
               NSLog(@"Background Time Remaining = %.02f Seconds",backgroundTimeRemaining);
               if(backgroundTimeRemaining<30&&NoticeNoBackground==false)
               {
                   [InterfaceFuncation ShowLocalNotification:@"向體系請求長時光堅持後台掉敗,請停止客戶端從新登錄"];
                   NoticeNoBackground=true;
               }
               //測試後台時光刷新
               if(backgroundTimeRemaining>200&&FlushBackgroundTime==false)
               {
                  [[NSNotificationCenterdefaultCenter] postNotificationName:@"MessageUpdate"object:@"刷新後台時光勝利\n"];
                  FlushBackgroundTime=true;
                  //[InterfaceFuncation ShowLocalNotification:@"刷新後台時光勝利"];
                }
            }
            self.jobExpired =NO;
         });
     }
}

以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐本站。

【iOS若何堅持法式在後台長時光運轉】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved