0

사용자가 원하는 시간에 여러 알림을 예약 할 수있게 해주는 프로젝트 중 하나에서 작업하고 있습니다.iOS 10의 로컬 알림 예약 및 처리

iOS 10은 알림을위한 화재 날짜로 DateComponents를 사용할 수있는 능력을 주었지만 여러 가지 알림을 예약하고 처리하는 방법에 대해서는 다소 분실했습니다.

각 알림에는 자체 요청이 필요하며 차례로 고유 식별자가 필요합니다. 그렇지 않으면 여러 알림을 만들 수 없습니다.

알림을 예약하고 처리하기 위해 식별자를 사용해야한다는 것을 알았지 만, 이제는 내 코드가 이렇게 혼란 스럽기 때문에 더 쉬운 방법이 없는지 직접 묻고 있습니다.

나의 데이터 모델에 따라 통지 고유 식별자로 구성된다

  1. 내 모델의 ID
  2. 새로운 통지
  3. 위 의해 분리되어 생성 될 때마다 증가하는 숫자 밑줄

예를 들어 ID 3 인 객체에 대해 10 개의 알림을 예약해야한다면 다음과 같이 보입니다. 3_1, 3_2, 3_3...

알림을받을 때마다받은 알림을 반복하여 내 UI를 업데이트합니다. 그리고 사용자가 특정 모델에 대해 수신 된 통지를 삭제하고자 할 때, 나는 동일한 ID로 시작하는 식별자를 검사하여 수신 된 통지의 고유 식별자를 반복한다. UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers:)

건은, 모든 만드는 것 :

정말 문서에 따르면, 배달 알림을 삭제하는 유일한 방법은 식별자를 사용하는 것입니다 때문에 그렇지 않으면 그것을 어떻게 관리 할 수 ​​표시되지 않습니다 문제의 종류와 나는 쉽게 그들을 수정할 수있는 동안 그것은 매우 해커 보인다. 나는 내가 한 일에 대해 자랑스럽지 않고 주위를 둘러 보는 더 영리한 방법을 찾고 있습니다. 그게 문제가 아니기 때문에 의도적으로 코드를 게시하지 않았습니다. 이 접근법은 실제 문제입니다.

UserNotifications 프레임 워크가 상당히 새롭고이 주제에 관한 리소스를 찾을 수 없었기 때문에 여기에서 묻습니다.

아이디어가 있으십니까? 미리 감사드립니다.

편집 : 여기에 몇 가지 코드가 있습니다. 모든 보류 및 알림을 전달

checkDeliveredAndPendingNotifications 방법에
@available(iOS 10.0, *) 
    func checkDeliveredAndPendingNotifications(completionHandler: @escaping (_ identifierDictionary: Dictionary<String, Int>) ->()) { 

     var identifierDictionary:[String: Int] = [:] 
     UNUserNotificationCenter.current().getDeliveredNotifications { (notifications) in 

      for notification in notifications { 
       let identifierArraySplit = notification.request.identifier.components(separatedBy: "_") 
       if identifierDictionary[identifierArraySplit[0]] == nil || identifierDictionary[identifierArraySplit[0]]! < Int(identifierArraySplit[1])! { 
        identifierDictionary[identifierArraySplit[0]] = Int(identifierArraySplit[1]) 
       } 
      } 

      UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: { (requests) in 
       for request in requests { 
        let identifierArraySplit = request.identifier.components(separatedBy: "_") 
        if identifierDictionary[identifierArraySplit[0]] == nil || Int(identifierArraySplit[1])! > identifierDictionary[identifierArraySplit[0]]! { 
         identifierDictionary[identifierArraySplit[0]] = Int(identifierArraySplit[1]) 
        } 
       } 
       completionHandler(identifierDictionary) 
      }) 
     } 
    } 


@available(iOS 10.0, *) 
    func generateNotifications() { 
     for medecine in medecines { 
      self.checkDeliveredAndPendingNotifications(completionHandler: { (identifierDictionary) in 
       DispatchQueue.main.async { 
        self.createNotification(medecineName: medecine.name, medecineId: medecine.id, identifierDictionary: identifierDictionary) 
        }      
      }) 
     } 
    } 


