我正在尝试开发一个简单的消息传递应用程序来学习 CloudKit 的基础知识。
我几乎弄明白了,只是我无法接收记录更新事件的通知。
为了测试应用程序,我在设备和模拟器上同时运行它。
两个实例都登录到同一个 iCloud 帐户(还没有抽出时间创建专门的帐户进行测试...);然而,该应用使用 UUId 将本地用户与远程用户区分开来,因此这不是问题。
当应用程序的一个实例想要发送消息时,它会创建一条记录并将其保存到 CloudKit。
我知道模拟器不支持 APNs,但如果我从模拟器发送消息,我可以在设备上收到通知。
这有效。
接下来,我想将这些消息标记为“已读”:也就是说,当它们首次显示在不是创作它们的设备上时标记它们。
我通过获取相应的记录、修改它并保存它来完成此操作。因此,我从设备发送的消息显示在模拟器上,并在那里标记为“已读”。我将更改与 cloudKit 同步,并希望设备收到通知:
publicDatabase.perform(query, inZoneWith: nil, completionHandler: {(records, error) in
guard let records = records, records.count > 0 else {
return print("Error - Message: \(message.text) by \(message.userName) NOT found on the cloud!")
}
let record = records[0]
// HERE THE RECORD IS MODIFIED LOCALLY:
record["readTimestamp"] = (message.readTimestamp! as NSDate)
// Now, save it:
self.publicDatabase.save(record, completionHandler: {record, error in
guard error == nil else {
return print("Error - Message: \(message.text) by \(message.userName) could NOT be saved as read!")
}
print("Message: \(message.text) by \(message.userName) SAVED as read at \(message.readTimestamp!)")
})
})
但是,在另一端,永远不会收到“更新”通知。
是否因为两个实例都以同一用户身份登录到 iCloud?我觉得这很难相信,因为“创建”通知可以毫无问题地传送。
两个通知(“消息创建”和“消息更新”)的订阅已成功注册并显示在 CloudKit 仪表板上(触发 INSERT 和 UPDATE)。
更新:经过很长时间思考我的“创建”订阅和我的“更新”订阅之间可能只有一个触发通知的不同之处,我意识到只有“创建”订阅有一个通知主体:
let subscription = CKQuerySubscription(recordType: "Message",
predicate: NSPredicate(value: true),
subscriptionID: Bundle.main.bundleIdentifier! + ".subscription.message.create",
options: .firesOnRecordCreation
)
let notificationInfo = CKNotificationInfo()
// THIS LINE MAKES ALL THE DIFFERENCE:
notificationInfo.alertBody = "You've Got Mail!"
subscription.notificationInfo = notificationInfo
publicDatabase.save(subscription, completionHandler: {savedSubscription, error in
...而“更新”订阅没有:
let notificationInfo = CKNotificationInfo()
subscription.notificationInfo = notificationInfo
添加警报正文后,“更新”通知开始到达。
但是,这只是一种变通方法:我的阅读更新需要静默通知。仅仅为了提醒用户他的消息已在另一端阅读而显示横幅是没有意义的。 此外,CloudKit 编程指南没有提及此限制。
有没有办法订阅静默(即空的)推送通知?
更新 2: 实际上,我在 API Reference 上找到了这个位对于 CKNotificationInfo:
Note
If you don’t set any of the
alertBody,soundName, orshouldBadgeproperties, the push notification is sent at a lower priority that doesn’t cause the system to alert the user.
(强调我的)
我仍然看不出这个“不会导致系统提醒用户的低优先级”是如何等同于“application(:didReceiveRemoteNotification:fetchCompletionHandler:) not being called完全”。
最佳答案
解决方案似乎是使用 shouldSendContentAvailable = true 的信息对象,如下所示:
let info = CKNotificationInfo()
info.shouldSendContentAvailable = true
subscription.notificationInfo = info
这已经为我解决了。它会导致 didReceiveRemoteNotification: 触发,而不会出现任何用户可见的通知。所以这是一个无声的通知,如所期望的那样,并且它确实如所期望的那样到达。
如果我将 subscription.notificationInfo 设为 nil,则应用程序永远不会收到更改通知。但是有了一个 [有效沉默] 信息对象,我得到了想要的结果。
关于ios - CloudKit 不发送更新通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39912403/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=
有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U