2015-08-21 12 views
6

मैंने अपने आईओएस एप्लिकेशन पर जीसीएम को लागू करने के लिए इस ट्यूटोरियल https://developers.google.com/cloud-messaging/ios/client का पालन किया है। मेरा ऐप सर्वर जावा में लिखा गया एक Google ऐप इंजन है और मैं gcm-server.jar https://github.com/google/gcm लाइब्रेरी का उपयोग करता हूं। मुझे लगता है कि मेरे प्रमाणपत्र ठीक हैं और मैं पंजीकरण कर सकता हूं, एक टोकन प्राप्त कर सकता हूं और यहां तक ​​कि मेरे ऐप सर्वर द्वारा भेजे गए संदेशों की सामग्री भी प्राप्त कर सकता हूं। हालांकि, जब ऐप पृष्ठभूमि में होता है तो मुझे कोई अधिसूचना अलर्ट प्राप्त नहीं होता है, मैं हमेशा इसे तब प्राप्त करता हूं जब मैं इसे पुनरारंभ करने के लिए ऐप आइकन पर क्लिक करता हूं।Google क्लाउड मैसेजिंग: आईओएस ऐप पृष्ठभूमि में होने पर अलर्ट प्राप्त नहीं करते

मैंने सोचा था कि था, क्योंकि मैं केवल didReceiveRemoteNotification: को लागू किया गया था और नहीं didReceiveRemoteNotification:fetchCompletionHandler: तो मैं यह पहली बार एक के बजाय लागू किया, लेकिन मैं थोड़ी देर के लिए या तो और बदतर पृष्ठभूमि में ऐप्लिकेशन क्रैश की तरह कुछ कह सूचनाएं प्राप्त नहीं करते "गैर मान्यता प्राप्त चयनकर्ता भेजा उदाहरण के लिए किया गया RereiveRemoteNotification: "उपयोगकर्ता इन्फॉर्फ़ में कुछ गलत था। मैंने xCode में पृष्ठभूमि मोड को इसके लिए जरूरी की अनुमति दी थी। यहाँ कोड मैं का उपयोग किया जाता है:

AppDelegate() 

@property (nonatomic, strong) NSDictionary *registrationOptions; 
@property (nonatomic, strong) GGLInstanceIDTokenHandler registrationHandler; 

@end 

@implementation AppDelegate 


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

//-- Set Notification 
[[GCMService sharedInstance] startWithConfig:[GCMConfig defaultConfig]]; 
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) 
{ 
    NSLog(@"Case iOS8"); 
    // iOS 8 Notifications 
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; 

    [application registerForRemoteNotifications]; 
} 
else 
{ 
    NSLog(@"Case iOS7"); 
    // iOS < 8 Notifications 
    [application registerForRemoteNotificationTypes: 
    (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)]; 
} 

self.registrationHandler = ^(NSString *registrationToken, NSError *error){ 
    if (registrationToken != nil) { 

     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
     [defaults setObject:registrationToken forKey:TOKENGCM]; 
     NSLog(@"Registration Token: %@", registrationToken); 
     //some code 
    } else { 
     NSLog(@"Registration to GCM failed with error: %@", error.localizedDescription); 
    } 
}; 
return YES; 
} 

- (void)applicationWillResignActive:(UIApplication *)application { 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application { 
[[GCMService sharedInstance] disconnect]; 
} 

- (void)applicationWillEnterForeground:(UIApplication *)application { 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application { 
// Connect to the GCM server to receive non-APNS notifications 
[[GCMService sharedInstance] connectWithHandler:^(NSError *error) { 
    if (error) { 
     NSLog(@"Could not connect to GCM: %@", error.localizedDescription); 
    } else { 
     NSLog(@"Connected to GCM"); 
     // ... 
    } 
}]; 
} 

- (void)applicationWillTerminate:(UIApplication *)application { 
} 


- (void)application:(UIApplication *)application 
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
// Start the GGLInstanceID shared instance with the default config and request a registration 
// token to enable reception of notifications 
[[GGLInstanceID sharedInstance] startWithConfig:[GGLInstanceIDConfig defaultConfig]]; 
self.registrationOptions = @{kGGLInstanceIDRegisterAPNSOption:deviceToken, 
         kGGLInstanceIDAPNSServerTypeSandboxOption:@NO}; 
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:SENDER_ID 
                scope:kGGLInstanceIDScopeGCM 
                options:self.registrationOptions 
                handler:self.registrationHandler]; 
} 

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
NSLog(@"Error in registration. Error: %@", err); 
} 

- (void)onTokenRefresh { 
// A rotation of the registration tokens is happening, so the app needs to request a new token. 
NSLog(@"The GCM registration token needs to be changed."); 
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:SENDER_ID 
                scope:kGGLInstanceIDScopeGCM 
                options:self.registrationOptions 
                handler:self.registrationHandler]; 
} 


