0

現在、私はappDelegatedidFinishLaunchingWithOptionsに、私は次のメソッドを呼んでいる中:AppDelegate以外の場所からプッシュメッセージを受信するためにユーザーのiosデバイスを登録するにはどうすればよいですか?

let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound] 
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil) 

application.registerUserNotificationSettings(pushNotificationSettings) 
application.registerForRemoteNotifications() 

私はまた、以下の方法がAppDelegateで実装している:

didRegisterForRemoteNotificationsWithDeviceToken 

didFailToRegisterForRemoteNotificationsWithError 

didReceiveRemoteNotification 

は、ユーザーが最初に私のアプリを起動すると、彼はプッシュメッセージの受信に関する許可を彼に求めるポップアップを見る。

ユーザが[設定]メニューで特定のオプションを手動で選択するまで、このポップアップの表示を延期します。設定メニューで

私はUISwitchを持っていると私はそれの状態にユーザーがそれを変更するたびにチェックしています:、

func messagesStateChanged(_ sender: UISwitch){ 
    if(sender.isOn){ 
     defaults.set("true", forKey: "popupMessages") 
     defaults.synchronize() 
    } else { 
     defaults.set("false", forKey: "popupMessages") 
     defaults.synchronize() 
    } 
} 

は、設定メニューにアプリデリゲートからpush取り扱いを移動する方法はありますユーザはアプリを起動した直後ではなく、UISwitchを選択したときにポップアップが表示されるようになります。また、将来、すべてのpushの機能は、私がSettingsクラスに移動すると機能しますか?

+1

なぜ、承認された標準化されたデザインパターンを悪化させたいのですか? – vadian

答えて

4

didFinishLaunchingWithOptionsにあるUIApplicationインスタンスにアクセスするには、UIKitにアクセスできるアプリケーションのどこからでもUIApplication.sharedクラスプロパティにアクセスします。私は通常、後でユニットテストを書いているときにUIApplication依存関係を注入することを可能にする通知を管理するラッパークラスを作成します。あなたがスイッチを起動しているとき

レジスタコールが起こるはず:

func messagesStateChanged(_ sender: UISwitch){ 
    if(sender.isOn){ 
     defaults.set("true", forKey: "popupMessages") 
     defaults.synchronize() 

     let application = UIApplication.shared 
     let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound] 
     let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil) 

     application.registerUserNotificationSettings(pushNotificationSettings) 
     application.registerForRemoteNotifications() 
    } else { 
     defaults.set("false", forKey: "popupMessages") 
     defaults.synchronize() 
    } 
} 

私が使用して単純化されたラッパークラス(簡単にするために使用さシングルトンを):

class NotificationManager { 
    static var shared = NotificationManager() 

    private var application : UIApplication? 

    func setup(application: UIApplication) { 
     self.application = application 
    } 

    func register() { 
     guard let application = application else { 
      print("Attempt to register without calling setup") 
      return 
     } 

     let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound] 
     let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil) 

     application.registerUserNotificationSettings(pushNotificationSettings) 
     application.registerForRemoteNotifications() 
    } 
} 

これはあなたのことが必要ですdidFinishLaunchingMethodの通話設定:

NotificationManager.shared.setup(application: application) 

しかし、その後、あなたが通知を登録する必要がどこに:これは、後で簡単にUIApplicationモックオブジェクトを注入し、クラスもきれいにすべての通知関連のロジックをカプセル化することにより、NotificationManagerクラスをテストすることができます

func messagesStateChanged(_ sender: UISwitch){ 
    if(sender.isOn){ 
     ... 
     NotificationManager.shared.register() 
    } 
    ... 
} 

。いくつかの変更を加えれば、既に登録済みの場合は追跡が容易になり、受信したプッシュトークンを追跡し、定型コードを複製せずにiOS 8/9の下位互換性を処理することさえできます。

+0

そのラッパークラスのサンプルコードを共有していただけますか? – user3766930

+0

あなたは行き​​ます。このソリューションを直接使用するのではなく、これをアイディアとして使用してください。 – Legoless

+0

私はここでフォローアップの質問をしましたhttp://stackoverflow.com/questions/41025023/why-i-cannot-register-my-device-for-apple-push-messages-after-unregistering-from ? – user3766930

関連する問題