@available(iOS 10.0, *) 
    func createNotification(medecineName: String, medecineId: Int identifierDictionary: Dictionary<String, Int>) { 

     let takeMedecineAction = UNNotificationAction(identifier: "TAKE", title: "Take your medecine", options: [.destructive]) 
     let category = UNNotificationCategory(identifier: "message", actions: [takeMedecineAction], intentIdentifiers:[], options: []) 
     UNUserNotificationCenter.current().setNotificationCategories([category]) 

     let takeMedecineContent = UNMutableNotificationContent() 
     takeMedecineContent.userInfo = ["id": medecineId] 
     takeMedecineContent.categoryIdentifier = "message" 
     takeMedecineContent.title = medecineName 
     takeMedecineContent.body = "It's time for your medecine" 
     takeMedecineContent.badge = 1 
     takeMedecineContent.sound = UNNotificationSound.default() 

     let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false) 

     var takeMedecineIdentifier = "" 
     for identifier in identifierDictionary { 
      if Int(identifier.key) == medecineId { 
       let nextIdentifierValue = identifier.value + 1 
       takeMedecineIdentifier = String(medecineId) + "_" + String(nextIdentifierValue) 
      } 
     } 
     let takeMedecineRequest = UNNotificationRequest(identifier: takeMedecineIdentifier, content: takeMedecineContent, trigger: trigger) 

     UNUserNotificationCenter.current().add(takeMedecineRequest, withCompletionHandler: { (error) in 
      if let _ = error { 
       print("There was an error : \(error)") 
      } 
     }) 
    } 

, I는 루프 때문에 나중에 I가 존재하지 않는 식별자를 생성 할 수있다. 각 알림에 대해 고유 한 식별자를 생성하는 또 다른 방법을 찾지 못했습니다.

대부분의 작업이 다른 비동기 대기열에서 수행되므로 작업을 마쳤을 때도 완료 처리기를 만들었습니다. 그런 다음 주 스레드에서 createNotification 메서드를 호출합니다 (왜냐하면 내가 영역을 사용하고 있기 때문에이 작업을해야합니다).

여기서 문제는 비동기로 작업하는 func add(UNNotificationRequest, withCompletionHandler: (Error?) -> Void)? = nil) 메서드입니다.그래서 generateNotifications 내 루프로 다시 checkDeliveredAndPendingNotifications 반환 잘못된 데이터를 갈 때. 잘 잘못되지는

나는 스레딩 총 멍청한 놈과 나는 작업의 이러한 종류 붙어있어 나는 어디로 가야 모르는 ... 통지가 아직 생성되지 않은 단지입니다. 내가 올바른 방법으로 문제에 접근하고 있는지 확신 할 수 없다.

+0

, 그것이 점점 위치를 확인하기 어렵다 원인이 게시물을 몇 가지 코드가 있어야 식별자 같은 지역의 통지에 필요한 것 지저분한 –

+0

, 정확히 무엇을 요구 설명해주십시오 . 어디서 문제가 있습니까? 이걸 보셨습니까? https://www.appcoda.com/ios10-user-notifications-guide/ – xpereta

+0

새'UNUserNotificationCenter'에 손을 얻고 싶은 경우에, 내가 게시 한이 답변을 확인합니다. 후반 답변 http://stackoverflow.com/questions/39713605/getting-local-notifications-to-show-while-app-is-in-foreground-swift-3/39715402#39715402 –

답변

0

당신은 모든 알림을 당신이 필요로 삭제/설정할 수 있습니다. Objc c와 swift 모두에 대해이 허용 된 대답을 살펴보십시오. 정말 문제를 이해하지 못하는

How to schedule a local notification in iOS 10 (objective-c)

+0

나는 각 통지에 대해 특정 식별자를 생성하여 특정 문제에 봉착했습니다. 내 대답을 업데이트했습니다. 너무 모호한 것에 대해 유감입니다. – Croisciento