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 

는 사용자가 처음 내 응용 프로그램을 시작하면, 그는 푸시 메시지 수신에 대한 권한을 요청하는 팝업을 봅니다.

사용자가 설정 메뉴에서 특정 옵션을 수동으로 선택하기 전까지이 팝업 표시를 연기하고 싶습니다. ,

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

설정 메뉴에 애플 대리자에서 처리 push을 이동하는 방법이 있나요 : 설정 메뉴에서

은 내가 UISwitch을 가지고 있고 그것의 상태를 확인하고 있습니다 때마다 사용자가 변경 사용자가 앱을 시작하자마자 팝업을 보지 못하게하고 UISwitch을 선택하면 또한 - 미래에 작동하고 모든 push 기능을 설정 클래스로 옮기면 잘 작동할까요?

+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