[ios] Xcode 8 / Swift 3.0에서 푸시 알림에 등록 하시겠습니까?

내 앱이 Xcode 8.0 에서 작동하도록하려고하는데 오류가 발생합니다. 이 코드가 이전 버전의 swift에서 잘 작동한다는 것을 알고 있지만이 코드가 새 버전에서 변경되었다고 가정합니다. 실행하려는 코드는 다음과 같습니다.

let settings = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.shared().registerForRemoteNotifications()

내가받은 오류는 “인수 레이블 ‘(forTypes :, categories :)’가 사용 가능한 오버로드와 일치하지 않습니다.”입니다.

이 작업을 수행 할 수있는 다른 명령이 있습니까?



답변

UserNotifications프레임 워크를 가져 UNUserNotificationCenterDelegate와서 AppDelegate.swift에 추가하세요 .

사용자 권한 요청

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
        }
        application.registerForRemoteNotifications()
        return true
}

장치 토큰 가져 오기

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print(deviceTokenString)
}

오류가 발생한 경우

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

        print("i am not available in simulator \(error)")
}

부여 된 권한을 알아야 할 경우

UNUserNotificationCenter.current().getNotificationSettings(){ (settings) in

            switch settings.soundSetting{
            case .enabled:

                print("enabled sound setting")

            case .disabled:

                print("setting has been disabled")

            case .notSupported:
                print("something vital went wrong here")
            }
        }


답변

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    if #available(iOS 10, *) {

        //Notifications get posted to the function (delegate):  func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)"


        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in

            guard error == nil else {
                //Display Error.. Handle Error.. etc..
                return
            }

            if granted {
                //Do stuff here..

                //Register for RemoteNotifications. Your Remote Notifications can display alerts now :)
                DispatchQueue.main.async {
                    application.registerForRemoteNotifications()
                }
            }
            else {
                //Handle user denying permissions..
            }
        }

        //Register for remote notifications.. If permission above is NOT granted, all notifications are delivered silently to AppDelegate.
        application.registerForRemoteNotifications()
    }
    else {
        let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()
    }

    return true
}


답변

import UserNotifications  

다음으로 대상의 프로젝트 편집기로 이동하고 일반 탭에서 연결된 프레임 워크 및 라이브러리 섹션을 찾습니다.

+를 클릭하고 UserNotifications.framework를 선택합니다.

// iOS 12 support
if #available(iOS 12, *) {
    UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound, .provisional, .providesAppNotificationSettings, .criticalAlert]){ (granted, error) in }
    application.registerForRemoteNotifications()
}

// iOS 10 support
if #available(iOS 10, *) {
    UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }
    application.registerForRemoteNotifications()
}
// iOS 9 support
else if #available(iOS 9, *) {
    UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
    UIApplication.shared.registerForRemoteNotifications()
}
// iOS 8 support
else if #available(iOS 8, *) {
    UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
    UIApplication.shared.registerForRemoteNotifications()
}
// iOS 7 support
else {
    application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])
}

알림 위임 방법 사용

// Called when APNs has assigned the device a unique token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Convert token to string
    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("APNs device token: \(deviceTokenString)")
}

// Called when APNs failed to register the device for push notifications
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    // Print the error to console (you should alert the user that registration failed)
    print("APNs registration failed: \(error)")
}

푸시 알림 수신

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    completionHandler(UIBackgroundFetchResult.noData)
}

푸시 알림을 설정하면 앱에 대해 Xcode 8 내의 기능이 활성화됩니다. 단순히 대상에 대한 프로젝트 편집기로 이동 한 다음 클릭 기능 탭 . 를 찾아 푸시 알림 및 그 값 토글 ON .

더 많은 알림 위임 방법은 아래 링크를 확인하십시오.

로컬 및 원격 알림 처리 UIApplicationDelegate을로컬 및 원격 통지를 처리

https://developer.apple.com/reference/uikit/uiapplicationdelegate


답변

여기서는 deviceToken 데이터 개체를 Xcode 8의 현재 베타 버전으로 서버에 보낼 문자열로 변환하는 데 문제가있었습니다. 특히 8.0b6에서 “32 바이트”를 반환하는 deviceToken.description을 사용하는 경우 별로 유용하지 않습니다 🙂

이것은 나를 위해 일한 것입니다 …

“hexString”메소드를 구현하기 위해 데이터에 확장을 작성하십시오.

extension Data {
    func hexString() -> String {
        return self.reduce("") { string, byte in
            string + String(format: "%02X", byte)
        }
    }
}

그런 다음 원격 알림 등록에서 콜백을받을 때이를 사용합니다.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let deviceTokenString = deviceToken.hexString()
    // Send to your server here...
}


답변

코드 대신 iOS10에서 다음과 같은 알림에 대한 승인을 요청해야합니다. ( UserNotifications프레임 워크 를 추가하는 것을 잊지 마세요 )

if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted: Bool, error: NSError?) in
            // Do something here
        }
    }

또한 올바른 코드는 다음과 같습니다 ( else예 : 이전 조건의에서 사용 ).

let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
UIApplication.shared().registerUserNotificationSettings(setting)
UIApplication.shared().registerForRemoteNotifications()

마지막으로 -> -> Push Notification에서 활성화되어 있는지 확인하십시오 . (설정 )targetCapabilitiesPush notificationOn


답변

이것은 나를 위해 일합니다. AppDelegate에서 1 위

import UserNotifications

그때:

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        registerForRemoteNotification()
        return true
    }

    func registerForRemoteNotification() {
        if #available(iOS 10.0, *) {
            let center  = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
                if error == nil{
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
        else {
            UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
            UIApplication.shared.registerForRemoteNotifications()
        }
    }

devicetoken을 얻으려면 :

  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

       let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

}


답변

주의 :이 작업을 위해 메인 스레드를 사용해야합니다.

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        if granted {
            DispatchQueue.main.async(execute: {
                UIApplication.shared.registerForRemoteNotifications()
            })
        }
    }