Skip to content

Commit 2f08dc8

Browse files
authored
Merge pull request #84 from OneSignal/email
Adds Email to the Unity SDK
2 parents 4d7fef7 + 53bdc4a commit 2f08dc8

File tree

17 files changed

+1188
-95
lines changed

17 files changed

+1188
-95
lines changed

OneSignalExample/Assets/OneSignal/Example/GameControllerExample.cs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
public class GameControllerExample : MonoBehaviour {
3535

3636
private static string extraMessage;
37+
public string email = "Email Address";
3738

3839
void Start () {
3940
extraMessage = null;
@@ -54,23 +55,29 @@ void Start () {
5455
OneSignal.inFocusDisplayType = OneSignal.OSInFocusDisplayOption.Notification;
5556
OneSignal.permissionObserver += OneSignal_permissionObserver;
5657
OneSignal.subscriptionObserver += OneSignal_subscriptionObserver;
58+
OneSignal.emailSubscriptionObserver += OneSignal_emailSubscriptionObserver;
5759

5860
var pushState = OneSignal.GetPermissionSubscriptionState();
5961
Debug.Log("pushState.subscriptionStatus.subscribed : " + pushState.subscriptionStatus.subscribed);
6062
Debug.Log("pushState.subscriptionStatus.userId : " + pushState.subscriptionStatus.userId);
6163
}
6264

6365
private void OneSignal_subscriptionObserver(OSSubscriptionStateChanges stateChanges) {
64-
Debug.Log("stateChanges: " + stateChanges);
65-
Debug.Log("stateChanges.to.userId: " + stateChanges.to.userId);
66-
Debug.Log("stateChanges.to.subscribed: " + stateChanges.to.subscribed);
66+
Debug.Log("SUBSCRIPTION stateChanges: " + stateChanges);
67+
Debug.Log("SUBSCRIPTION stateChanges.to.userId: " + stateChanges.to.userId);
68+
Debug.Log("SUBSCRIPTION stateChanges.to.subscribed: " + stateChanges.to.subscribed);
6769
}
6870

69-
private void OneSignal_permissionObserver(OSPermissionStateChanges stateChanges) {
70-
Debug.Log("stateChanges.from.status: " + stateChanges.from.status);
71-
Debug.Log("stateChanges.to.status: " + stateChanges.to.status);
71+
private void OneSignal_permissionObserver(OSPermissionStateChanges stateChanges) {
72+
Debug.Log("PERMISSION stateChanges.from.status: " + stateChanges.from.status);
73+
Debug.Log("PERMISSION stateChanges.to.status: " + stateChanges.to.status);
7274
}
7375

76+
private void OneSignal_emailSubscriptionObserver(OSEmailSubscriptionStateChanges stateChanges) {
77+
Debug.Log("EMAIL stateChanges.from.status: " + stateChanges.from.emailUserId + ", " + stateChanges.from.emailAddress);
78+
Debug.Log("EMAIL stateChanges.to.status: " + stateChanges.to.emailUserId + ", " + stateChanges.to.emailAddress);
79+
}
80+
7481
// Called when your app is in focus and a notificaiton is recieved.
7582
// The name of the method can be anything as long as the signature matches.
7683
// Method must be static or this object should be marked as DontDestroyOnLoad
@@ -107,11 +114,11 @@ public static void HandleNotificationOpened(OSNotificationOpenedResult result) {
107114
Debug.Log("[HandleNotificationOpened] message "+ message +", additionalData: "+ Json.Serialize(additionalData) as string);
108115

109116
if (actionID != null) {
110-
// actionSelected equals the id on the button the user pressed.
111-
// actionSelected will equal "__DEFAULT__" when the notification itself was tapped when buttons were present.
112-
extraMessage = "Pressed ButtonId: " + actionID;
113-
}
114-
}
117+
// actionSelected equals the id on the button the user pressed.
118+
// actionSelected will equal "__DEFAULT__" when the notification itself was tapped when buttons were present.
119+
extraMessage = "Pressed ButtonId: " + actionID;
120+
}
121+
}
115122

116123
// Test Menu
117124
// Includes SendTag/SendTags, getting the userID and pushToken, and scheduling an example notification
@@ -122,9 +129,24 @@ void OnGUI () {
122129
GUIStyle guiBoxStyle = new GUIStyle("box");
123130
guiBoxStyle.fontSize = 30;
124131

125-
GUI.Box(new Rect(10, 10, 390, 340), "Test Menu", guiBoxStyle);
132+
GUIStyle textFieldStyle = new GUIStyle ("textField");
133+
textFieldStyle.fontSize = 30;
134+
135+
136+
float itemOriginX = 50.0f;
137+
float itemWidth = Screen.width - 120.0f;
138+
float boxWidth = Screen.width - 20.0f;
139+
float boxOriginY = 120.0f;
140+
float boxHeight = 630.0f;
141+
float itemStartY = 200.0f;
142+
float itemHeightOffset = 90.0f;
143+
float itemHeight = 60.0f;
144+
145+
GUI.Box(new Rect(10, boxOriginY, boxWidth, boxHeight), "Test Menu", guiBoxStyle);
146+
147+
float count = 0.0f;
126148

127-
if (GUI.Button (new Rect (60, 80, 300, 60), "SendTags", customTextSize)) {
149+
if (GUI.Button (new Rect (itemOriginX, itemStartY + (count * itemHeightOffset), itemWidth, itemHeight), "SendTags", customTextSize)) {
128150
// You can tags users with key value pairs like this:
129151
OneSignal.SendTag("UnityTestKey", "TestValue");
130152
// Or use an IDictionary if you need to set more than one tag.
@@ -136,13 +158,18 @@ void OnGUI () {
136158
// OneSignal.DeleteTags(new List<string>() {"UnityTestKey2", "UnityTestKey3" });
137159
}
138160

139-
if (GUI.Button (new Rect (60, 170, 300, 60), "GetIds", customTextSize)) {
140-
OneSignal.IdsAvailable((userId, pushToken) => {
161+
count++;
162+
163+
if (GUI.Button (new Rect (itemOriginX, itemStartY + (count * itemHeightOffset), itemWidth, itemHeight), "GetIds", customTextSize)) {
164+
OneSignal.IdsAvailable((userId, pushToken) => {
141165
extraMessage = "UserID:\n" + userId + "\n\nPushToken:\n" + pushToken;
142166
});
143167
}
144168

145-
if (GUI.Button (new Rect (60, 260, 300, 60), "TestNotification", customTextSize)) {
169+
170+
count++;
171+
172+
if (GUI.Button (new Rect (itemOriginX, itemStartY + (count * itemHeightOffset), itemWidth, itemHeight), "TestNotification", customTextSize)) {
146173
extraMessage = "Waiting to get a OneSignal userId. Uncomment OneSignal.SetLogLevel in the Start method if it hangs here to debug the issue.";
147174
OneSignal.IdsAvailable((userId, pushToken) => {
148175
if (pushToken != null) {
@@ -158,21 +185,50 @@ void OnGUI () {
158185
notification["send_after"] = System.DateTime.Now.ToUniversalTime().AddSeconds(30).ToString("U");
159186

160187
extraMessage = "Posting test notification now.";
188+
161189
OneSignal.PostNotification(notification, (responseSuccess) => {
162190
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);
163191
}, (responseFailure) => {
164192
extraMessage = "Notification failed to post:\n" + Json.Serialize(responseFailure);
165193
});
166-
}
167-
else
194+
} else {
168195
extraMessage = "ERROR: Device is not registered.";
196+
}
197+
});
198+
}
199+
200+
count++;
201+
202+
email = GUI.TextField (new Rect (itemOriginX, itemStartY + (count * itemHeightOffset), itemWidth, itemHeight), email, customTextSize);
203+
204+
count++;
205+
206+
if (GUI.Button (new Rect (itemOriginX, itemStartY + (count * itemHeightOffset), itemWidth, itemHeight), "SetEmail", customTextSize)) {
207+
extraMessage = "Setting email to " + email;
208+
209+
OneSignal.SetEmail (email, () => {
210+
Debug.Log("Successfully set email");
211+
}, (error) => {
212+
Debug.Log("Encountered error setting email: " + Json.Serialize(error));
213+
});
214+
}
215+
216+
count++;
217+
218+
if (GUI.Button (new Rect (itemOriginX, itemStartY + (count * itemHeightOffset), itemWidth, itemHeight), "LogoutEmail", customTextSize)) {
219+
extraMessage = "Logging Out of [email protected]";
220+
221+
OneSignal.LogoutEmail (() => {
222+
Debug.Log("Successfully logged out of email");
223+
}, (error) => {
224+
Debug.Log("Encountered error logging out of email: " + Json.Serialize(error));
169225
});
170226
}
171227

172228
if (extraMessage != null) {
173229
guiBoxStyle.alignment = TextAnchor.UpperLeft;
174230
guiBoxStyle.wordWrap = true;
175-
GUI.Box (new Rect (10, 390, Screen.width - 20, Screen.height - 400), extraMessage, guiBoxStyle);
231+
GUI.Box (new Rect (10, boxOriginY + boxHeight + 20, Screen.width - 20, Screen.height - (boxOriginY + boxHeight + 40)), extraMessage, guiBoxStyle);
176232
}
177233
}
178234
}
Binary file not shown.

OneSignalExample/Assets/OneSignal/Platforms/iOS/OneSignal.h

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
#import <UserNotifications/UserNotifications.h>
5151
#endif
5252

53+
54+
#pragma clang diagnostic push
55+
#pragma clang diagnostic ignored "-Wstrict-prototypes"
56+
#pragma clang diagnostic ignored "-Wnullability-completeness"
57+
5358
/* The action type associated to an OSNotificationAction object */
5459
typedef NS_ENUM(NSUInteger, OSNotificationActionType) {
5560
OSNotificationActionTypeOpened,
@@ -236,26 +241,42 @@ typedef NS_ENUM(NSInteger, OSNotificationPermission) {
236241

237242
@end
238243

239-
@interface OSSubscriptionStateChanges : NSObject
240244

245+
@interface OSEmailSubscriptionState : NSObject
246+
@property (readonly, nonatomic) NSString* emailUserId; // The new Email user ID
247+
@property (readonly, nonatomic) NSString *emailAddress;
248+
@property (readonly, nonatomic) BOOL subscribed;
249+
- (NSDictionary*)toDictionary;
250+
@end
251+
252+
@interface OSSubscriptionStateChanges : NSObject
241253
@property (readonly) OSSubscriptionState* to;
242254
@property (readonly) OSSubscriptionState* from;
243-
244255
- (NSDictionary*)toDictionary;
256+
@end
245257

258+
@interface OSEmailSubscriptionStateChanges : NSObject
259+
@property (readonly) OSEmailSubscriptionState* to;
260+
@property (readonly) OSEmailSubscriptionState* from;
261+
- (NSDictionary*)toDictionary;
246262
@end
247263

248264
@protocol OSSubscriptionObserver <NSObject>
249265
- (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges*)stateChanges;
250266
@end
251267

268+
@protocol OSEmailSubscriptionObserver <NSObject>
269+
- (void)onOSEmailSubscriptionChanged:(OSEmailSubscriptionStateChanges*)stateChanges;
270+
@end
271+
252272

253273

254274
// Permission+Subscription Classes
255275
@interface OSPermissionSubscriptionState : NSObject
256276

257277
@property (readonly) OSPermissionState* permissionStatus;
258278
@property (readonly) OSSubscriptionState* subscriptionStatus;
279+
@property (readonly) OSEmailSubscriptionState *emailSubscriptionStatus;
259280
- (NSDictionary*)toDictionary;
260281

261282
@end
@@ -341,7 +362,6 @@ typedef NS_ENUM(NSUInteger, ONE_S_LOG_LEVEL) {
341362
+ (void)deleteTags:(NSArray*)keys onSuccess:(OSResultSuccessBlock)successBlock onFailure:(OSFailureBlock)failureBlock;
342363
+ (void)deleteTags:(NSArray*)keys;
343364
+ (void)deleteTagsWithJsonString:(NSString*)jsonString;
344-
345365
// Optional method that sends us the user's email as an anonymized hash so that we can better target and personalize notifications sent to that user across their devices.
346366
// Sends as MD5 and SHA1 of the provided email
347367
+ (void)syncHashedEmail:(NSString*)email;
@@ -357,6 +377,9 @@ typedef NS_ENUM(NSUInteger, ONE_S_LOG_LEVEL) {
357377
+ (void)addSubscriptionObserver:(NSObject<OSSubscriptionObserver>*)observer;
358378
+ (void)removeSubscriptionObserver:(NSObject<OSSubscriptionObserver>*)observer;
359379

380+
+ (void)addEmailSubscriptionObserver:(NSObject<OSEmailSubscriptionObserver>*)observer;
381+
+ (void)removeEmailSubscriptionObserver:(NSObject<OSEmailSubscriptionObserver>*)observer;
382+
360383
+ (void)setSubscription:(BOOL)enable;
361384

362385
// - Posting Notification
@@ -380,4 +403,29 @@ typedef NS_ENUM(NSUInteger, ONE_S_LOG_LEVEL) {
380403
+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent;
381404
+ (UNMutableNotificationContent*)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent;
382405

406+
// Email methods
407+
408+
// Typedefs defining completion blocks for email & simultaneous HTTP requests
409+
typedef void (^OSEmailFailureBlock)(NSError* error);
410+
typedef void (^OSEmailSuccessBlock)();
411+
412+
// Allows you to set the email for this user.
413+
// Email Auth Token is a (recommended) optional parameter that should *NOT* be generated on the client.
414+
// For security purposes, the emailAuthToken should be generated by your backend server.
415+
// If you do not have a backend server for your application, use the version of thge setEmail: method without an emailAuthToken parameter.
416+
+ (void)setEmail:(NSString * _Nonnull)email withEmailAuthHashToken:(NSString * _Nullable)hashToken withSuccess:(OSEmailSuccessBlock _Nullable)successBlock withFailure:(OSEmailFailureBlock _Nullable)failureBlock;
417+
418+
// Sets email without an authentication token
419+
+ (void)setEmail:(NSString * _Nonnull)email withSuccess:(OSEmailSuccessBlock _Nullable)successBlock withFailure:(OSEmailFailureBlock _Nullable)failureBlock;
420+
421+
// Logs the device out of the current email.
422+
+ (void)logoutEmailWithSuccess:(OSEmailSuccessBlock _Nullable)successBlock withFailure:(OSEmailFailureBlock _Nullable)failureBlock;
423+
424+
//convenience - no completion blocks
425+
+ (void)logoutEmail;
426+
+ (void)setEmail:(NSString * _Nonnull)email;
427+
+ (void)setEmail:(NSString * _Nonnull)email withEmailAuthHashToken:(NSString * _Nullable)hashToken;
428+
383429
@end
430+
431+
#pragma clang diagnostic pop

OneSignalExample/Assets/OneSignal/Platforms/iOS/OneSignalUnityRuntime.m

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ static void injectSelector(Class newClass, SEL newSel, Class addToClass, SEL mak
8888

8989
@interface OSUnityPermissionAndSubscriptionObserver : NSObject<OSPermissionObserver, OSSubscriptionObserver>
9090
- (void)onOSPermissionChanged:(OSPermissionStateChanges*)stateChanges;
91-
- (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges*)stateChanges;
91+
- (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges*)stateChanges;
92+
- (void)onOSEmailSubscriptionChanged:(OSEmailSubscriptionStateChanges *)stateChanges;
9293
@end
9394

9495
@implementation OSUnityPermissionAndSubscriptionObserver
@@ -98,6 +99,10 @@ - (void)onOSPermissionChanged:(OSPermissionStateChanges*)stateChanges {
9899

99100
- (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges*)stateChanges {
100101
UnitySendMessage(unityListener, "onOSSubscriptionChanged", dictionaryToJsonChar([stateChanges toDictionary]));
102+
}
103+
104+
- (void)onOSEmailSubscriptionStateChanged:(OSEmailSubscriptionStateChanges *)stateChanges {
105+
UnitySendMessage(unityListener, "onOSEmailSubscriptionStateChanged", dictionaryToJsonChar([stateChanges toDictionary]));
101106
}
102107
@end
103108

@@ -273,6 +278,17 @@ void _addSubscriptionObserver() {
273278

274279
void _removeSubscriptionObserver() {
275280
[OneSignal removeSubscriptionObserver:osUnityObserver];
281+
}
282+
283+
void _addEmailSubscriptionObserver() {
284+
if (!osUnityObserver)
285+
osUnityObserver = [OSUnityPermissionAndSubscriptionObserver alloc];
286+
287+
[OneSignal addEmailSubscriptionObserver:osUnityObserver];
288+
}
289+
290+
void _removeEmailSubscriptionObserver() {
291+
[OneSignal removeEmailSubscriptionObserver:osUnityObserver];
276292
}
277293

278294
char* _getPermissionSubscriptionState() {
@@ -287,6 +303,32 @@ void _promptForPushNotificationsWithUserResponse() {
287303

288304
void _setOneSignalLogLevel(int logLevel, int visualLogLevel) {
289305
[OneSignal setLogLevel:logLevel visualLevel: visualLogLevel];
306+
}
307+
308+
// email
309+
310+
void _setUnauthenticatedEmail(const char*email) {
311+
[OneSignal setEmail:CreateNSString(email) withSuccess:^{
312+
UnitySendMessage(unityListener, "onSetEmailSuccess", dictionaryToJsonChar(@{@"status" : @"success"}));
313+
} withFailure:^(NSError *error) {
314+
UnitySendMessage(unityListener, "onSetEmailFailure", [[OneSignal parseNSErrorAsJsonString:error] UTF8String]);
315+
}];
316+
}
317+
318+
void _setEmail(const char *email, const char *emailAuthCode) {
319+
[OneSignal setEmail:CreateNSString(email) withEmailAuthHashToken:CreateNSString(emailAuthCode) withSuccess:^{
320+
UnitySendMessage(unityListener, "onSetEmailSuccess", dictionaryToJsonChar(@{@"status" : @"success"}));
321+
} withFailure:^(NSError *error) {
322+
UnitySendMessage(unityListener, "onSetEmailFailure", [[OneSignal parseNSErrorAsJsonString:error] UTF8String]);
323+
}];
324+
}
325+
326+
void _logoutEmail() {
327+
[OneSignal logoutEmailWithSuccess:^{
328+
UnitySendMessage(unityListener, "onLogoutEmailSuccess", dictionaryToJsonChar(@{@"status" : @"success"}));
329+
} withFailure:^(NSError *error) {
330+
UnitySendMessage(unityListener, "onLogoutEmailFailure", [[OneSignal parseNSErrorAsJsonString:error] UTF8String]);
331+
}];
290332
}
291333

292334
@end
2.08 MB
Binary file not shown.

0 commit comments

Comments
 (0)