ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS] BackgroundTasks Framework ๊ฐ„๋‹จ ์ •๋ฆฌ
    ๊ณต๋ถ€/iOS 2020. 2. 24. 07:55

    ๋ชฉ์ฐจ 

    1. BackgroundTasks Framework?
    2. ๋ฌด์—‡์„ ์ง€์›ํ•˜๋Š”๊ฐ€
    3. ์ฃผ์˜ ์‚ฌํ•ญ
    4. ๊ฐ„๋‹จํ•˜๊ฒŒ ์จ๋ณด์ž!
    5. ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ธฐ
    6. ์ฐธ๊ณ  ๊ธ€๊ณผ ๋” ๋ณด๋ฉด ์ข‹์„ ๊ฒƒ๋“ค

    1. BackgroundTasks Framework?

    https://developer.apple.com/documentation/backgroundtasks

     

    ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์‹œ์Šคํ…œ์—๊ฒŒ ์š”์ฒญํ•˜๋Š” ๊ฑธ ๋„์™€์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์—์š”.

    ๊ฐ„๋‹จํ•œ ์„œ๋ฒ„ ํ˜ธ์ถœ > ๋ฆฌํ”„๋ ˆ์‰ฌ ์ž‘์—…๋ถ€ํ„ฐ, ์—๋„ˆ์ง€๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ์š”๊ตฌํ•˜๋Š” ์ž‘์—…๋„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ด์š”.

     

    iOS 13๋ถ€ํ„ฐ ์ง€์›. 13 ์ดํ›„์˜ ๋ฒ„์ „์€ ์ด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๊ณ  ํ•ด์š”.

    setMinimumFetchInterval๋Š” deprecated ๋˜์–ด๋ฒ„๋ ธ๋„ค์š” ๐Ÿฅบ

    2. ๋ฌด์—‡์„ ์ง€์›ํ•˜๋Š”๊ฐ€

    ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. 

    ์ž‘์—…์˜ ๋ณต์žก๋„์™€ ์—๋„ˆ์ง€ ์–‘์— ๋”ฐ๋ผ ๋‘ ๊ฐ€์ง€ ๋ชจ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

     

    1. App Refresh Task

    ๊ฐ€๋ฒผ์šด ์ž‘์—…. ๋‹จ์ˆœ API ํ˜ธ์ถœ ๋ฐ ์ €์žฅ. ์‚ฌ์šฉ์ž๊ฐ€ ํฐ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์‹œ๊ฐ„(๋ณดํ†ต ๋‚ฎ)์—๋„ ์‹คํ–‰ํ•ด์ค€๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

     

    2. Processing Task

    DB๋“ฑ ํฌ๊ณ  ๋ฌด๊ฑฐ์šด ์ž‘์—… ํ•  ๋•Œ ์‚ฌ์šฉ. ์˜ต์…˜ ์ค‘ ์ถ”๊ฐ€ ๋ฐฐํ„ฐ๋ฆฌ๋ฅผ  ์‚ฌ์šฉํ•˜๋Š”๊ฐ€, ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€ ๋“ฑ์˜ ์š”์†Œ๋„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋ฌด๊ฑฐ์šด ์ž‘์—…์ด๊ธฐ ๋–„๋ฌธ์—, ๋ณดํ†ต ์•ฑ์ด ์ถฉ์ „ ์ค‘์ด๊ณ , idle ํ•  ๋•Œ (์•” ๊ฒƒ๋„ ์•ˆ ํ•˜๊ณ  ๋†€๊ณ  ์žˆ์„ ๋•Œ) ์‹คํ–‰์‹œ์ผœ ์ค€๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

     

    3. ์ฃผ์˜ ์‚ฌํ•ญ

    - ์ผ์ •ํ•œ ์‹œ๊ฐ„์— ํ˜ธ์ถœ๋˜์ง€ ์•Š์Œ (์‹œ์Šคํ…œ์—์„œ ํŒ๋‹จํ–ˆ์„ ๋•Œ ๋ฐฐํ„ฐ๋ฆฌ, ๋ฉ”๋ชจ๋ฆฌ ์ƒํ™ฉ์ด ๊ดœ์ฐฎ์„ ๋•Œ, ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ด ์•ฑ์„ ์–ธ์ œ ๋ณดํ†ต ์ผœ๋Š”์ง€ ํ•™์Šตํ•ด ๊ทธ ์ „์— ํ˜ธ์ถœํ•จ = ์•Œ ์ˆ˜ ์—†์Œ)

    - ์‚ฌ์šฉ์ž๊ฐ€ ์ผ์ฃผ์ผ ๋™์•ˆ ์•ฑ์„ ์ผœ์ง€ ์•Š์œผ๋ฉด ๋” ์ด์ƒ Background Fetch๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Œ.

    - UI ์กฐ์ž‘ ๋…ธ๋…ธ! ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ์„œ ํฌ๋ž˜์‹œ ๋‚จ. (๋„คํŠธ์›Œํฌ ์ธ๋””์ผ€์ดํ„ฐ๋„ ์•ˆ๋จ... ์–ด๋–ป๊ฒŒ ์•„๋ƒ๊ณ ์—ฌ? ์ €๋„ ์•Œ๊ณ  ์‹ถ์ง€ ์•Š์•˜์–ด์š”..)

    ์ด๋Ÿฐ ์ด๋ฆ„์˜ ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค :)

    4. ๊ตฌํ˜„ํ•ด๋ณด์ž!

    ์• ํ”Œ ์˜ˆ์ œ๊ฐ€ ์ž˜ ๋˜์–ด ์žˆ์–ด์„œ ์ฝ”๋“œ์™€ ์˜ˆ์ œ๋Š” ๊ทธ๋Œ€๋กœ ๋“ค๊ณ  ์™”์Šต๋‹ˆ๋‹ค. 

     

    1. ์•ฑ์—๊ฒŒ Background Fetch, Background Processing ๊ถŒํ•œ์„ ์ค๋‹ˆ๋‹ค.

    ์ถœ์ฒ˜ : https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler

     

    2. Info.plist์— BGTaskSchedulerPermittedIdentifiers๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    ์•„๋ž˜์— ๋ณด์ด๋Š” Permitted background task scheduler Identifiers ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋ฐฐ์—ด๋กœ, ๊ฐ ์š”์†Œ์— ์‹คํ–‰ํ•  task์˜ Identifier๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

     

    ์ถœ์ฒ˜ : https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler

     

    3. ์œ„์— ์„ ์–ธํ•œ task์˜ Identifier๋กœ task๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ์ œ์—์„œ์˜ ์‹œ์ ์€ didFinishLaunchingWithOptions๋„ค์š”. 

     

      //AppDelegate
      
      //์•ฑ ๋Ÿฐ์นญ
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
           
           //์˜ˆ์ œ ์„œ๋ฒ„์—์„œ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๊ฐ–๊ณ ์˜ค๊ณ  ํ•˜๋Š” ๋ถ€๋ถ„. ์ƒ๋žตํ•จ.
            
            // ์—ฌ๊ธฐ์„œ๋Š” ํƒœ์Šคํฌ๋ฅผ ๋“ฑ๋กํ•ด์ค๋‹ˆ๋‹ค. ์Šค์ผ€์ค„ํ•˜๋Š” ๊ฑด ๋ณ„๋„ ์—์š”!
            BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.apple-samplecode.ColorFeed.refresh", using: nil) { task in
        
                //์‹ค์ œ๋กœ ์ˆ˜ํ–‰ํ•  ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋™์ž‘ ๊ตฌํ˜„
                //๋‚˜์ค‘์— ์Šค์ผ€์ฅด ํ•  ๋•Œ, ํ•ด๋‹น ํƒœ์Šคํฌ์˜ ํด๋ž˜์Šค๋ฅผ ์•Œ๊ณ  ๋“ฑ๋ก์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‹ค์šด ์บ์ŠคํŒ…์ด ๊ฐ€๋Šฅํ•ด์š”.
                self.handleAppRefresh(task: task as! BGAppRefreshTask)
            }
        
            BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.apple-samplecode.ColorFeed.db_cleaning", using: nil) { task in
                
                // Downcast the parameter to a processing task as this identifier is used for a processing request.
                self.handleDatabaseCleaning(task: task as! BGProcessingTask)
            }
    
            return true
        }
       
       
       //์‹ค์ œ๋กœ ํƒœ์Šคํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ณณ์—์„œ๋Š” ๋‘ ๊ฐ€์ง€๋ฅผ ์‹ ๊ฒฝ์จ ์ฃผ์„ธ์š”.
       // task.expirationHandler ๊ตฌํ˜„
       // ์ž‘์—…์˜ ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋˜์—ˆ๋“ , task.setTaskCompleted(success: ์ž‘์—… ์„ฑ๊ณต ์—ฌ๋ถ€) ํ˜ธ์ถœํ•˜๊ธฐ.
       func handleAppRefresh(task: BGAppRefreshTask) {
    
    		//๋‹ค์Œ ๋™์ž‘์„ ๋˜ ์Šค์ผ€์ฅด ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต ์ˆ˜ํ–‰ ์‹œ ํ•„์š”ํ•˜๊ฒ ์ฃ ?
            //์Šค์ผ€์ฅด ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋Š” ์ด ์ฝ”๋“œ ๋ธ”๋Ÿญ ์ดํ›„์— ๋‚˜์˜ต๋‹ˆ๋‹ค!
    		scheduleAppRefresh()
            
            let queue = OperationQueue()
            queue.maxConcurrentOperationCount = 1
            
            let context = PersistentContainer.shared.newBackgroundContext()
            let operations = Operations.getOperationsToFetchLatestEntries(using: context, server: server)
            let lastOperation = operations.last!
            
            
            //๋•Œ์— ๋”ฐ๋ผ์„œ๋Š” ๋„ˆ๋ฌด ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค๋˜๊ฐ€ ํ•ด์„œ ์ข…๋ฃŒ๋  ๋•Œ๊ฐ€ ์žˆ์ฃ . ๊ทธ ๋•Œ๋ฅผ ์œ„ํ•œ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ์—์š”.
            task.expirationHandler = {
            
            	//์˜ˆ์ œ์—์„œ๋Š” OperationQueue๋ฅผ ์‚ฌ์šฉํ•˜๋‹ˆ๊นŒ, ๋ชจ๋“  ๋™์ž‘์„ ์ทจ์†Œํ–ˆ๋„ค์š”.
                queue.cancelAllOperations()
            }
    
    		//์ด ๋ถ€๋ถ„์€ Alamofire์˜ api ressponse ์ฒ˜๋ฆฌ ๋ธ”๋ก ๋“ฑ์ด ๋  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ์˜ˆ์ œ์—์„œ๋Š” Operation Queue๋ฅผ ์‚ฌ์šฉํ–ˆ๋„ค์š”.
            lastOperation.completionBlock = {
            
            //์ž‘์—… ์™„๋ฃŒ ์‹œ, setTaskCompleted๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์ฃผ์„ธ์š”. ๋™๊ธฐ๋กœ ํ˜ธ์ถœ๋  ํ•„์š”๋Š” ์—†์–ด์š”!
                task.setTaskCompleted(success: !lastOperation.isCancelled)
            }
    
            queue.addOperations(operations, waitUntilFinished: false)
        }
        
    
    
    //BGProcessingTask์—์„œ ์ˆ˜ํ–‰ํ•  ๊ฒƒ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์œ„์™€ ๋˜‘๊ฐ™์•„์š”!
    
        func handleDatabaseCleaning(task: BGProcessingTask) {
            let queue = OperationQueue()
            queue.maxConcurrentOperationCount = 1
    
            let context = PersistentContainer.shared.newBackgroundContext()
            let predicate = NSPredicate(format: "timestamp < %@", NSDate(timeIntervalSinceNow: -24 * 60 * 60))
            let cleanDatabaseOperation = DeleteFeedEntriesOperation(context: context, predicate: predicate)
            
            task.expirationHandler = {
                // After all operations are cancelled, the completion block below is called to set the task to complete.
                queue.cancelAllOperations()
            }
    
            cleanDatabaseOperation.completionBlock = {
                let success = !cleanDatabaseOperation.isCancelled
                if success {
                    // Update the last clean date to the current time.
                    PersistentContainer.shared.lastCleaned = Date()
                }
                
                task.setTaskCompleted(success: success)
            }
            
            queue.addOperation(cleanDatabaseOperation)
        }

     

    4. ํƒœ์Šคํฌ๋ฅผ ๋“ฑ๋กํ–ˆ์œผ๋ฉด, ์Šค์ผ€์ฅด ํ•˜์ž!

    ์•ฑ์—์„œ์˜ ์‹œ์ ์€ AppDelegate์˜ applicationDidEnterBackground, ํ˜น์€ ์œ„์˜ ํƒœ์Šคํฌ์˜ ๊ตฌํ˜„ ๋‚ด๋ถ€๋„ค์š”. 

    ํ›„์ž์˜ ๊ฒฝ์šฐ๋Š” ๋ฐ˜๋ณต ์ˆ˜ํ–‰์„ ์œ„ํ•ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋ฌผ๋ก  ์ฃผ๊ธฐ๋Š” ์‹œ์Šคํ…œ์ด ๋ง˜๋Œ€๋ฃจ..)

     

    ์ด๋•Œ, submit์€ synchronousํ•œ ๋ฉ”์†Œ๋“œ์ด๋ฏ€๋กœ, launch ์‹œ์ ์—์„œ submit์„ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ๋‹ค๋ฅธ concurrent queue์—์„œ ๋“ฑ๋ก ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๊ธธ ๊ถŒ์žฅํ•œ๋‹ค๊ณ  ํ•˜๋„ค์š”!

     

        //AppDelegate
        
        //์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์— ๋“ค์–ด๊ฐ”์„ ๋•Œ ํ˜ธ์ถœ ๋จ.
        func applicationDidEnterBackground(_ application: UIApplication) 
        {
            scheduleAppRefresh()
            scheduleDatabaseCleaningIfNeeded()
        }
        
    
    	// ์‹ค์ œ๋กœ ํƒœ์Šคํฌ๋ฅผ ์Šค์ผ€์ค„ ํ•˜๋Š” ๋ถ€๋ถ„.
        
        //BGAppRefreshTaskRequest๋ฅผ ๋งŒ๋“ค์–ด ๋ด…๋‹ˆ๋‹ค
        func scheduleAppRefresh() {
        
      		  //1. ์›ํ•˜๋Š” ํ˜•ํƒœ์˜ TaskRequest๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ๋•Œ, ์‚ฌ์šฉ๋˜๋Š” identifier๋Š” ์œ„์˜ 1, 2๊ณผ์ •์—์„œ ๋“ฑ๋กํ•œ info.plist์˜ identifier์—ฌ์•ผ ํ•ด์š”!
            let request = BGAppRefreshTaskRequest(identifier: "com.example.apple-samplecode.ColorFeed.refresh")
            
            //2. ๋ฆฌํ€˜์ŠคํŠธ๊ฐ€ ์–ธ์ œ ์‹คํ–‰๋˜๋ฉด ์ข‹๊ฒ ๋Š”์ง€ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ setMinimumFetchInterval๊ณผ ๋™์ผํ•˜๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 
            //์—ฌ์ „ํžˆ, ์–ธ์ œ ์‹คํ–‰๋ ์ง€๋Š” ์‹œ์Šคํ…œ์˜ ๋งˆ์Œ์ž…๋‹ˆ๋‹ค...
            request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
            
            
            //3. ์‹ค์ œ๋กœ task๋ฅผ submit ํ•ฉ๋‹ˆ๋‹ค.
            //์ด ๋•Œ ์ฃผ์˜์‚ฌํ•ญ์€, submit์€ synchronousํ•œ ํ•จ์ˆ˜๋ผ, launching ๋•Œ ์‹คํ–‰ํ•˜๋ฉด ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋ฝ ๋  ์ˆ˜ ์žˆ์œผ๋‹ˆ 
            //OperationQueue, GCD๋“ฑ์„ ์ด์šฉํ•ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค๊ณ  ํ•˜๋„ค์š”.
            do {
                try BGTaskScheduler.shared.submit(request)
            } catch {
                print("Could not schedule app refresh: \(error)")
            }
        }
        
        
        //BGProcessingTaskRequest๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ต์…˜์ด ์žˆ๋Š” ๊ฑธ ์ œ์™ธํ•˜๋ฉด ์œ„์™€ ๋™์ผํ•ด์š”.
        func scheduleDatabaseCleaningIfNeeded() {
            let lastCleanDate = PersistentContainer.shared.lastCleaned ?? .distantPast
    
            let now = Date()
            let oneWeek = TimeInterval(7 * 24 * 60 * 60)
    
            // Clean the database at most once per week.
            guard now > (lastCleanDate + oneWeek) else { return }
            
            
            //์ด๋ฒˆ์—” ๋ฌด๊ฑฐ์šด DB ์ž‘์—…์ด๋‹ˆ๊นŒ, BGProcessingTaskRequest๋ฅผ ์Šค์ผ€์ฅด ํ•ด์ค๋‹ˆ๋‹ค.
            let request = BGProcessingTaskRequest(identifier: "com.example.apple-samplecode.ColorFeed.db_cleaning")
            
            //๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ์—ฌ๋ถ€, ์—๋„ˆ์ง€ ์†Œ๋ชจ๋Ÿ‰ ์˜ต์…˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
            request.requiresNetworkConnectivity = false
            request.requiresExternalPower = true
            
            do {
                try BGTaskScheduler.shared.submit(request)
            } catch {
                print("Could not schedule database cleaning: \(error)")
            }
        }

     

    5. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํƒœ์Šคํฌ ์‹คํ–‰ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ธฐ

    ๊ธฐ์กด์˜ Simulate Background Fetch๋กœ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ใ… ใ… ใ…  ์•„๋ž˜ ์ฒ˜๋Ÿผ, ์ง์ ‘ ์ฝ˜์†”์— ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด์ค˜์•ผ ํ•ด์š”.

     

    2020/02/24 - [๊ฐœ๋ฐœ ์‚ฝ์งˆ๊ธฐ/iOS] - [iOS]BackgroundTasks ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, task ์‹คํ–‰, ์ค‘๋‹จ ํ…Œ์ŠคํŠธํ•˜๊ธฐ.

     

    1. BGTaskScheduler์—๊ฒŒ task๋ฅผ submitํ•˜๋Š” ์ฝ”๋“œ ์‹คํ–‰.

    2. ๊ทธ ๋‹ค์Œ ์‹œ์ ์— break point ์žก๊ธฐ

    3. break ํฌ์ธํŠธ๊ฐ€ ๊ฑธ๋ฆฌ๋ฉด ์•„๋ž˜ ๋ช…๋ น์–ด ์ž…๋ ฅํ•˜๊ธฐ.

    4. ๋ฐฑ ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰์‹œ (์œ„ ๊ฐ™์ด didEnterBackground ์‹œ์ ) ์•„๋ž˜ ๋ช…๋ น์–ด ์ž…๋ ฅ ํ›„, ๋‹ค์‹œ ์•ฑ์„ foreground์—์„œ ์‹คํ–‰์‹œ์ผœ ์ฃผ์–ด์•ผ ์ œ๋Œ€๋กœ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

     

    ๋ฐ˜๋“œ์‹œ ์‹ค ๊ธฐ๊ธฐ์—์„œ ์‹คํ–‰์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋””๋ฒ„๊ทธ ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•ด๋‹ฌ๋ผ๊ณ  ๊ฒฝ๊ณ ๊ฐ€ ์žˆ๋„ค์š”.

     

    e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"Info.plist์— ๋“ฑ๋กํ•œ ํƒœ์Šคํฌ Identifier"]

     

    ์œ„ ๋ช…๋ น์–ด๊ฐ€ ์ œ๋Œ€๋กœ ์‹คํ–‰๋˜๋ฉด ์ฝ˜์†”์— ์•„๋ž˜ ๋ฌธ๊ตฌ๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ , ํƒœ์Šคํฌ ๋‚ด์—์„œ์˜ BP๋„ ์žกํž™๋‹ˆ๋‹ค.

     

    Simulating launch for task with identifier ์•„๊นŒ ์‹คํ–‰ ์‹œํ‚จ ํƒœ์ŠคํŠธ Identifier

    Starting simulated task: <BGAppRefreshTask: ์•„๊นŒ ์‹คํ–‰ ์‹œํ‚จ ํƒœ์ŠคํŠธ Identifier>

     

    ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์  ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

     

    ์š”๋Ÿฐ ์ด๋ฆ„์˜ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

    6. ์ฐธ๊ณ  ์ž๋ฃŒ์™€ ๋” ๋ณด๋ฉด ์ข‹์„ ๊ฒƒ๋“ค

    ์‚ฌ์šฉ ์˜ˆ์ œ๊ฐ€ ์ž˜ ๋“œ๋Ÿฌ๋‚œ ๊ธ€

    https://medium.com/snowdog-labs/managing-background-tasks-with-new-task-scheduler-in-ios-13-aaabdac0d95b

     

    WWDC 2019 ์˜ Background Execution ์˜์ƒ

    https://developer.apple.com/videos/play/wwdc2019/707/

    ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ๋Š” ๋ฐ˜๋“œ์‹œ ์‹ค ๊ธฐ๊ธฐ์—์„œ ๋Œ์•„๊ฐ€์•ผ ํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

     

    ์• ํ”Œ ๋ฌธ์„œ

    Background Tasks Framework ์„ค๋ช…

    https://developer.apple.com/documentation/backgroundtasks

     

    Background Task ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ

    https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development

     

    + ๋จผ์ € ๊ณต๋ถ€ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ

    OperationQueue. task๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฐœ๋… ๋“ฑ์€ Operation Queue์—์„œ ์˜จ ๊ฒƒ์ด ๋งŽ์•„ ๋ณด์ž…๋‹ˆ๋‹ค. ์ €๋„ ์ด ๋ถ€๋ถ„ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ์• ๋จน์–ด์„œ... ๊ณต๋ถ€๋ฅผ ์ข€ ๋” ํ•ด์•ผ๊ฒ ๋„ค์š”!

     

    + ์‚ฌ๋‹ด

    ์˜ˆ์ œ ์ฝ”๋“œ์—์„œ ๋ชฉ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“  ๋ฐฉ์‹์ด ๊ฝค๋‚˜ ๋งˆ์Œ์— ๋“ค์–ด์š”. ๋‚˜์ค‘์— ํ…Œ์ŠคํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค ๋–„ ํ•œ ๋ฒˆ ๋”ฐ๋ผํ•ด๋ณผ๊นŒ ํ•ฉ๋‹ˆ๋‹ค. 

    ๋Œ“๊ธ€

Designed by Tistory. @Bola Kim