2017-08-02 17 views
0

こんにちはフェロープログラマ、IOSのプッシュ通知 - GCDAsyncSocket

私は、ユーザーが(など、友達リクエストを送信するなど)他のユーザーにプッシュ通知を送信できるようにしようとしています。

ここでの最終目標は、ユーザーが自分のアカウントにログインすると(特定のビューが読み込まれた後)、引き続きiOSアプリが特定のホスト名/ポートURLを聞くことです。私のスタックは、MongoDBと通信する高速サーバです。

は{ACCOUNT_ID}を持つユーザがログインし、自分のアカウント情報へのパスは次のようになりますとしましょう:「http://72.89.157.153:3000/accounts/ {ACCOUNT_ID}

私は私のアプリは、このURLに送信するすべての要求に耳を傾けたいと思い、私は思います。しかし、私は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 

ここで私はSocketConnectionのインスタンスを作成のViewControllerのスポットです...

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

この2つのパッケージは、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); 
} 
}); 

あなたはこの1つのようなPOSTを実行する必要がありプッシュ通知を送信するには:

IOS

の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]; 

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

今、あなたはすべてのデバイスにプッシュ通知を送信することができます。

あなたの2番目の目標は、サーバー側で簡単に行うことができます。リクエストがURLに送信されたときに、プッシュ通知を送信するPOSTを実行できます。たとえば、誰かがあなたを友達として追加したい場合などです。彼らはhttp://72.89.157.153:3000/friends/ {account_id}にリクエストしました)、あなたに新しい友人関係のリクエストがあることを知らせる通知をユーザーに送信できます。

mongodbの重要な点は、パッケージとユーザーのトークンを保存することで、正しい通知を送信できることです。

希望します。