- (void)application:(UIApplication *)application 
didReceiveRemoteNotification:(NSDictionary *)userInfo { 
NSLog(@"Notification received: %@", userInfo);//This does print the content of my message in the console if the app is in foreground 
UIApplicationState state = [application applicationState]; 
if (state == UIApplicationStateActive) { 
    NSString *cancelTitle = @"Close"; 
    NSString *showTitle = @"Show"; 
    NSString *message = [[userInfo valueForKey:@"aps"] valueForKey:@"alert"]; 
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Some title" 
                 message:message 
                 delegate:self 
               cancelButtonTitle:cancelTitle 
               otherButtonTitles:showTitle, nil]; 
    [alertView show]; 
} 
else{ 
    NSLog(@"Notification received while inactive"); 
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 99]; 
    UIAlertView *BOOM = [[UIAlertView alloc] initWithTitle:@"BOOM" 
                message:@"app was INACTIVE" 
                delegate:self 
             cancelButtonTitle:@"a-ha!" 
             otherButtonTitles:nil]; 
    [BOOM show]; 
    NSLog(@"App was NOT ACTIVE"); 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification!" 
                 object:nil 
                 userInfo:userInfo]; 
} 
// This works only if the app started the GCM service 
[[GCMService sharedInstance] appDidReceiveMessage:userInfo]; 
} 

//Implement that causes unrecognized selector crash 
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler { 
NSLog(@"Notification received: %@", userInfo); 
// This works only if the app started the GCM service 
[[GCMService sharedInstance] appDidReceiveMessage:userInfo]; 
// Handle the received message 
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value 
// [START_EXCLUDE] 
[[NSNotificationCenter defaultCenter] postNotificationName:@"notif" 
                object:nil 
                userInfo:userInfo]; 
handler(UIBackgroundFetchResultNoData); 
// [END_EXCLUDE] 
} 

@end 

कोई यह पता लगाने सकते हैं कि मैं जब अग्रभूमि में नहीं सूचनाएं प्राप्त नहीं करते क्या?

संपादित: सर्वर साइड पर इस्तेमाल किया जावा कोड GCM संदेश भेजने के:

public static MulticastResult sendViaGCM(String tag, String message, List<String> deviceIdsList) throws IOException { 
    Sender sender = new Sender(Constantes.API_KEY); 
    // This message object is a Google Cloud Messaging object 
    Message msg = new Message.Builder().addData("tag",tag).addData("message", message).build(); 
    MulticastResult result = sender.send(msg, deviceIdsList, 5); 
    return result; 
} 

EDIT2:: पोस्ट अनुरोध http://image.noelshack.com/fichiers/2015/34/1440193492-gcm1.png http://image.noelshack.com/fichiers/2015/34/1440193502-gcm2.png

EDIT3 की स्क्रीनशॉट अनुरोध अब मैं अपने ऐप सर्वर से भेजता हूं:

