Skip to content

Commit 8bab228

Browse files
authored
Setting External ID's (#453)
* Setting External ID's • Adds setExternalUserId() and removeExternalUserId() as public functions to the OneSignal SDK • Adds tests to verify the request is working correctly and the API request is correctly formatted • Adds a test to verify that removeExternalUserId() works the same except it sends an empty string (which is what the API wants) * Add External ID To Demo Project • We have a (very) simple dev project for the SDK. This commit adds a text field and button to set an arbitrary external User ID, as well as a button to remove the ID * De-Duplication • Persists the most recently set external user ID so that if a developer sets it every time a user opens the app (setting the same ID every time), the SDK does not send unnecessary duplicate API requests • Adds tests to verify that unnecessary API requests don't occur in this scenario * Email Player External User ID's • I had implemented external user ID for Push players but it turns out we want to support it for Email user records as well. • This commit adds external_user_id to email user records, in a similar matter to how we execute simultaneous requests for sendTags and so on. • Added an integration test in EmailTests to make sure external ID methods work correctly, duplicate requests don't generate unnecessary API traffic, etc. • Changes the OneSignalClientOverrider so that it maintains an array of executed OneSignalRequest (API request) objects. This makes testing more flexible
1 parent 1c8a853 commit 8bab228

File tree

14 files changed

+311
-23
lines changed

14 files changed

+311
-23
lines changed

