2017-08-02 232 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上存儲包和用戶令牌的重要性,因此您可以發送正確的通知。

希望它有幫助。