- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我是 iOS 开发的新手,也是 swift 的新手。我正在尝试让适用于 iOS 的谷歌云消息传递示例。
我已经从 https://developers.google.com/cloud-messaging/ios/start?ver=swift 为 iOS(Swift 版本)设置了谷歌云消息传递示例
我用以下方法做了 Action :pod 试试 Google
我确实收到了一个注册 token ,但是 applicationDidBecomeActive
部分的连接处理程序部分似乎没有出现错误,但似乎也没有进入连接到 GCM 部分。来自:
func applicationDidBecomeActive( application: UIApplication) {
// Connect to the GCM server to receive non-APNS notifications
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
print("Connected to GCM")
// [START_EXCLUDE]
self.subscribeToTopic()
// [END_EXCLUDE]
}
})
}
我看过GCM for iOS, gcm connection handler is never called但是缺少的部分已经包含在 pod try
的代码示例中。
这是完整的 AppDelegate.swift:
//
// Copyright (c) 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GGLInstanceIDDelegate, GCMReceiverDelegate {
var window: UIWindow?
var connectedToGCM = false
var subscribedToTopic = false
var gcmSenderID: String?
var registrationToken: String?
var registrationOptions = [String: AnyObject]()
let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
let subscriptionTopic = "/topics/global"
// [START register_for_remote_notifications]
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[NSObject: AnyObject]?) -> Bool {
// [START_EXCLUDE]
// Configure the Google context: parses the GoogleService-Info.plist, and initializes
// the services that have entries in the file
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
// [END_EXCLUDE]
// Register for remote notifications
if #available(iOS 8.0, *) {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
// Fallback
let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
application.registerForRemoteNotificationTypes(types)
}
// [END register_for_remote_notifications]
// [START start_gcm_service]
let gcmConfig = GCMConfig.defaultConfig()
gcmConfig.logLevel = GCMLogLevel.Debug
gcmConfig.receiverDelegate = self
GCMService.sharedInstance().startWithConfig(gcmConfig)
// [END start_gcm_service]
return true
}
func subscribeToTopic() {
// If the app has a registration token and is connected to GCM, proceed to subscribe to the
// topic
if(registrationToken != nil && connectedToGCM) {
GCMPubSub.sharedInstance().subscribeWithToken(self.registrationToken, topic: subscriptionTopic,
options: nil, handler: {(NSError error) -> Void in
if (error != nil) {
// Treat the "already subscribed" error more gently
if error.code == 3001 {
print("Already subscribed to \(self.subscriptionTopic)")
} else {
print("Subscription failed: \(error.localizedDescription)");
}
} else {
self.subscribedToTopic = true;
print("Subscribed to \(self.subscriptionTopic)");
NSLog("Subscribed to \(self.subscriptionTopic)");
}
})
}
}
// [START connect_gcm_service]
func applicationDidBecomeActive( application: UIApplication) {
// Connect to the GCM server to receive non-APNS notifications
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
print("Connected to GCM")
// [START_EXCLUDE]
self.subscribeToTopic()
// [END_EXCLUDE]
}
})
}
// [END connect_gcm_service]
// [START disconnect_gcm_service]
func applicationDidEnterBackground(application: UIApplication) {
GCMService.sharedInstance().disconnect()
// [START_EXCLUDE]
self.connectedToGCM = false
// [END_EXCLUDE]
}
// [END disconnect_gcm_service]
// [START receive_apns_token]
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
// [END receive_apns_token]
// [START get_gcm_reg_token]
// Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol.
let instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
instanceIDConfig.delegate = self
instanceIDConfig.logLevel = GGLInstanceIDLogLevel.Debug
// Start the GGLInstanceID shared instance with that config and request a registration
// token to enable reception of notifications
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
// [END get_gcm_reg_token]
}
// [START receive_apns_token_error]
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
print("Registration for remote notification failed with error: \(error.localizedDescription)")
// [END receive_apns_token_error]
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
registrationKey, object: nil, userInfo: userInfo)
}
// [START ack_message_reception]
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
// [END_EXCLUDE]
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
handler(UIBackgroundFetchResult.NoData);
// [END_EXCLUDE]
}
// [END ack_message_reception]
func registrationHandler(registrationToken: String!, error: NSError!) {
if (registrationToken != nil) {
self.registrationToken = registrationToken
print("Registration Token: \(registrationToken)")
self.subscribeToTopic()
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
print("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
// [START on_token_refresh]
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
print("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
// [END on_token_refresh]
// [START upstream_callbacks]
func willSendDataMessageWithID(messageID: String!, error: NSError!) {
if (error != nil) {
// Failed to send the message.
} else {
// Will send message, you can save the messageID to track the message
}
}
func didSendDataMessageWithID(messageID: String!) {
// Did successfully send message identified by messageID
}
// [END upstream_callbacks]
func didDeleteMessagesOnServer() {
// Some messages sent to this device were deleted on the GCM server before reception, likely
// because the TTL expired. The client should notify the app server of this, so that the app
// server can resend those messages.
}
}
这是日志中的信息:
2016-02-11 14:54:02.836 GcmExampleSwift[8484:] <GMR/INFO> App measurement v.1302000 started
2016-02-11 14:54:02.844 GcmExampleSwift[8484:] <GMR/INFO> To enable debug logging set the following application argument: -GMRDebugEnabled (see http://goo.gl/Y0Yjwu)
2016-02-11 14:54:02.845 GcmExampleSwift[8484:] <GMR/DEBUG> Debug logging enabled
2016-02-11 14:54:02.845 GcmExampleSwift[8484:] <GMR/DEBUG> App measurement is monitoring the network status
2016-02-11 14:54:02.871: GCM | Invalid key in checkin plist: GMSInstanceIDDeviceDataVersion
2016-02-11 14:54:02.900: GCM | Signing into MCS
2016-02-11 14:54:02.940 GcmExampleSwift[8484:] <GMR/DEBUG> App measurement is ready to receive events
2016-02-11 14:54:02.962: GGLInstanceID | Save InstanceID library version 1.1.6
2016-02-11 14:54:03.002 GcmExampleSwift[8484:] <GMR/DEBUG> No network. Upload task will not be scheduled
2016-02-11 14:54:03.004 GcmExampleSwift[8484:] <GMR/DEBUG> Scheduling user engagement timer
Registration Token: XXXXXXXXXXXXX
2016-02-11 14:54:03.010 GcmExampleSwift[8484:] <GMR/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-02-11 14:54:03.027 GcmExampleSwift[8484:] <GMR/INFO> App measurement enabled
2016-02-11 14:54:03.028 GcmExampleSwift[8484:] <GMR/DEBUG> Network status has changed. code, status: 2, Connected
2016-02-11 14:54:03.038 GcmExampleSwift[8484:] <GMR/DEBUG> Timer scheduled to fire in approx. (s): 2816.722655892372
2016-02-11 14:54:03.039 GcmExampleSwift[8484:] <GMR/DEBUG> Upload task scheduled to be executed in approx. (s): 2816.722655892372
2016-02-11 14:54:08.222: GCM | Successfully deleted 0 sync messages from store
2016-02-11 14:54:44.905: GCM | Signing into MCS
2016-02-11 14:55:28.909: GCM | Signing into MCS
2016-02-11 14:56:16.914: GCM | Signing into MCS
2016-02-11 14:57:12.918: GCM | Signing into MCS
2016-02-11 14:58:24.923: GCM | Signing into MCS
2016-02-11 15:00:08.927: GCM | Signing into MCS
2016-02-11 15:02:46.495 GcmExampleSwift[8484:] <GMR/DEBUG> Scheduling user engagement timer
2016-02-11 15:02:46.532 GcmExampleSwift[8484:] <GMR/DEBUG> Canceling active timer
2016-02-11 15:02:46.534 GcmExampleSwift[8484:] <GMR/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-02-11 15:02:46.535 GcmExampleSwift[8484:] <GMR/DEBUG> Canceling active timer
2016-02-11 15:02:46.536 GcmExampleSwift[8484:] <GMR/DEBUG> Logging event: origin, name, params: auto, _e, {
"_et" = 523435;
"_o" = auto;
}
2016-02-11 15:02:46.551 GcmExampleSwift[8484:] <GMR/DEBUG> Event logged. Event name, event params: _e, {
"_et" = 523435;
"_o" = auto;
}
2016-02-11 15:02:46.566 GcmExampleSwift[8484:] <GMR/DEBUG> Do not schedule an upload task. Task already exists
2016-02-11 15:02:56.662: GCM | Signing into MCS
2016-02-11 15:02:56.681 GcmExampleSwift[8484:] <GMR/DEBUG> Scheduling user engagement timer
2016-02-11 15:02:56.683 GcmExampleSwift[8484:] <GMR/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-02-11 15:03:38.666: GCM | Signing into MCS
2016-02-11 15:04:22.671: GCM | Signing into MCS
2016-02-11 15:05:10.675: GCM | Signing into MCS
2016-02-11 15:06:06.680: GCM | Signing into MCS
2016-02-11 15:07:18.664: GCM | Signing into MCS
2016-02-11 15:08:43.991: GCM | Signing into MCS
2016-02-11 15:11:31.996: GCM | Signing into MCS
2016-02-11 15:16:27.991: GCM | Signing into MCS
2016-02-11 15:25:39.985: GCM | Signing into MCS
我用 XXXXXXXXXXXXX
替换了真实的注册 token 。
从日志中还注意到:
GCM | checkin plist 中的 key 无效:GMSInstanceIDDeviceDataVersion
这正常吗?我找不到关于这意味着什么的信息?
通过 GCM 向设备发送消息确实有效,如果您将上面的示例代码修改为不检查 connectedToGCM
,您也可以接收主题消息。但是示例代码中肯定不会有错误,我假设我的配置有问题,但我无法弄清楚。任何帮助将不胜感激。
最佳答案
检查这个documentation错误的可能原因。请求中传递的注册 token 可能有问题;这可能是一个不可恢复的错误,还需要从服务器数据库中删除注册。
这SO question也可能有帮助。
关于iOS GCM - 连接到 GCM 部分不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35341417/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!