2016-06-05 8 views
1

이벤트를 기록하기 위해 도청 할 수있는 Apple Watch 앱이 있습니다. 이벤트가 기록되면 앱에서 보류중인 모든 로컬 알림을 취소하고 싶습니다. 문제는 때때로 로컬 알림이 취소되고 다른 시간은 취소되지 않는 것입니다.iPhone에서 페어링 된 Apple Watch (때로는)에서 메시지를 수신하면 로컬 알림이 취소되지 않음

여기 시계 앱의 코드가 있습니다. 버튼을 탭하면, 나는 아이폰 앱에 메시지를 보내 AppDelegate에에서

func buttonTapped() { 

    // check to make sure the session is reachable, so a message can be sent 
    if session.reachable == true { 

     // a dict containing the date of the event to be sent to the iPhone 
     let dict = ["date" : NSDate()] 

     // send the dict and specify the replyHandler 
     session.sendMessage(dict, replyHandler: { (reply) in 

       if reply["success"] as? Bool == true { 

        print("notifications were cancelled") 
       } 

      }, errorHandler: { (error) in 

       // some kind of error has occurred 
      } 
     ) 
    } 
} 

을 아이폰에, 나는 알림이 지워지지 어디 메시지를받을 수있는 WatchConnectivity 위임 방법을 구현했습니다. 그런 다음, replyHandler는 메시지가 성공적으로 수신 및 처리 된 시계 응용 프로그램에 표시하기 위해 호출됩니다 나는 성공적인 응답이 시계에 돌아온 것을 볼에도

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) { 

    if message["date"] != nil { 

     dispatch_async(dispatch_get_main_queue()){ 

      let reply = ["success" : true] 

      UIApplication.sharedApplication().cancelAllLocalNotifications() 

      // send the reply to the Watch to confirm all this has happened 
      replyHandler(reply) 
     } 
    } 
} 

, 로컬 알림 실제로 가끔 없습니다 취소 된.

이것이 iOS 또는 watchOS 버그 일 가능성이 높으며 해결할 수있는 방법이 아닌 것 같습니까? 앱이 백그라운드에서 실행될 때 특정 API에 액세스 할 수 있다고 보장하지 않을 수 있습니까? (WatchConnectivity로 메시지를 보낼 때 어떤 일이 일어나는 것 같습니다)

답변

1

이 방법으로 AppDelegate에서 메시지를 받으면 멀티 태스킹 화면에 나타나지 않더라도 앱이 백그라운드에서 실행됩니다). 그러나 iOS에 배경 시간을 명시 적으로 묻지 않았기 때문에 didReceiveMessage의 코드가 항상 완전히 실행되지는 않았습니다.

해결 방법은 특별히 백그라운드 시간을 요구하는 것입니다.

// initialize a background task identifier 
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid 

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) { 

    if message["date"] != nil { 

     dispatch_async(dispatch_get_main_queue()){ 

      // begin the background task 
      self.backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithName("CancelNotifications", expirationHandler: { 

       // this expirationHandler will be called to end and invalidate the background task in case it doesn't have enough time to complete 

       UIApplication.sharedApplication().endBackgroundTask(self.backgroundTask) 
       self.backgroundTask = UIBackgroundTaskInvalid 
      }) 

      let reply = ["success" : true] 

      UIApplication.sharedApplication().cancelAllLocalNotifications() 

      // send the reply to the Watch to confirm all this has happened 
      replyHandler(reply) 

      // let iOS know the background task is done 
      UIApplication.sharedApplication().endBackgroundTask(self.backgroundTask) 
      self.backgroundTask = UIBackgroundTaskInvalid 
     } 
    } 
} 

빅 데이비드 월시, creator of HeartWatch (멋진 애플 시계와 아이폰 응용 프로그램)에 감사하는 방법이 문제를 해결하기 위해 저를 보여주는 : 여기가 작업을 진행하게 didReceiveMessage을 변경하는 방법입니다!