2017-08-02 176 views
0

您好研究员程序员,IOS推送通知 - GCDAsyncSocket

我试图让用户推送通知发送给其他用户(如发送好友请求等)。

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

比方说用{ACCOUNT_ID}用户登录,路径到他的帐户信息将是:“http://72.89.157.153:3000/accounts/ {ACCOUNT_ID}

我想我的应用程序来听任何请求发送到这个网址我使用GCDAsyncSocket库来帮助解决这个问题,但是当我连接到http://72.89.157.153:3000/进行测试时,没有委托函数被调用,我看到很多人都遇到了同样的问题,但是我没有得到任何我已经阅读的解决方案。

代码:

SocketCo nnection.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 
} 

如果这不是实现我的目标的最佳方式,请指出我的正确方向(链接阅读,其他框架,图书馆等) 有任何问题,请让我知道。

谢谢你的帮助。

回答

2

好,你的第一个目标(允许用户发送推送通知给其他用户,并假设你有快递和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推送通知:

IOS

目标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]; 

SWIFT

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() 

WEB(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发送推送通知,例如,如果有人想将您添加为朋友(让我们说他们向http://72.89.157.153:3000/friends/ {account_id})发出了一个请求,您可以向用户发送通知,告诉他他有新的友谊请求。

它在mongodb上存储包和用户令牌的重要性,因此您可以发送正确的通知。

希望它有帮助。