0

私は自分のプロジェクトの1つで、複数の通知を希望する時刻にスケジュールできるようにしています。iOS 10のローカル通知をスケジュールして処理する

iOS 10では、通知の発砲日としてDateComponentsを使用することができましたが、スケジュールの設定や複数の通知の処理方法については迷っています。

各通知には独自の要求が必要であり、次に独自の識別子が必要です。複数の通知を作成することはできません。

私は、通知をスケジュールして処理するために識別子を使用しなければならないと考えましたが、今は自分のコードがこれほど簡単ではないかと真剣に尋ねています。

私のデータモデルによれば、通知固有の識別子がで構成されている:

  1. 私のモデル
  2. 新しい通知が
  3. 上記を区切られ作成されるたびにインクリメントする番号のIDアンダースコア

たとえば、id 3のオブジェクトに対して10個の通知をスケジュールする必要がある場合は、次のようになります。3_1, 3_2, 3_3...

通知を受け取るたびに、受け取った通知をループしてUIを更新します。そして、ユーザが受信した通知を特定のモデルに対して削除したい場合、私は受信した通知の一意の識別子を、同じIDで始まる識別子をチェックすることによってループする。 UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers:)

事がある、それはすべて作成しています:

私は本当にマニュアルに従って、配信通知を削除する唯一の方法は、識別子を使用しているので、私はそれ以外の場合はそれを行うために管理することができるかが表示されません私は簡単にそれらを修正することができますが、それは非常にハッキーに見えます。私は自分のやり遂げたことを誇りに思っていないし、もっと巧みなやり方を模索している。私は意図的にコードを投稿していませんでした。問題ではないからです。このアプローチは本当の問題です。

UserNotificationsフレームワークがかなり新しく、この件について取り組んでいるリソースを見つけることができなかったので、私はここで質問しています。

前もって感謝します。

編集:ここにいくつかのコードがあります。すべての保留中のスルーcheckDeliveredAndPendingNotifications方法、Iループで

@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が存在しない識別子を作成することができるので、後に、通知を配信。私は、通知ごとに一意の識別子を生成する別の方法を発見していません。

ほとんどの作業は別の非同期キューで行われるため、仕事を終えた時点で完了ハンドラも作成しました。私はcreateNotificationメソッドをメインスレッド上で呼び出します(私はRealmを使用しているので、これも義務付けられています)。通知を作成する必要があります。

ここで問題となるのは、非同期で作業する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とswiftの両方について、この受け入れられた答えを見てください。私は本当にあなたの問題を理解していない

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

+0

私は、通知ごとに固有の識別子を作成することに特有の問題があります。私は私の答えを更新しました、あまりにも漠然として申し訳ありません。 – Croisciento

関連する問題