gpt4 book ai didi

IOS 设备间推送通知——GCDAsyncSocket

转载 作者:行者123 更新时间:2023-11-28 21:06:33 27 4
gpt4 key购买 nike

各位程序员大家好,

我正在尝试允许用户向其他用户发送推送通知(例如发送好友请求等)。

这里的最终目标是让我的 iOS 应用程序在用户登录到他们的帐户(也就是加载了特定 View )后持续监听特定的主机名/端口 URL。我的堆栈是一个与 MongoDB 通信的快速服务器。

假设用户使用 {account_id} 登录,其帐户信息的路径为:“http://72.89.157.153:3000/accounts/ {account_id}

我希望我的应用能够监听发送到该 URL 的任何请求。我正在使用 GCDAsyncSocket 库来帮助解决这个问题。但是,当我连接到 http://72.89.157.153:3000/ 时出于测试目的,没有调用委托(delegate)函数。我见过很多人遇到同样的问题,但我无法找到我所阅读的任何解决方案。

代码:

SocketConnection.h

#ifndef SocketConnection_h
#define SocketConnection_h
#import "GCDAsyncSocket.h" // for TCP

@import CocoaAsyncSocket;

@interface SocketConnection : NSObject <GCDAsyncSocketDelegate>

/* GCDAsyncSocket */
@property (strong, nonatomic) GCDAsyncSocket *socket;


// Methods
+(SocketConnection *)sharedConnection;

@end

#endif /* SocketConnection_h */

SocketConnection.m

#import <Foundation/Foundation.h>
#import "SocketConnection.h"
@implementation SocketConnection

+(SocketConnection *)sharedConnection {
static dispatch_once_t once;
static SocketConnection *instance;

dispatch_once(&once, ^{
instance = [[SocketConnection alloc] init];
});


return instance;
}


-(id)init {

_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

NSError *err = nil;
if (![_socket connectToHost:@"http://72.89.157.153" onPort:3000 error:&err]) {
printf("\nDid Not Return Okay: %s\n", [[err localizedDescription] UTF8String]);
} else {
printf("\nReturned Okay\n"); // This is printed
}

return self;
}

/* ASNYC DELEGATES */

/* I am expecting this method to be called when connectToHost: is called in init.. */

- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port {
printf("I'm connected! Host:%s\n", [host UTF8String]);
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
printf("I have written That was easy.\n");


}

- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag {
printf("I have read That was easy.\n");

dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
[_socket readDataWithTimeout:-1 tag:1];
}


});

}

@end

这是我在 ViewController 中创建 SocketConnection 实例的位置...

-(void)viewDidAppear:(BOOL)animated {
/* Socket connector */
SocketConnection *s = [SocketConnection sharedConnection];
printf("port: %hu\n" ,s.socket.connectedPort); // prints 0 right now
}

如果这不是实现我目标的最佳方式,请为我指出正确的方向(链接阅读、其他框架、库等)有任何问题请告诉我。

谢谢你的帮助。

最佳答案

好的,对于你的第一个目标(允许用户向其他用户发送推送通知并假设你有一个带有 express 和 mongodb 的 node.js 服务器端)尝试这样做:

首先在服务器端安装apn和node-gcm。

npm i --save apn node-gcm

这两个包用于向ios和android发送推送通知。

一旦你安装了这些包,就在你的服务器端创建一个路由来发送通知。这可以通过这样的方式完成:

const express = require('express');
const path = require('path');
const gcm = require('node-gcm');
const apn = require('apn');

const apnProvider = new apn.Provider({
token: {
// YOU CAN FOUND THIS KEYS AND THE CERTIFICATE ON APPLE DEVELOPERS SITE
key: path.resolve(__dirname, 'PATH TO YOUR CERTIFICATE.P8'),
keyId: YOUR APN KEY ID,
teamId: YOUR APN TEAM ID,
},
production: false,
});

router.post('/sendNotification', (req, res) => {
const deviceToken = req.body.token;
const message = req.body.message;
const payload = req.body.payload;
const packages = req.body.package;

switch (packages) {
case 'com.foo.bar': {
const notification = new apn.Notification();
notification.topic = 'com.foo.bar';
notification.expiry = Math.floor(Date.now() / 1000) + 3600;
notification.badge = 1;
notification.sound = 'ping.aiff';
notification.alert = { message };
notification.payload = { payload };
apnProvider.send(notification, deviceToken).then((result) => {
return result === 200 ? res.sendStatus(200, result) : res.sendStatus(400);
});
break;
}
case 'com.yourteam.foo.bar': {
const androidMessage = new gcm.Message({
priority: 'high',
contentAvailable: true,
delayWhileIdle: false,
timeToLive: 10,
restrictedPackageName: 'com.yourteam.foo.bar',
dryRun: false,
data: {
title: 'foo',
icon: '@mipmap/logo',
notId: parseInt(Math.random() * new Date().getSeconds(), 10),
message,
},
});
const sender = new gcm.Sender(YOUR_KEY);
const registrationTokens = [deviceToken];
sender.send(androidMessage, { registrationTokens }, (err, response) => {
return err ? res.send(err) : res.send(response);
});
break;
}
default:
return res.sendStatus(400);
}
});

现在要发送推送通知,您需要执行这样的 POST:

苹果

objective-c

#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/x-www-form-urlencoded",
@"cache-control": @"no-cache"

NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"token=xxxxx" dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:[@"&message=xxxxx" dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:[@"&payload=xxxxx" dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:[@"&package=xxxxx" dataUsingEncoding:NSUTF8StringEncoding]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://72.89.157.153:3000/notifications/sendNotification"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];

迅捷

import Foundation

let headers = [
"content-type": "application/x-www-form-urlencoded",
"cache-control": "no-cache"
]

let postData = NSMutableData(data: "token=xxxxx".data(using: String.Encoding.utf8)!)
postData.append("&message=xxxxx".data(using: String.Encoding.utf8)!)
postData.append("&payload=xxxxx".data(using: String.Encoding.utf8)!)
postData.append("&package=xxxxx".data(using: String.Encoding.utf8)!)

let request = NSMutableURLRequest(url: NSURL(string: "http://72.89.157.153:3000/notifications/sendNotification")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})

dataTask.resume()

网络(AJAX)

var settings = {
"async": true,
"crossDomain": true,
"url": "http://72.89.157.153:3000/notifications/sendNotification",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded",
"cache-control": "no-cache"
},
"data": {
"token": "xxxxx",
"message": "xxxxx",
"payload": "xxxxx",
"package": "xxxxx"
}
}

$.ajax(settings).done(function (response) {
console.log(response);
});

Java

OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "token=xxxxx&message=xxxxx&payload=xxxxx&package=xxxxx");
Request request = new Request.Builder()
.url("http://72.89.157.153:3000/notifications/sendNotification")
.post(body)
.addHeader("content-type", "application/x-www-form-urlencoded")
.addHeader("cache-control", "no-cache")
.build();

Response response = client.newCall(request).execute();

现在您可以向所有设备发送推送通知。

你的第二个目标可以通过你的服务器端轻松完成,当一个请求被发送到你的 URL 时,你可以做一个 POST 发送推送通知,例如如果有人想加你为 friend (可以说他们向 http://72.89.157.153:3000/friends/ {account_id} 发出了请求),您可以向用户发送通知,告诉他有新的友谊请求。

在 mongodb 上存储包和用户 token 很重要,这样您就可以发送正确的通知。

希望对您有所帮助。

关于IOS 设备间推送通知——GCDAsyncSocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45468888/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com