swift - GCM for iOS, gcm connection handler is never called -
i'm implementing google cloud messaging in application. i've followed tutorial given in google documentations. can send notifications device http post request, problem in applicationdidbecomeactive, google showed, try connect gcmservice the connectionhandler block never called.
applicationdidbecomeactive function in appdelegate
func applicationdidbecomeactive(application: uiapplication) { gcmservice.sharedinstance().connectwithhandler({ (nserror error) -> void in if error != nil { print("could not connect gcm: \(error.localizeddescription)") } else { self.connectedtogcm = true print("connected gcm") self.subscribetotopic() } }) }
does 1 have solved issue?
edit - correct way
here complete appdelegate.swift file
// // appdelegate.swift // import uikit import coredata @uiapplicationmain class appdelegate: uiresponder, uiapplicationdelegate, gglinstanceiddelegate, gcmreceiverdelegate { var window: uiwindow? var connectedtogcm = false var gcmsenderid: string? var gcmregistrationtoken: string? var gcmregistrationoptions = [string: anyobject]() let gcmregistrationkey = "onregistrationcompleted" var subscribedtotopic = false func application(application: uiapplication, didfinishlaunchingwithoptions launchoptions: [nsobject: anyobject]?) -> bool { print("bundleid=\(nsbundle.mainbundle().bundleidentifier)") // configure google analytics // configure tracker googleservice-info.plist. var configureerror:nserror? gglcontext.sharedinstance().configurewitherror(&configureerror) assert(configureerror == nil, "error configuring google services: \(configureerror)") // optional: configure gai options. let gai = gai.sharedinstance() gai.trackuncaughtexceptions = true // report uncaught exceptions gai.logger.loglevel = gailoglevel.verbose // remove before app release // override point customization after application launch. application.registerusernotificationsettings(uiusernotificationsettings(fortypes: [.alert, .badge, .sound], categories: nil)) // types uiusernotificationtype members // register remotes notifications uiapplication.sharedapplication().registerforremotenotifications() // gcm sender id gcmsenderid = gglcontext.sharedinstance().configuration.gcmsenderid var gcmconfig = gcmconfig.defaultconfig() gcmconfig.receiverdelegate = self gcmservice.sharedinstance().startwithconfig(gcmconfig) return true } func applicationwillresignactive(application: uiapplication) { // sent when application move active inactive state. can occur types of temporary interruptions (such incoming phone call or sms message) or when user quits application , begins transition background state. // use method pause ongoing tasks, disable timers, , throttle down opengl es frame rates. games should use method pause game. } func applicationdidenterbackground(application: uiapplication) { // use method release shared resources, save user data, invalidate timers, , store enough application state information restore application current state in case terminated later. // if application supports background execution, method called instead of applicationwillterminate: when user quits. gcmservice.sharedinstance().disconnect() connectedtogcm = false } func applicationwillenterforeground(application: uiapplication) { // called part of transition background inactive state; here can undo many of changes made on entering background. } func applicationdidbecomeactive(application: uiapplication) { // restart tasks paused (or not yet started) while application inactive. if application in background, optionally refresh user interface. // -->the app go through point // connect gcm server receive non-apns notifications gcmservice.sharedinstance().connectwithhandler(gcmconnectionhandler) // -->the app go through point } func gcmconnectionhandler(error: nserror?) { // -->the app never enter in function if let error = error { print("could not connect gcm: \(error.localizeddescription)") } else { self.connectedtogcm = true print("connected gcm") // ... } } func applicationwillterminate(application: uiapplication) { // called when application terminate. save data if appropriate. see applicationdidenterbackground:. self.savecontext() } func application(application: uiapplication, didregisterforremotenotificationswithdevicetoken devicetoken: nsdata) { // create config , set delegate implements gglinstaceiddelegate protocol. let instanceidconfig = gglinstanceidconfig.defaultconfig() instanceidconfig.delegate = self // start gglinstanceid shared instance config , request registration // token enable reception of notifications gglinstanceid.sharedinstance().startwithconfig(instanceidconfig) gcmregistrationoptions = [kgglinstanceidregisterapnsoption:devicetoken, kgglinstanceidapnsservertypesandboxoption:true] gglinstanceid.sharedinstance().tokenwithauthorizedentity(gcmsenderid, scope: kgglinstanceidscopegcm, options: gcmregistrationoptions, handler: gcmregistrationhandler) } func application(application: uiapplication, didfailtoregisterforremotenotificationswitherror error: nserror) { print("-- failed devicetoken: \(error.localizeddescription)") } func application(application: uiapplication, didreceiveremotenotification userinfo: [nsobject : anyobject]) { application.applicationiconbadgenumber += 1 print(userinfo) let apsinfo = userinfo["aps"] as! nsdictionary var alertmessage = "" print("********************** received notif") if let alert = apsinfo["alert"] as? string{ alertmessage = alert print(alertmessage) } else if let alert = apsinfo["alert"] as? nsdictionary, let body = alert["body"] as? string { alertmessage = body print(alertmessage) } // if application on screen "active" trigger custom banner view notification shown // else system handle , put in notification center if application.applicationstate == uiapplicationstate.active { agpushnoteview.showwithnotificationmessage(alertmessage, autoclose: true, completion: { () -> void in // nothing }) } } func gcmregistrationhandler(registrationtoken: string!, error: nserror!) { if (registrationtoken != nil) { self.gcmregistrationtoken = registrationtoken print("gcm registration token: \(registrationtoken)") let userinfo = ["registrationtoken": registrationtoken] nsnotificationcenter.defaultcenter().postnotificationname( self.gcmregistrationkey, object: nil, userinfo: userinfo) } else { print("registration gcm failed error: \(error.localizeddescription)") let userinfo = ["error": error.localizeddescription] nsnotificationcenter.defaultcenter().postnotificationname(self.gcmregistrationkey, object: nil, userinfo: userinfo) } } // mark: - gglinstanceiddelegate func ontokenrefresh() { // rotation of registration tokens happening, app needs request new token. print("the gcm registration token needs changed.") gglinstanceid.sharedinstance().tokenwithauthorizedentity(gcmsenderid, scope: kgglinstanceidscopegcm, options: gcmregistrationoptions, handler: gcmregistrationhandler) } // mark: - gcmreceiverdelegate func willsenddatamessagewithid(messageid: string!, error: nserror!) { if (error != nil) { // failed send message. } else { // send message, can save messageid track message } } func didsenddatamessagewithid(messageid: string!) { // did send message identified messageid } // [end upstream_callbacks] func diddeletemessagesonserver() { // messages sent device deleted on gcm server before reception, // because ttl expired. client should notify app server of this, app // server can resend messages. } func subscribetotopic() { // if app has registration token , connected gcm, proceed subscribe // topic let subscriptiontopic = "/topics/test-global" if(gcmregistrationtoken != nil && connectedtogcm) { gcmpubsub.sharedinstance().subscribewithtoken(gcmregistrationtoken, topic: subscriptiontopic, options: nil, handler: {(nserror error) -> void in if (error != nil) { // treat "already subscribed" error more gently if error.code == 3001 { print("already subscribed \(subscriptiontopic)") } else { print("subscription failed: \(error.localizeddescription)"); } } else { subscribedtotopic = true; nslog("subscribed \(subscriptiontopic)"); } }) } } }
there couple problems in code.
first, need call gcmservice.sharedinstance().startwithconfig(gcmconfig.defaultconfig())
in didfinishlaunchingwithoptions
method, called in didregisterforremotenotificationswithdevicetoken
method.
second, should call application.registerforremotenotifications()
after application.registerusernotificationsettings()
in didfinishlaunchingwithoptions
method.
there sample gcm project ios available, can follow sample implementation appdelegate.swift
file, app work correctly.
you can gcm ios sample project via cocoapods doing pod try google
, can visit this documentation more details.
edited:
you should replace lines in didfinishlaunchingwithoptions
following (notice should use let gcmconfig = gcmconfig.defaultconfig()
, gcmconfig.receiverdelegate = self
):
// [start_exclude] // configure google context: parses googleservice-info.plist, , initializes // services have entries in file var configureerror:nserror? gglcontext.sharedinstance().configurewitherror(&configureerror) assert(configureerror == nil, "error configuring google services: \(configureerror)") gcmsenderid = gglcontext.sharedinstance().configuration.gcmsenderid // [end_exclude] // register remote notifications let settings: uiusernotificationsettings = uiusernotificationsettings( fortypes: [.alert, .badge, .sound], categories: nil ) application.registerusernotificationsettings( settings ) application.registerforremotenotifications() // [end register_for_remote_notifications] // [start start_gcm_service] var gcmconfig = gcmconfig.defaultconfig() gcmconfig.receiverdelegate = self gcmservice.sharedinstance().startwithconfig(gcmconfig) // [end start_gcm_service] return true
Comments
Post a Comment