xcode 使用 Parse 从一个用户向另一个用户发送推送通知
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20626513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending a Push Notification from one user to another user with Parse
提问by tagabek
I have built a messaging app that is similar to Snapchat - one user can send another user pictures. I am trying to add push notifications to the app, so that when a message is sent from UserA to UserB, UserB receives a push notification of "New Message from UserA".
我已经构建了一个类似于 Snapchat 的消息传递应用程序 - 一个用户可以发送另一个用户的图片。我正在尝试向应用程序添加推送通知,以便当消息从用户 A 发送到用户 B 时,用户 B 会收到“来自用户 A 的新消息”的推送通知。
I have been researching this for hours now, and I feel like I am very close.
我已经研究了几个小时了,我觉得我很接近。
I am trying to use Parse to send push notifications. I would like it to work like this: When UserA sends UserB a message, UserB is also sent a push notification that says "New Message from UserA". I was successfully able to use the Parse website to send a push notification to devices using the application, but am NOT able to successfully send a push notification from within the app (when a user sends a message) to the receiving user's device.
我正在尝试使用 Parse 发送推送通知。我希望它像这样工作:当用户 A 向用户 B 发送消息时,用户 B 也会收到一个推送通知,上面写着“来自用户 A 的新消息”。我成功地使用 Parse 网站向使用该应用程序的设备发送推送通知,但无法从应用程序内(当用户发送消息时)成功向接收用户的设备发送推送通知。
The push notifications are apparently being sent successfully, as my Parse account shows the messages that I have sent. However, no messages actually reaches the intended device and the list of push notifications shows 0 subscribers for each push notification.
推送通知显然已成功发送,因为我的 Parse 帐户显示了我发送的消息。但是,实际上没有消息到达预期设备,并且推送通知列表显示每个推送通知有 0 个订阅者。
And I can click on one of those to see the details.
我可以单击其中之一查看详细信息。
Also, I am using a Distribution/Production Provisioning Profile & Certificate.
此外,我正在使用分发/生产供应配置文件和证书。
Here's the code that I am using the send the push notification after UserA would send a message to UserB - the message
object is the message that has been uploaded to Parse, and the messageRecipients are the users that the message is being sent to:
这是我在 UserA 向 UserB 发送消息后使用发送推送通知的代码 -message
对象是已上传到 Parse 的消息,而 messageRecipients 是消息被发送到的用户:
// Send Push Notification to recipients
NSArray *messageRecipients = [message objectForKey:@"recipientIds"];
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:@"owner" containedIn:messageRecipients];
PFPush *push = [[PFPush alloc] init];
[push setQuery:pushQuery];
[push setMessage:[NSString stringWithFormat: @"New Message from %@!", [PFUser currentUser].username]];
[push sendPushInBackground];
Here are my AppDelegate.m related methods:
这是我的 AppDelegate.m 相关方法:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Parse setApplicationId:@"[This is where my app Id is]"
clientKey:@"[This is where client Id is]"];
[self customizeUserInterface];
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[PFPush storeDeviceToken:deviceToken];
[PFPush subscribeToChannelInBackground:@""];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"Did fail to register for push, %@", error);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[PFPush handlePush:userInfo];
}
I have also submitted a post on the Parse.com forums: https://parse.com/questions/sending-a-push-notification-from-one-user-to-another-user
我还在 Parse.com 论坛上提交了一篇帖子:https://parse.com/questions/sending-a-push-notification-from-one-user-to-another-user
Is there something that I am missing or doing wrong?
我有什么遗漏或做错了吗?
EDIT: I am now able to see subscribers in my Parse account, but I am not actually receiving the push notifications on my device. The same goes for when I try to send a push notification test from the Parse website.
编辑:我现在可以在我的 Parse 帐户中看到订阅者,但我实际上没有在我的设备上收到推送通知。当我尝试从 Parse 网站发送推送通知测试时也是如此。
回答by Wesley Smith
My searches kept coming back to here but nothing here really spelled it out for me. So here's how I got mine working:
我的搜索不断回到这里,但这里没有什么能真正为我解释清楚。所以这就是我的工作方式:
In my AppDelegate.m I have:
在我的 AppDelegate.m 我有:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
PFUser *currentUser = [PFUser currentUser];
if (currentUser) {
//save the installation
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
currentInstallation[@"installationUser"] = [[PFUser currentUser]objectId];
// here we add a column to the installation table and store the current user's ID
// this way we can target specific users later
// while we're at it, this is a good place to reset our app's badge count
// you have to do this locally as well as on the parse server by updating
// the PFInstallation object
if (currentInstallation.badge != 0) {
currentInstallation.badge = 0;
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
// Handle error here with an alert…
}
else {
// only update locally if the remote update succeeded so they always match
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
NSLog(@"updated badge");
}
}];
}
} else {
[PFUser logOut];
// show the signup screen here....
}
}
in the viewController where I send the push I have:
在我发送推送的 viewController 中:
myViewController.h
视图控制器.h
@property (nonatomic, strong) NSMutableArray *recipients; // declare the array we'll use to store our recipients
myViewController.m
视图控制器.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.recipients = [[NSMutableArray alloc] init]; // initialize the array we'll use to hold our recipients
}
// in another part of the code (not shown here) we set up a tableView with all of the current user's friends in it
// when the user taps a row in that tableView we add or remove the selected friend from our recipients list
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
PFUser *user = [self.friends objectAtIndex:indexPath.row];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.recipients addObject:user.objectId]; // user selected a recipient, add them to the array
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.recipients removeObject:user.objectId]; // user de-selected a recipient, remove them from the array
}
}
- (void)uploadMessage
{
UIImage *newImage = [self resizeImage:self.image toWidth:640.0f andHeight:960.0f];
NSData *fileData= UIImageJPEGRepresentation(newImage, 1.0);
NSString *fileName= @"image.jpg";;
NSString *fileType= @"image";
PFFile *file = [PFFile fileWithName:fileName data:fileData];
[file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
// Handle error here with an alert…
}
else {
PFObject *message = [PFObject objectWithClassName:@"Messages"];
[message setObject:file forKey:@"file"];
[message setObject:fileType forKey:@"fileType"];
[message setObject:self.recipients forKey:@"recipientIds"];
// self.recipients is an NSMutableArray of the objectIds for each
// user the message will go to
[message setObject:[[PFUser currentUser] objectId] forKey:@"senderId"];
[message setObject:[[PFUser currentUser] username] forKey:@"senderName"];
[message saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
// Handle error here with an alert…
}
else {
// Everything was successful! Reset UI… do other stuff
// Here's where we will send the push
//set our options
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
@“Ne messages available!!”, @"alert",
@"Increment", @"badge",
nil];
// Now we'll need to query all saved installations to find those of our recipients
// Create our Installation query using the self.recipients array we already have
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:@"installationUser" containedIn:self.recipients];
// Send push notification to our query
PFPush *push = [[PFPush alloc] init];
[push setQuery:pushQuery];
[push setData:data];
[push sendPushInBackground];
}
}];
}
}];
}
回答by Nic Huang
I think I have the answer. I encountered the same problem and I just solved it.
我想我有答案。我遇到了同样的问题,我刚刚解决了它。
When you are setting value to owner, you should use "[PFUser currentUser].objectId", instead of [PFUser currentUser]. The latter gives you a pointer to owner, but we need a string to set Push query within this situation.
当您为所有者设置值时,您应该使用“[PFUser currentUser].objectId”,而不是 [PFUser currentUser]。后者为您提供了一个指向所有者的指针,但在这种情况下我们需要一个字符串来设置 Push 查询。
When we first set owner to Installation, we should set objectId as string to owner instead of just [PFUser currentUser] like below.
当我们第一次将 owner 设置为 Installation 时,我们应该将 objectId 作为字符串设置为 owner 而不是像下面这样只设置 [PFUser currentUser]。
[currentInstallation setObject:[PFUser currentUser].objectId forKey:@"owner"];
And later we could set the owner (string) to our pushQuery.
稍后我们可以将所有者(字符串)设置为我们的 pushQuery。
回答by djshiow
Have you tried storing the owner in the installation. ie.
您是否尝试将所有者存储在安装中。IE。
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation setObject:[PFUser currentUser] forKey:@"owner"];
[currentInstallation saveInBackground];
}
From: click here
来自:点击这里
回答by Lyndsey Scott
Given what you've posted so far, I'm not sure why your code isn't working for you. It seems as if either your Installation table doesn't contain an "owner" column or it contains an "owner" column with values/types other than those contained in your [message objectForKey:@"recipientIds"]
array; but, just in case you need/want to try a back-up method, here's another way to send push notifications from one device to another using Parse:
鉴于您到目前为止发布的内容,我不确定为什么您的代码对您不起作用。似乎您的安装表不包含“所有者”列,或者它包含一个“所有者”列,其中包含[message objectForKey:@"recipientIds"]
数组中包含的值/类型以外的值/类型;但是,以防万一您需要/想要尝试备份方法,这是使用 Parse 将推送通知从一个设备发送到另一个设备的另一种方法:
First subscribe the user/group of users receiving the push to their own unique channel (in addition to the main channel), ex.
首先将接收推送的用户/用户组订阅到他们自己的独特频道(除了主频道),例如。
[PFPush subscribeToChannelInBackground:taylors_channel];
Then from the device sending the push, set the channel to that of the recipient:
然后从发送推送的设备,将频道设置为接收者的频道:
PFPush *push = [[PFPush alloc] init];
[push setChannel:taylors_channel];
[push setMessage:[NSString stringWithFormat: @"New Message from %@!", [PFUser currentUser].username]];
[push sendPushInBackground];
Additionally, you can also set the same channel for multiple peers or send a message to multiple channels at once using [push setChannels:channel_array]
;
此外,您还可以为多个对等方设置相同的频道或使用[push setChannels:channel_array]
;一次向多个频道发送消息;
回答by Logan
To elaborate on djshiow's response, once you have saved the current installation as such.
详细说明 djshiow 的响应,一旦您将当前安装保存为这样。
PFQuery * pushQuery = [PFInstallation query];
PFUser * userReceivingPush;
[pushQuery whereKey:@"owner" equalTo:userReceivingPush];
NSString * alert = [NSString stringWithFormat:@"You have a new message from %@!", [PFUser currentUser].username];
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
alert, @"alert",
@"default", @"sound",
@"Increment", @"badge",
nil];
[PFPush sendPushDataToQueryInBackground:pushQuery withData:data block:^(BOOL succeeded, NSError *error) {
if (!error) {
}
else {
}
}];