Skip to content

Commit

Permalink
* Added enableInAppAlertNotification, setSubscription, and postNotifi…
Browse files Browse the repository at this point in the history
…cation

* Calling EnableInAppAlertNotification with true will enable notifications to be displayed as alerts when one is received when the user is in your app.
   - On Android you call EnableNotificationsWhenActive with true place notifications in the notification area instead.
* Calling SetSubscription with false will unsubscribe the user from receiving push notifications.
* PostNotification lets you create user to user notifications and schedule future notifications without have to make calls to the REST API yourself.
* Added more logging to help debug issues.
* Android devices now retry to subscribe to GCM for push notifications if it fails due to a connection issue.
  • Loading branch information
jkasten2 committed Jun 4, 2015
1 parent 0205e49 commit e7dca57
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 74 deletions.
10 changes: 10 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,13 @@ Includes portions from DTTJailbreakDetection:
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Includes portions from BSMobileProvision:
Copyright (c) 2013, The Blindsight Corporation
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -29,78 +29,110 @@
using System.Collections;
using System.Collections.Generic;

using OneSignalPush.MiniJSON;

public class GameControllerExample : MonoBehaviour {

private static string extraMessage;

void Start () {
extraMessage = null;

// Enable line below to debug issues with setuping OneSignal. (logLevel, visualLogLevel)
//OneSignal.SetLogLevel(OneSignal.LOG_LEVEL.INFO, OneSignal.LOG_LEVEL.INFO);

// The only required method you need to call to setup OneSignal to recieve push notifications.
// Call before using any other methods on OneSignal.
// Should only be called once when your game is loaded.
// OneSignal.Init(OneSignal_AppId, GoogleProjectNumber, NotificationReceivedHandler(optional));
OneSignal.Init("b2f7f966-d8cc-11e4-bed1-df8f05be55ba", "703322744261", HandleNotification);
}

// Gets called when the user opens the notification or gets one while in your game.
// The name of the method can be anything as long as the signature matches.
// Method must be static or this object should be marked as DontDestroyOnLoad
private static void HandleNotification(string message, Dictionary<string, object> additionalData, bool isActive) {
print("GameControllerExample:HandleNotification");
print(message);

// When isActive is true this means the user is currently in your game.
// Use isActive and your own game logic so you don't interupt the user with a popup or menu when they are in the middle of playing your game.
if (additionalData != null) {
if (additionalData.ContainsKey("discount")) {
extraMessage = (string)additionalData["discount"];
// Take user to your store.
}
else if (additionalData.ContainsKey("actionSelected")) {
// actionSelected equals the id on the button the user pressed.
// actionSelected will equal "__DEFAULT__" when the notification itself was tapped when buttons were present.
extraMessage = "Pressed ButtonId: " + additionalData["actionSelected"];
}
}
}

// Test Menu
// Includes SendTag/SendTags and getting the userID and pushToken
void OnGUI () {
GUIStyle customTextSize = new GUIStyle("button");
customTextSize.fontSize = 30;

GUIStyle guiBoxStyle = new GUIStyle("box");
guiBoxStyle.fontSize = 30;

GUI.Box(new Rect(10, 10, 390, 250), "Test Menu", guiBoxStyle);

if (GUI.Button (new Rect (60, 80, 300, 60), "SendTags", customTextSize)) {
// You can tags users with key value pairs like this:
OneSignal.SendTag("UnityTestKey", "TestValue");
// Or use an IDictionary if you need to set more than one tag.
OneSignal.SendTags(new Dictionary<string, string>() { { "UnityTestKey2", "value2" }, { "UnityTestKey3", "value3" } });

// You can delete a single tag with it's key.
// OneSignal.DeleteTag("UnityTestKey");
// Or delete many with an IList.
// OneSignal.DeleteTags(new List<string>() {"UnityTestKey2", "UnityTestKey3" });
}

if (GUI.Button (new Rect (60, 170, 300, 60), "GetIds", customTextSize)) {
private static string extraMessage;

void Start () {
extraMessage = null;

// Enable line below to debug issues with setuping OneSignal. (logLevel, visualLogLevel)
//OneSignal.SetLogLevel(OneSignal.LOG_LEVEL.INFO, OneSignal.LOG_LEVEL.INFO);

// The only required method you need to call to setup OneSignal to receive push notifications.
// Call before using any other methods on OneSignal.
// Should only be called once when your app is loaded.
// OneSignal.Init(OneSignal_AppId, GoogleProjectNumber, NotificationReceivedHandler(optional));
OneSignal.Init("b2f7f966-d8cc-11e4-bed1-df8f05be55ba", "703322744261", HandleNotification);

// Shows a Native iOS/Android alert dialog when the user is in your app when a notification comes in.
OneSignal.EnableInAppAlertNotification(true);
}

// Gets called when the user opens the notification or gets one while in your app.
// The name of the method can be anything as long as the signature matches.
// Method must be static or this object should be marked as DontDestroyOnLoad
private static void HandleNotification(string message, Dictionary<string, object> additionalData, bool isActive) {
print("GameControllerExample:HandleNotification:message" + message);
extraMessage = "Notification opened with text: " + message;

// When isActive is true this means the user is currently in your game.
// Use isActive and your own game logic so you don't interrupt the user with a popup or menu when they are in the middle of playing your game.
if (additionalData != null) {
if (additionalData.ContainsKey("discount")) {
extraMessage = (string)additionalData["discount"];
// Take user to your store.
}
else if (additionalData.ContainsKey("actionSelected")) {
// actionSelected equals the id on the button the user pressed.
// actionSelected will equal "__DEFAULT__" when the notification itself was tapped when buttons were present.
extraMessage = "Pressed ButtonId: " + additionalData["actionSelected"];
}
}
}

// Test Menu
// Includes SendTag/SendTags, getting the userID and pushToken, and scheduling an example notification
void OnGUI () {
GUIStyle customTextSize = new GUIStyle("button");
customTextSize.fontSize = 30;

GUIStyle guiBoxStyle = new GUIStyle("box");
guiBoxStyle.fontSize = 30;

GUI.Box(new Rect(10, 10, 390, 340), "Test Menu", guiBoxStyle);

if (GUI.Button (new Rect (60, 80, 300, 60), "SendTags", customTextSize)) {
// You can tags users with key value pairs like this:
OneSignal.SendTag("UnityTestKey", "TestValue");
// Or use an IDictionary if you need to set more than one tag.
OneSignal.SendTags(new Dictionary<string, string>() { { "UnityTestKey2", "value2" }, { "UnityTestKey3", "value3" } });

// You can delete a single tag with it's key.
// OneSignal.DeleteTag("UnityTestKey");
// Or delete many with an IList.
// OneSignal.DeleteTags(new List<string>() {"UnityTestKey2", "UnityTestKey3" });
}

if (GUI.Button (new Rect (60, 170, 300, 60), "GetIds", customTextSize)) {
OneSignal.GetIdsAvailable((userId, pushToken) => {
extraMessage = "UserID:\n" + userId + "\n\nPushToken:\n" + pushToken;
});
}

if (extraMessage != null) {
guiBoxStyle.alignment = TextAnchor.UpperLeft;
guiBoxStyle.wordWrap = true;
GUI.Box (new Rect (10, 300, Screen.width - 20, Screen.height - 310), extraMessage, guiBoxStyle);
}
}
extraMessage = "UserID:\n" + userId + "\n\nPushToken:\n" + pushToken;
});
}