iOS_SDK/OneSignalDevApp/OneSignalDevApp/Base.lproj/Main.storyboard

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
33
<device id="retina4_7" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
66
<dependencies>
77
<deployment identifier="iOS"/>
8-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
9-
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
10-
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
119
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1210
</dependencies>
1311
<scenes>
@@ -24,7 +22,7 @@
2422
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
2523
<subviews>
2624
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="H3K-GA-smE">
27-
<rect key="frame" x="146.5" y="270" width="82" height="30"/>
25+
<rect key="frame" x="146.5" y="270.5" width="82" height="30"/>
2826
<constraints>
2927
<constraint firstAttribute="width" constant="82" id="5Mr-b6-M73"/>
3028
<constraint firstAttribute="height" constant="30" id="8ZT-dR-9mp"/>
@@ -35,7 +33,7 @@
3533
</connections>
3634
</button>
3735
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="E-Mail Address" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ebC-zs-TnD">
38-
<rect key="frame" x="70" y="318" width="235" height="30"/>
36+
<rect key="frame" x="70" y="318.5" width="235" height="30"/>
3937
<constraints>
4038
<constraint firstAttribute="height" constant="30" id="zBY-vy-YNY"/>
4139
</constraints>
@@ -44,7 +42,7 @@
4442
<textInputTraits key="textInputTraits"/>
4543
</textField>
4644
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Kp7-Oh-BQ1">
47-
<rect key="frame" x="95" y="356" width="185" height="30"/>
45+
<rect key="frame" x="95" y="356.5" width="185" height="30"/>
4846
<constraints>
4947
<constraint firstAttribute="height" constant="30" id="GNh-1z-CX0"/>
5048
<constraint firstAttribute="width" constant="185" id="rqq-aH-vLk"/>
@@ -55,7 +53,7 @@
5553
</connections>
5654
</button>
5755
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0cV-KP-U0v">
58-
<rect key="frame" x="109" y="394" width="156" height="30"/>
56+
<rect key="frame" x="109.5" y="394.5" width="156" height="30"/>
5957
<constraints>
6058
<constraint firstAttribute="height" constant="30" id="Q6W-wH-cP9"/>
6159
<constraint firstAttribute="width" constant="156" id="dya-kL-Z4L"/>
@@ -66,14 +64,14 @@
6664
</connections>
6765
</button>
6866
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="k3C-y9-O4O">
69-
<rect key="frame" x="313" y="323" width="20" height="20"/>
67+
<rect key="frame" x="313" y="323.5" width="20" height="20"/>
7068
<constraints>
7169
<constraint firstAttribute="width" constant="20" id="ITB-dD-BVh"/>
7270
<constraint firstAttribute="height" constant="20" id="bBI-BW-dmM"/>
7371
</constraints>
7472
</activityIndicatorView>
7573
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" translatesAutoresizingMaskIntoConstraints="NO" id="05S-ud-V2e">
76-
<rect key="frame" x="163" y="442" width="179" height="29"/>
74+
<rect key="frame" x="163" y="442.5" width="179" height="29"/>
7775
<constraints>
7876
<constraint firstAttribute="height" constant="28" id="nSO-fn-AxS"/>
7977
</constraints>
@@ -86,14 +84,62 @@
8684
</connections>
8785
</segmentedControl>
8886
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Consent Status:" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j3e-42-uww">
89-
<rect key="frame" x="0.0" y="445" width="155" height="21"/>
87+
<rect key="frame" x="28" y="446" width="127" height="21"/>
9088
<constraints>
89+
<constraint firstAttribute="width" constant="127" id="73d-Xe-Gy6"/>
9190
<constraint firstAttribute="height" constant="21" id="sCD-KJ-VyV"/>
9291
</constraints>
9392
<fontDescription key="fontDescription" type="system" pointSize="17"/>
9493
<nil key="textColor"/>
9594
<nil key="highlightedColor"/>
9695
</label>
96+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fLa-FX-A3b">
97+
<rect key="frame" x="28" y="492" width="314" height="39"/>
98+
<subviews>
99+
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="External ID" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="AFJ-eF-rWt">
100+
<rect key="frame" x="8" y="4.5" width="176" height="30"/>
101+
<constraints>
102+
<constraint firstAttribute="height" constant="30" id="ALb-mU-3Ut"/>
103+
</constraints>
104+
<nil key="textColor"/>
105+
<fontDescription key="fontDescription" type="system" pointSize="14"/>
106+
<textInputTraits key="textInputTraits"/>
107+
</textField>
108+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Dhr-UW-GHI">
109+
<rect key="frame" x="192" y="4.5" width="114" height="30"/>
110+
<constraints>
111+
<constraint firstAttribute="width" constant="114" id="XjX-wR-b1K"/>
112+
<constraint firstAttribute="height" constant="30" id="zE1-wG-LaA"/>
113+
</constraints>
114+
<state key="normal" title="Set External ID"/>
115+
<connections>
116+
<action selector="setExternalIdButtonPressed:" destination="BYZ-38-t0r" eventType="touchUpInside" id="uaT-ID-84D"/>
117+
</connections>
118+
</button>
119+
</subviews>
120+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
121+
<constraints>
122+
<constraint firstAttribute="height" constant="39" id="3TC-zN-6cA"/>
123+
<constraint firstItem="Dhr-UW-GHI" firstAttribute="leading" secondItem="AFJ-eF-rWt" secondAttribute="trailing" constant="8" id="3ho-0l-xxm"/>
124+
<constraint firstItem="AFJ-eF-rWt" firstAttribute="leading" secondItem="fLa-FX-A3b" secondAttribute="leading" constant="8" id="9tD-VA-W8w"/>
125+
<constraint firstAttribute="trailing" secondItem="Dhr-UW-GHI" secondAttribute="trailing" constant="8" id="ILe-2x-elS"/>
126+
<constraint firstItem="AFJ-eF-rWt" firstAttribute="centerY" secondItem="fLa-FX-A3b" secondAttribute="centerY" id="VdF-tj-8tq"/>
127+
<constraint firstItem="Dhr-UW-GHI" firstAttribute="centerY" secondItem="fLa-FX-A3b" secondAttribute="centerY" id="liP-GL-j67"/>
128+
</constraints>
129+
</view>
130+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NQk-bd-dOf">
131+
<rect key="frame" x="96" y="539" width="178" height="30"/>
132+
<constraints>
133+
<constraint firstAttribute="width" constant="178" id="WCX-us-pnp"/>
134+
<constraint firstAttribute="height" constant="30" id="ppE-FB-SnD"/>
135+
</constraints>
136+
<state key="normal" title="Remove External ID">
137+
<color key="titleColor" red="0.66666668650000005" green="0.1872406381" blue="0.18939384749999999" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
138+
</state>
139+
<connections>
140+
<action selector="removeExternalIdButtonPressed:" destination="BYZ-38-t0r" eventType="touchUpInside" id="njM-2D-osL"/>
141+
</connections>
142+
</button>
97143
</subviews>
98144
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
99145
<constraints>
@@ -105,20 +151,25 @@
105151
<constraint firstItem="Kp7-Oh-BQ1" firstAttribute="centerX" secondItem="H3K-GA-smE" secondAttribute="centerX" id="BET-RV-SSL"/>
106152
<constraint firstItem="05S-ud-V2e" firstAttribute="top" secondItem="0cV-KP-U0v" secondAttribute="bottom" constant="18" id="Doq-ct-llI"/>
107153
<constraint firstItem="k3C-y9-O4O" firstAttribute="leading" secondItem="ebC-zs-TnD" secondAttribute="trailing" constant="8" id="EHn-dg-Gsx"/>
154+
<constraint firstItem="fLa-FX-A3b" firstAttribute="trailing" secondItem="05S-ud-V2e" secondAttribute="trailing" id="K6p-Xd-c2S"/>
108155
<constraint firstAttribute="trailingMargin" secondItem="ebC-zs-TnD" secondAttribute="trailing" constant="54" id="NSB-la-nXF"/>
156+
<constraint firstItem="NQk-bd-dOf" firstAttribute="top" secondItem="fLa-FX-A3b" secondAttribute="bottom" constant="8" id="THA-kk-eHd"/>
109157
<constraint firstItem="k3C-y9-O4O" firstAttribute="centerY" secondItem="ebC-zs-TnD" secondAttribute="centerY" id="WyY-eM-1NM"/>
110-
<constraint firstItem="j3e-42-uww" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="XLa-mE-TYD"/>
111158
<constraint firstItem="ebC-zs-TnD" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="Yug-OZ-HIr"/>
112159
<constraint firstAttribute="trailing" secondItem="05S-ud-V2e" secondAttribute="trailing" constant="33" id="en0-C1-hCf"/>
160+
<constraint firstItem="fLa-FX-A3b" firstAttribute="top" secondItem="05S-ud-V2e" secondAttribute="bottom" constant="21.5" id="gKz-dl-7dd"/>
161+
<constraint firstItem="fLa-FX-A3b" firstAttribute="leading" secondItem="j3e-42-uww" secondAttribute="leading" id="gWj-eK-0fo"/>
113162
<constraint firstItem="0cV-KP-U0v" firstAttribute="centerX" secondItem="Kp7-Oh-BQ1" secondAttribute="centerX" id="rAQ-XU-eNr"/>
114163
<constraint firstItem="j3e-42-uww" firstAttribute="centerY" secondItem="05S-ud-V2e" secondAttribute="centerY" id="thm-36-AAy"/>
115164
<constraint firstItem="ebC-zs-TnD" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="54" id="tp6-Bq-3wr"/>
165+
<constraint firstItem="NQk-bd-dOf" firstAttribute="centerX" secondItem="fLa-FX-A3b" secondAttribute="centerX" id="uZb-Vr-ZFa"/>
116166
<constraint firstItem="0cV-KP-U0v" firstAttribute="top" secondItem="Kp7-Oh-BQ1" secondAttribute="bottom" constant="8" id="wyD-rc-wek"/>
117167
</constraints>
118168
</view>
119169
<connections>
120170
<outlet property="activityIndicatorView" destination="k3C-y9-O4O" id="cIe-9k-ZJW"/>
121171
<outlet property="consentSegmentedControl" destination="05S-ud-V2e" id="9HS-Rj-OmM"/>
172+
<outlet property="externalIdTextField" destination="AFJ-eF-rWt" id="iMO-PW-IDt"/>
122173
<outlet property="textField" destination="ebC-zs-TnD" id="Qds-Dp-amQ"/>
123174
</connections>
124175
</viewController>

