2017-04-17 41 views
0

運行的Xcode 8與SWIFT 3如何將設備令牌從AppDelegate.swift傳遞到ViewController.swift?

下面是我的ViewController文件

class ViewController: UIViewController { 

    @IBOutlet weak var testWebview: UIWebView! 


    override func viewDidLoad() { 
     print("inside viewDidLoad ") 
     super.viewDidLoad() 

     guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { 
      return 
     } 
     guard let deviceTokenString = appDelegate.deviceTokenString else { 
      print("can not get device token string") 
      return 
     } 


     let deviceid = UIDevice.current.identifierForVendor!.uuidString 
     print("====== device id =======") 
     print(deviceid) 

     let testURL = URL(string: "http://www.test.com/user?device=ios&deviceid=" + deviceid + "&devicetoken=" + deviceTokenString) 


     let testURLRequest = URLRequest(url: testURL!) 
     print("before load request") 
     print(testURL!) 
     RJWebview.loadRequest(testURLRequest) 
    } 

} 

下面是我的AppDelegate文件

class AppDelegate: UIResponder, UIApplicationDelegate { 

    var window: UIWindow? 
    var deviceTokenString: String? 



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

     let center = UNUserNotificationCenter.current() 

     center.requestAuthorization(options: [.alert, .sound, .badge], completionHandler: { granted, error in 
      if granted { 
       print("YES。") 
      } 
      else { 
       print("NO!") 
      } 
     }) 

     application.registerForRemoteNotifications() 

     return true 
    } 


    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
     deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) 
     print("==== didRegisterForRemoteNotificationsWithDeviceToken ====") 
     print("===== deviceTokenString =====") 
     print(deviceTokenString!) 
    } 

} 

下面是我的調試區域信息

YES。 
inside viewDidLoad 
can not get device token string 
==== didRegisterForRemoteNotificationsWithDeviceToken ==== 
===== deviceTokenString ===== 
DF9AB59resrF68532C07ECB00627E4632F08F02975D5C4adsfsd2e810A5EB4 

它好像我無法從AppD獲取設備標記字符串elegate.swift。 我怎樣才能得到它?

或者我可以在didFinishLaunchingWithOptions中獲得設備令牌嗎?

+0

爲什麼不你剛剛保存設備令牌串到你的userdefaults? –

+0

競態條件問題,我想 – iDhaval

+0

你試圖獲得設備令牌之前,它分配給應用程序委託中的deviceTokenString。 – iDhaval

回答

3

didRegisterForRemoteNotificationsWithDeviceToken在後的viewController的viewDidLoad總是執行,這就是爲什麼字符串爲空的原因。

爲了解決你可以做

  • AppDelegate聲明弱財產的時機問題。

    weak var viewController : ViewController? 
    
  • ViewController>viewDidLoad設置屬性。你不需要guardAppDelegate。如果它不在那裏,應用程序不會啓動。

    override func viewDidLoad() { 
        print("inside viewDidLoad ") 
        super.viewDidLoad() 
        let appDelegate = UIApplication.shared.delegate as! AppDelegate 
        appDelegate.viewController = self 
    } 
    
  • ViewController把代碼加載web請求是一個額外的方法。

    func loadRequest(for deviceTokenString : String) 
    { 
        let deviceid = UIDevice.current.identifierForVendor!.uuidString 
        print("====== device id =======") 
        print(deviceid) 
        let testURL = URL(string: "http://www.test.com/user?device=ios&deviceid=" + deviceid + "&devicetoken=" + deviceTokenString 
    
        let testURLRequest = URLRequest(url: testURL!) 
        print("before load request") 
        print(testURL!) 
        RJWebview.loadRequest(testURLRequest) 
    } 
    
  • AppDelegate>didRegisterForRemoteNotificationsWithDeviceToken呼叫的方法。

    viewController?.loadRequest(for: deviceTokenString!) 
    
+0

很好解釋。但是我有一個疑問,___ if'applicationDidFinishLaunching'總是在viewController___的'viewDidLoad'之後執行,那麼爲什麼控制檯會打印這個命令:__YES。,在viewDidLoad__裏面?相反,它應該是__inside viewDidLoad,YES .__!對?? – nayem

+0

我不好,我更新了答案。 – vadian

+0

現在,這是有道理的 – nayem