if (GUI.Button (new Rect (60, 260, 300, 60), "TestNotification", customTextSize)) {
extraMessage = "Waiting to get a OneSignal userId. Uncomment OneSignal.SetLogLevel in the Start method if it hangs here to debug the issue.";
OneSignal.GetIdsAvailable((userId, pushToken) => {
if (pushToken != null) {
// See http://documentation.onesignal.com/v2.0/docs/notifications-create-notification for a full list of options.
// You can not use included_segments or any fields that require your OneSignal 'REST API Key' in your app for security reasons.
// If you need to use your OneSignal 'REST API Key' you will need your own server where you can make this call.

var notification = new Dictionary<string, object>();
notification["contents"] = new Dictionary<string, string>() { {"en", "Test Message"} };
// Send notification to this device.
notification["include_player_ids"] = new List<string>() { userId };
// Example of scheduling a notification in the future.
notification["send_after"] = System.DateTime.Now.ToUniversalTime().AddSeconds(30).ToString("U");

extraMessage = "Posting test notification now.";
OneSignal.PostNotification(notification, (responseSuccess) => {
extraMessage = "Notification posted successful! Delayed by about 30 secounds to give you time to press the home button to see a notification vs an in-app alert.\n" + Json.Serialize(responseSuccess);
}, (responseFailure) => {
extraMessage = "Notification failed to post:\n" + Json.Serialize(responseFailure);
});
}
else
extraMessage = "ERROR: Device is not registered.";
});
}