iOS_SDK/OneSignalDevApp/OneSignalDevApp/ViewController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
#import <UIKit/UIKit.h>
3232

33-
@interface ViewController : UIViewController
33+
@interface ViewController : UIViewController <UITextFieldDelegate>
3434

3535

3636
@end

iOS_SDK/OneSignalDevApp/OneSignalDevApp/ViewController.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ @interface ViewController ()
3636
@property (weak, nonatomic) IBOutlet UITextField *textField;
3737
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicatorView;
3838
@property (weak, nonatomic) IBOutlet UISegmentedControl *consentSegmentedControl;
39+
@property (weak, nonatomic) IBOutlet UITextField *externalIdTextField;
3940

4041
@end
4142

@@ -48,6 +49,9 @@ - (void)viewDidLoad {
4849
self.activityIndicatorView.hidden = true;
4950

5051
self.consentSegmentedControl.selectedSegmentIndex = (NSInteger)![OneSignal requiresUserPrivacyConsent];
52+
53+
self.textField.delegate = self;
54+
self.externalIdTextField.delegate = self;
5155
}
5256

5357
- (void)changeAnimationState:(BOOL)animating {
@@ -129,5 +133,18 @@ - (IBAction)consentSegmentedControlValueChanged:(UISegmentedControl *)sender {
129133
[OneSignal consentGranted:(bool)sender.selectedSegmentIndex];
130134
}
131135

136+
- (IBAction)setExternalIdButtonPressed:(UIButton *)sender {
137+
[OneSignal setExternalUserId:self.externalIdTextField.text];
138+
}
139+
140+
- (IBAction)removeExternalIdButtonPressed:(UIButton *)sender {
141+
[OneSignal removeExternalUserId];
142+
}
143+
144+
#pragma mark UITextFieldDelegate Methods
145+
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
146+
[textField resignFirstResponder];
147+
return false;
148+
}
132149

133150
@end

iOS_SDK/OneSignalSDK/Source/OneSignal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ typedef void (^OSEmailSuccessBlock)();
457457
+ (void)setEmail:(NSString * _Nonnull)email;
458458
+ (void)setEmail:(NSString * _Nonnull)email withEmailAuthHashToken:(NSString * _Nullable)hashToken;
459459

460+
+ (void)setExternalUserId:(NSString * _Nonnull)externalId;
461+
+ (void)removeExternalUserId;
462+
460463
@end
461464

462465
#pragma clang diagnostic pop

0 commit comments

Comments
 (0)