public static void sendGCMMessage(String tag, String message, List<String> deviceIdsList) { 
    String request = "https://gcm-http.googleapis.com/gcm/send"; 
    try{ 
     URL url = new URL(request); 
     HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
     conn.setDoOutput(true); 
     //conn.setInstanceFollowRedirects(false); 
     conn.setRequestMethod("POST"); 
     //Les deux headers obligatoires: 
     conn.setRequestProperty("Content-Type", "application/json"); 
     conn.setRequestProperty("Authorization", "key=" + API_KEY); 
     //Construction du JSON: 
     JSONObject fullJSON = new JSONObject(); 
     JSONObject data=new JSONObject(); 
     JSONObject notification=new JSONObject(); 
     data.put("tag", tag); 
     data.put("message", message); 
     notification.put("sound", "default"); 
     notification.put("badge", "1"); 
     notification.put("title", "default"); 
     notification.put("body", message); 
     fullJSON.put("registration_ids", deviceIdsList); 

     fullJSON.put("notification", notification); 
     fullJSON.put("content_available", "true"); 
     fullJSON.put("data", data); 

     //Phase finale: 
     OutputStreamWriter wr= new OutputStreamWriter(conn.getOutputStream()); 
     wr.write(fullJSON.toString()); 
     wr.flush(); 
     wr.close();//pas obligatoire 
     //conn.setUseCaches(false); 
    } 
    catch(Exception e){ 
     e.printStackTrace(); 
    } 

उत्तर

11

GCM documentation के आधार पर, आप content_available से true पर सेट कर सकते हैं।

(आईओएस पर, एपीएनएस पेलोड में उपलब्ध सामग्री का प्रतिनिधित्व करने के लिए इस क्षेत्र का उपयोग करें। जब कोई अधिसूचना या संदेश भेजा जाता है और यह सत्य पर सेट होता है, तो एक निष्क्रिय क्लाइंट ऐप जागृत होता है। एंड्रॉइड पर, डेटा संदेश जागते हैं डिफ़ॉल्ट रूप से अनुप्रयोग। Chrome पर, वर्तमान में समर्थित नहीं।)

content_available एप्पल के content-available, जो आप this Apple Push Notification Service documentation में पा सकते हैं के अनुरूप है।

इसके अलावा, आपको अपने आईओएस एप्लिकेशन को संदेश भेजने के लिए Notification playload का उपयोग करना चाहिए, ताकि जब आपका ऐप पृष्ठभूमि में हो तो यह बैनर दिखा सकता है।

यहां नमूने HTTP अनुरोध है:

https://gcm-http.googleapis.com/gcm/send 
Content-Type:application/json 
Authorization:key=API_KEY 
{ 
    "to" : "REGISTRATION_TOKEN", 
    "notification" : { 
    "sound" : "default", 
    "badge" : "1", 
    "title" : "default", 
    "body" : "Test", 
    }, 
    "content_available" : true, 
} 

The Java library सिर्फ एक नमूना है, आप इसे करने के लिए अन्य क्षेत्रों में जोड़ सकते हैं। उदाहरण के लिए, Message.java कक्षा में, आप दो निजी चर जोड़ सकते हैं, एक private final Boolean contentAvailable है, दूसरा एक private final Map<String, String> notification है।

आप curl -i -H "Content-Type:application/json" -H "Authorization:key=API_KEY" -X POST -d '{"to":"REGISTRATION_TOKEN", "notificaiton":{"sound":"default", "badge":"1", "title": "default", "body":"test",},"content_available":true}' https://android.googleapis.com/gcm/send करके अपने टर्मिनल में HTTP अनुरोध का प्रयास कर सकते हैं, या Postman पर इसे आजमाएं।

संपादित:

यदि आपका आवेदन निरस्त कर दी गई है, और पुश नोटिफिकेशन के लिए आप चाहते हैं अपने डिवाइस में दिखाई जाने वाली, तो आप अपने HTTP अनुरोध शरीर में एक high priority (सेट कर सकते हैं कि करने के लिए अपने संदेश की स्थापना सावधान रहना उच्च प्राथमिकता सामान्य प्राथमिकता संदेशों की तुलना में बैटरी नाली में अधिक योगदान देती है)।

नमूना HTTP अनुरोध:

{ 
    "to" : "REGISTRATION_TOKEN", 
    "notification" : { 
    "sound" : "default", 
    "badge" : "1", 
    "title" : "default", 
    "body" : "Test", 
    }, 
    "content_available" : true, 
    "priority" : "normal", 
} 
+0

क्या आगे बढ़ने का कोई और तरीका है? चूंकि जावा लाइब्रेरी का उपयोग मैं करता हूं (https://github.com/google/gcm) सामग्री_ उपलब्ध फ़ील्ड या अधिसूचना पेलोड को प्रदर्शित नहीं करता है। मैं उस लाइब्रेरी का उपयोग करके भेजे गए संदेश के कोड स्निपेट को रखने के लिए अपना उत्तर संपादित करूंगा। – Gannicus

+0

@Gannicus, कृपया मेरा संपादन उत्तर देखें। – ztan

+1

पोस्टमैन के विचार के लिए धन्यवाद। मैंने आपके POST अनुरोध का उपयोग करने का प्रयास किया लेकिन यह वास्तव में अजीब है: अगर मैं अनुरोध भेजता हूं, तो मुझे एक "त्रुटि: रिपोर्ट नहीं किया गया" मिलता है और ऐप अब अधिसूचनाएं प्राप्त नहीं कर सकता है (यहां तक ​​कि जिन्हें मैंने अग्रभूमि में प्राप्त किया था)। मुझे इसे फिर से काम करने के लिए एक नया जीसीएम टोकन जेनरेट करना होगा और जैसे ही मैं POST अनुरोध का उपयोग करता हूं, यह फिर से होता है। तुम जानते हो क्यों? – Gannicus

4

मैं एक ही समस्या थी, जब एप्लिकेशन की मौत हो गई, इस पोस्ट अब काम कर रहा है विषय सूचना प्राप्त नहीं कर सकता है, मैं प्राथमिकता hight जोड़ने के लिए किया था।

{ 
    "to" : "/topics/offers", 
    "notification" : { 
    "sound" : "default", 
    "badge" : "1", 
    "body" : "Text", 
    }, 
    "priority" : "high", 
} 
+0

धन्यवाद! आपने मेरा जीवन बचाया: डी –

संबंधित मुद्दे