if (extraMessage != null) {
guiBoxStyle.alignment = TextAnchor.UpperLeft;
guiBoxStyle.wordWrap = true;
GUI.Box (new Rect (10, 390, Screen.width - 20, Screen.height - 400), extraMessage, guiBoxStyle);
}
}
}
63 changes: 62 additions & 1 deletion UnityOneSignalExample/Assets/Plugins/OneSignal/OneSignal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#define ANDROID_ONLY
#endif

#if ONESIGNAL_PLATFORM && !UNITY_WP8
#define SUPPORTS_LOGGING
#endif

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
Expand All @@ -49,6 +53,9 @@ public class OneSignal : MonoBehaviour {
public delegate void IdsAvailable(string playerID, string pushToken);
public delegate void TagsReceived(Dictionary<string, object> tags);

public delegate void OnPostNotificationSuccess(Dictionary<string, object> response);
public delegate void OnPostNotificationFailure(Dictionary<string, object> response);

public static IdsAvailable idsAvailableDelegate = null;
public static TagsReceived tagsReceivedDelegate = null;

Expand All @@ -57,12 +64,16 @@ public enum LOG_LEVEL {
}

#if ONESIGNAL_PLATFORM
#if SUPPORTS_LOGGING
private static LOG_LEVEL logLevel = LOG_LEVEL.INFO, visualLogLevel = LOG_LEVEL.NONE;
#endif

private static OneSignalPlatform oneSignalPlatform = null;
private static bool initialized = false;

internal static NotificationReceived notificationDelegate = null;
internal static OnPostNotificationSuccess postNotificationSuccessDelegate = null;
internal static OnPostNotificationFailure postNotificationFailureDelegate = null;

// Name of the GameObject that gets automaticly created in your game scene.
private const string gameObjectName = "OneSignalRuntimeObject_KEEP";
Expand Down Expand Up @@ -113,7 +124,7 @@ public static void Init(string appId) {
}

public static void SetLogLevel(LOG_LEVEL inLogLevel, LOG_LEVEL inVisualLevel) {
#if ONESIGNAL_PLATFORM
#if SUPPORTS_LOGGING
logLevel = inLogLevel; visualLogLevel = inVisualLevel;
#endif
}
Expand Down Expand Up @@ -202,6 +213,38 @@ public static void EnableSound(bool enable) {
#endif
}

public static void EnableNotificationsWhenActive(bool enable) {
#if ANDROID_ONLY
((OneSignalAndroid)oneSignalPlatform).EnableNotificationsWhenActive(enable);
#endif
}

public static void EnableInAppAlertNotification(bool enable) {
#if ONESIGNAL_PLATFORM
oneSignalPlatform.EnableInAppAlertNotification(enable);
#endif
}

public static void SetSubscription(bool enable) {
#if ONESIGNAL_PLATFORM
oneSignalPlatform.SetSubscription(enable);
#endif
}

public static void PostNotification(Dictionary<string, object> data) {
#if ONESIGNAL_PLATFORM
PostNotification(data, null, null);
#endif
}

public static void PostNotification(Dictionary<string, object> data, OnPostNotificationSuccess inOnPostNotificationSuccess, OnPostNotificationFailure inOnPostNotificationFailure) {
#if ONESIGNAL_PLATFORM
postNotificationSuccessDelegate = inOnPostNotificationSuccess;
postNotificationFailureDelegate = inOnPostNotificationFailure;
oneSignalPlatform.PostNotification(data);
#endif
}


/*** protected and private methods ****/
#if ONESIGNAL_PLATFORM
Expand Down Expand Up @@ -229,5 +272,23 @@ private void onTagsReceived(string jsonString) {
void OnApplicationPause(bool paused) {
oneSignalPlatform.OnApplicationPause(paused);
}

// Called from the native SDK
private void onPostNotificationSuccess(string response) {
if (postNotificationSuccessDelegate != null) {
postNotificationSuccessDelegate(Json.Deserialize(response) as Dictionary<string, object>);
postNotificationFailureDelegate = null;
postNotificationSuccessDelegate = null;
}
}

// Called from the native SDK
private void onPostNotificationFailed(string response) {
if (postNotificationFailureDelegate != null) {
postNotificationFailureDelegate(Json.Deserialize(response) as Dictionary<string, object>);
postNotificationFailureDelegate = null;
postNotificationSuccessDelegate = null;
}
}
#endif
}
16 changes: 16 additions & 0 deletions UnityOneSignalExample/Assets/Plugins/OneSignal/OneSignalAndroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,21 @@ public void EnableVibrate(bool enable) {
public void EnableSound(bool enable) {
mOneSignal.Call("enableSound", enable);
}

public void EnableInAppAlertNotification(bool enable) {
mOneSignal.Call("enableInAppAlertNotification", enable);
}

public void EnableNotificationsWhenActive(bool enable) {
mOneSignal.Call("enableNotificationsWhenActive", enable);
}

public void SetSubscription(bool enable) {
mOneSignal.Call("setSubscription", enable);
}

public void PostNotification(Dictionary<string, object> data) {
mOneSignal.Call("postNotification", Json.Serialize(data));
}
}
#endif
21 changes: 21 additions & 0 deletions UnityOneSignalExample/Assets/Plugins/OneSignal/OneSignalIOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ public class OneSignalIOS : OneSignalPlatform {
[System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void _idsAvailable();

[System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void _enableInAppAlertNotification(bool enable);

[System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void _setSubscription(bool enable);

[System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void _postNotification(string json);

[System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void _setLogLevel(int logLevel, int visualLogLevel);

Expand Down Expand Up @@ -93,6 +102,18 @@ public void IdsAvailable() {
_idsAvailable();
}

public void EnableInAppAlertNotification(bool enable) {
_enableInAppAlertNotification(enable);
}

public void SetSubscription(bool enable) {
_setSubscription(enable);
}

public void PostNotification(Dictionary<string, object> data) {
_postNotification(Json.Serialize(data));
}

public void FireNotificationReceivedEvent(string jsonString, OneSignal.NotificationReceived notificationReceived) {
var dict = Json.Deserialize(jsonString) as Dictionary<string, object>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public interface OneSignalPlatform {
void DeleteTags(IList<string> keys);
void OnApplicationPause(bool paused);
void IdsAvailable();
void EnableInAppAlertNotification(bool enable);
void SetSubscription(bool enable);
void PostNotification(Dictionary<string, object> data);

void FireNotificationReceivedEvent(string jsonString, OneSignal.NotificationReceived notificationReceived);
}
9 changes: 9 additions & 0 deletions UnityOneSignalExample/Assets/Plugins/OneSignal/OneSignalWP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ public void IdsAvailable() {
});
}

// Not available the WP SDK.
public void EnableInAppAlertNotification(bool enable) { }

// Not available in WP SDK.
public void SetSubscription(bool enable) {}

// Not available in WP SDK.
public void PostNotification(Dictionary<string, object> data) { }

// Doesn't apply to Windows Phone: The Callback is setup in the constructor so this is never called.
public void FireNotificationReceivedEvent(string jsonString, OneSignal.NotificationReceived notificationReceived) {}

Expand Down
2 changes: 1 addition & 1 deletion UnityOneSignalExample/Assets/Plugins/OneSignal/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.0
1.9.0
Loading

0 comments on commit e7dca57

Please sign in to comment.