Skip to content

Commit 93ebe6f

Browse files
authored
FIAM Programmatic triggers (#3081)
* Add card scene to storyboard, use IBDesignable rounded corners view * Use IBdesignable rounded corners view for modal message * Add card message type * Parse card message type, add new fields for secondary actions and landscape URLs to view model classes * Display a really basic card message * Naive landscape image loading (needs error handling) * Quick bug fix * Wire up Display to show cards * Wire up Display to show cards * Fix tablet width * Pick right image for orientation * Remove placeholder image sizing constraints at build time * Add more test functionality * Better image sizes * Size message image out * Switch to body text view rather than body label * Make the body text view scrollable. Set correct text color on button. * Hook up buttons and text color * Include action URL in messageClicked callback * Fix action URL * Update pod specs * Update message clicked delegate to pass an action object, not just the actionURL * Change podspec versions back, hook up background color * Don't animate scroll to top on scroll view * Fix text scrolling bug * Fix portrait and landscape fetching code. Fix background color bug * Flesh out FIRIAMMessageContentDataWithImageURLTests * Fix up FIRIAMFetchFlowTests * Fix up FIRIAMMessageClientCacheTests * Fix up FIRIAMMessageDisplayForTesting * Fix fetching in FIRIAMMessageContentDataWithImageURL * Tests for message parsing * Fix up view controllers for banner, modal, image only. Add a view controller for testing card * Add required vertical compression resistance for primary and secondary action button * Add UI tests for card view controller * Add back deprecated messageClicked: method, call it if the newer method isn't implemented. Make all display delegate methods optional. * Run scripts/styles.sh * Add FIRIAMDisplayExecutor logic to display an in-app message programmatically. * Add a public method on FIRInAppMessaging that triggers a message to be shown via the display executor * Add button to test app that programmatically triggers a message * Add unit tests for display executor programmatic trigger flow * Documentation cleanup * Fix style in FIRIAMMessageContentDataWithImageURLTests.m * Add missing copyright notices * Bump versions of both FIAM SDKS * Remove default.profraw * Address some logging punctuation nits. Cancel landscape image load if portrait image load fails. * Add missing error flow in image fetch. A few comment nits. * Shorten up init method for CardDisplayMessage * Documentation updates * Deintegrate cocoa pods * Include landscape image data in test image load class * Fix Swift naming for InAppMessagingAction in UItests * Remove card message initializer from public API, place into a private header * Mark some properties on the card object as readonly that should've been already, Find a way to initialize a card message in the UI tests. * Bump dependency on InAppMessaging given changes * Bump versions in podspecs for both SDKs * Make all view model properties for message subclasses readonly * Revert changes to other message subclasses * Make card view model properties readonly * Run styles.sh * Run styles.sh, address some comments about logging * Reuse analytic trigger method to show programmatic messages. Fix issue with overriding accessibility of card message params
1 parent 8a6c1b6 commit 93ebe6f

File tree

6 files changed

+75
-22
lines changed

6 files changed

+75
-22
lines changed

Firebase/InAppMessaging/FIRInAppMessaging.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,9 @@ - (void)setMessageDisplayComponent:(id<FIRInAppMessagingDisplay>)messageDisplayC
141141
messageDisplayComponent;
142142
}
143143

144+
- (void)triggerEvent:(NSString *)eventName {
145+
[[FIRIAMRuntimeManager getSDKRuntimeInstance].displayExecutor
146+
checkAndDisplayNextContextualMessageForAnalyticsEvent:eventName];
147+
}
148+
144149
@end

Firebase/InAppMessaging/Public/FIRInAppMessaging.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ NS_SWIFT_NAME(InAppMessaging)
7777
*/
7878
@property(nonatomic) id<FIRInAppMessagingDisplay> messageDisplayComponent;
7979

80+
/**
81+
* Directly requests an in-app message with the given trigger to be shown.
82+
*/
83+
- (void)triggerEvent:(NSString *)eventName;
84+
8085
/**
8186
* This delegate should be set on the app side to receive message lifecycle events in app runtime.
8287
*/

Firebase/InAppMessaging/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ - (instancetype)initWithMessageID:(NSString *)messageID
3838

3939
@implementation FIRInAppMessagingCardDisplay
4040

41+
- (void)setBody:(NSString *_Nullable)body {
42+
_body = body;
43+
}
44+
45+
- (void)setLandscapeImageData:(FIRInAppMessagingImageData *_Nullable)landscapeImageData {
46+
_landscapeImageData = landscapeImageData;
47+
}
48+
49+
- (void)setSecondaryActionButton:(FIRInAppMessagingActionButton *_Nullable)secondaryActionButton {
50+
_secondaryActionButton = secondaryActionButton;
51+
}
52+
53+
- (void)setSecondaryActionURL:(NSURL *_Nullable)secondaryActionURL {
54+
_secondaryActionURL = secondaryActionURL;
55+
}
56+
4157
- (instancetype)initWithMessageID:(NSString *)messageID
4258
campaignName:(NSString *)campaignName
4359
renderAsTestMessage:(BOOL)renderAsTestMessage

Firebase/InAppMessaging/RenderingObjects/FIRInAppMessagingRenderingPrivate.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ NS_ASSUME_NONNULL_BEGIN
1818

1919
@interface FIRInAppMessagingCardDisplay (Private)
2020

21-
@property(nonatomic, nullable, copy, readwrite) NSString *body;
22-
@property(nonatomic, nullable, copy, readwrite) FIRInAppMessagingImageData *landscapeImageData;
23-
@property(nonatomic, nullable, readwrite) FIRInAppMessagingActionButton *secondaryActionButton;
24-
@property(nonatomic, nullable, readwrite) NSURL *secondaryActionURL;
21+
- (void)setBody:(NSString *_Nullable)body;
22+
- (void)setLandscapeImageData:(FIRInAppMessagingImageData *_Nullable)landscapeImageData;
23+
- (void)setSecondaryActionButton:(FIRInAppMessagingActionButton *_Nullable)secondaryActionButton;
24+
- (void)setSecondaryActionURL:(NSURL *_Nullable)secondaryActionURL;
2525

2626
- (instancetype)initWithMessageID:(NSString *)messageID
2727
campaignName:(NSString *)campaignName

InAppMessaging/Example/App/InAppMessaging-Example-iOS/AutoDisplayFlowViewController.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ @interface AutoDisplayFlowViewController ()
4242
@property(weak, nonatomic) IBOutlet UITextField *autoDisplayIntervalText;
4343
@property(weak, nonatomic) IBOutlet UITextField *autoFetchIntervalText;
4444
@property(weak, nonatomic) IBOutlet UITextField *eventNameText;
45+
@property(weak, nonatomic) IBOutlet UITextField *programmaticTriggerNameText;
4546
@property(nonatomic) FIRIAMRuntimeManager *sdkRuntime;
4647
@property(weak, nonatomic) IBOutlet UIButton *disableEnableSDKBtn;
4748
@property(weak, nonatomic) IBOutlet UIButton *changeDataCollectionBtn;
@@ -77,6 +78,12 @@ - (IBAction)triggerAnalyticEventTapped:(id)sender {
7778
[FIRAnalytics logEventWithName:self.eventNameText.text parameters:@{}];
7879
}
7980

81+
- (IBAction)triggerProgrammaticallyTapped:(id)sender {
82+
NSLog(@"Trigger event %@ programmatically", self.eventNameText.text);
83+
84+
[[FIRInAppMessaging inAppMessaging] triggerEvent:self.programmaticTriggerNameText.text];
85+
}
86+
8087
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
8188
UITouch *touch = [touches anyObject];
8289
if (![touch.view isMemberOfClass:[UITextField class]]) {

InAppMessaging/Example/App/InAppMessaging-Example-iOS/Base.lproj/Main.storyboard

Lines changed: 38 additions & 18 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="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ebq-cZ-Ywc">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ebq-cZ-Ywc">
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="14088"/>
9-
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
10-
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
119
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1210
</dependencies>
1311
<scenes>
@@ -24,13 +22,13 @@
2422
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
2523
<subviews>
2624
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Nbf-aL-D4Q">
27-
<rect key="frame" x="0.0" y="320.5" width="375" height="287.5"/>
25+
<rect key="frame" x="0.0" y="370.5" width="375" height="237.5"/>
2826
<connections>
2927
<segue destination="PsL-F0-NPD" kind="embed" identifier="message-table-segue" id="Ruf-dB-QUH"/>
3028
</connections>
3129
</containerView>
3230
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Messages To Display" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2lf-ei-PaY">
33-
<rect key="frame" x="0.0" y="292" width="375" height="20.5"/>
31+
<rect key="frame" x="0.0" y="342" width="375" height="20.5"/>
3432
<fontDescription key="fontDescription" type="system" pointSize="17"/>
3533
<nil key="textColor"/>
3634
<nil key="highlightedColor"/>
@@ -49,14 +47,6 @@
4947
<constraint firstAttribute="height" constant="2" id="qn7-el-C36"/>
5048
</constraints>
5149
</view>
52-
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TWl-ic-ODQ">
53-
<rect key="frame" x="14" y="247" width="138" height="30"/>
54-
<fontDescription key="fontDescription" type="system" pointSize="13"/>
55-
<state key="normal" title="Trigger analytics event"/>
56-
<connections>
57-
<action selector="triggerAnalyticEventTapped:" destination="pEd-Cp-eSk" eventType="touchUpInside" id="IEI-K3-ihJ"/>
58-
</connections>
59-
</button>
6050
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3kb-Du-qxH" userLabel="Top Half View">
6151
<rect key="frame" x="0.0" y="40" width="375" height="190"/>
6252
<subviews>
@@ -97,7 +87,7 @@
9787
<nil key="highlightedColor"/>
9888
</label>
9989
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZUt-bH-BSp">
100-
<rect key="frame" x="10" y="90" width="355" height="28"/>
90+
<rect key="frame" x="10" y="89.5" width="355" height="28"/>
10191
<fontDescription key="fontDescription" type="system" pointSize="13"/>
10292
<state key="normal" title="Apply Displa/Fetch Frequency Change"/>
10393
<connections>
@@ -171,19 +161,44 @@
171161
<constraint firstItem="Erp-ss-RqT" firstAttribute="leading" secondItem="3kb-Du-qxH" secondAttribute="leading" constant="10" id="yst-Bp-eIN"/>
172162
</constraints>
173163
</view>
164+
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TWl-ic-ODQ">
165+
<rect key="frame" x="14" y="247" width="138" height="30"/>
166+
<fontDescription key="fontDescription" type="system" pointSize="13"/>
167+
<state key="normal" title="Trigger analytics event"/>
168+
<connections>
169+
<action selector="triggerAnalyticEventTapped:" destination="pEd-Cp-eSk" eventType="touchUpInside" id="IEI-K3-ihJ"/>
170+
</connections>
171+
</button>
174172
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="test_event" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="M0T-f0-qfn">
175173
<rect key="frame" x="182" y="247" width="173" height="30"/>
176174
<nil key="textColor"/>
177175
<fontDescription key="fontDescription" type="system" pointSize="13"/>
178176
<textInputTraits key="textInputTraits"/>
179177
</textField>
178+
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PA9-qD-Z5X">
179+
<rect key="frame" x="14" y="287" width="152" height="30"/>
180+
<fontDescription key="fontDescription" type="system" pointSize="13"/>
181+
<state key="normal" title="Trigger programmatically"/>
182+
<connections>
183+
<action selector="triggerAnalyticEventTapped:" destination="pEd-Cp-eSk" eventType="touchUpInside" id="74T-tl-wdH"/>
184+
<action selector="triggerProgrammaticallyTapped:" destination="pEd-Cp-eSk" eventType="touchUpInside" id="jPY-TA-aJN"/>
185+
</connections>
186+
</button>
187+
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="test_trigger" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Qzz-aW-vHr">
188+
<rect key="frame" x="196" y="287" width="159" height="30"/>
189+
<nil key="textColor"/>
190+
<fontDescription key="fontDescription" type="system" pointSize="13"/>
191+
<textInputTraits key="textInputTraits"/>
192+
</textField>
180193
</subviews>
181194
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
182195
<constraints>
183196
<constraint firstItem="2lf-ei-PaY" firstAttribute="leading" secondItem="27y-ro-ncL" secondAttribute="leading" id="0g2-Zm-MAm"/>
184197
<constraint firstItem="FB6-Ej-jmi" firstAttribute="top" secondItem="3kb-Du-qxH" secondAttribute="bottom" constant="5" id="19L-XJ-rNE"/>
185198
<constraint firstAttribute="trailing" secondItem="2lf-ei-PaY" secondAttribute="trailing" id="2sG-IE-v1C"/>
199+
<constraint firstItem="PA9-qD-Z5X" firstAttribute="top" secondItem="TWl-ic-ODQ" secondAttribute="bottom" constant="10" id="3d8-nF-Yf8"/>
186200
<constraint firstAttribute="trailing" secondItem="Nbf-aL-D4Q" secondAttribute="trailing" id="3nJ-jP-296"/>
201+
<constraint firstAttribute="trailing" secondItem="Qzz-aW-vHr" secondAttribute="trailing" constant="20" id="56F-2K-y7M"/>
187202
<constraint firstItem="M0T-f0-qfn" firstAttribute="bottom" secondItem="TWl-ic-ODQ" secondAttribute="bottom" id="68L-bx-rfi"/>
188203
<constraint firstItem="QzN-45-brV" firstAttribute="leading" secondItem="Nbf-aL-D4Q" secondAttribute="leading" id="68c-cK-w0l"/>
189204
<constraint firstItem="QzN-45-brV" firstAttribute="top" secondItem="Nbf-aL-D4Q" secondAttribute="bottom" constant="10" id="CCo-W9-Nwb"/>
@@ -195,13 +210,17 @@
195210
<constraint firstItem="3kb-Du-qxH" firstAttribute="centerX" secondItem="27y-ro-ncL" secondAttribute="centerX" id="Um3-SX-kub"/>
196211
<constraint firstItem="TWl-ic-ODQ" firstAttribute="top" secondItem="FB6-Ej-jmi" secondAttribute="bottom" constant="10" id="YYp-3Y-QXH"/>
197212
<constraint firstItem="FB6-Ej-jmi" firstAttribute="width" secondItem="27y-ro-ncL" secondAttribute="width" id="aGR-qE-35f"/>
213+
<constraint firstItem="Qzz-aW-vHr" firstAttribute="top" secondItem="PA9-qD-Z5X" secondAttribute="top" id="btv-LV-CyU"/>
198214
<constraint firstAttribute="trailing" secondItem="M0T-f0-qfn" secondAttribute="trailing" constant="20" id="cHW-QJ-D5z"/>
215+
<constraint firstItem="PA9-qD-Z5X" firstAttribute="leading" secondItem="TWl-ic-ODQ" secondAttribute="leading" id="f4g-bo-YSa"/>
216+
<constraint firstItem="Qzz-aW-vHr" firstAttribute="leading" secondItem="PA9-qD-Z5X" secondAttribute="trailing" constant="30" id="gAn-fn-Xoj"/>
199217
<constraint firstItem="M0T-f0-qfn" firstAttribute="top" secondItem="TWl-ic-ODQ" secondAttribute="top" id="hHq-ch-Cw9"/>
200218
<constraint firstItem="fcu-KV-0co" firstAttribute="top" secondItem="Nbf-aL-D4Q" secondAttribute="bottom" constant="10" id="iF9-YE-7Bh"/>
201219
<constraint firstItem="M0T-f0-qfn" firstAttribute="leading" secondItem="TWl-ic-ODQ" secondAttribute="trailing" constant="30" id="oK4-kd-ngD"/>
202220
<constraint firstItem="QzN-45-brV" firstAttribute="trailing" secondItem="Nbf-aL-D4Q" secondAttribute="trailing" id="ore-FG-3Z5"/>
221+
<constraint firstItem="Qzz-aW-vHr" firstAttribute="bottom" secondItem="PA9-qD-Z5X" secondAttribute="bottom" id="qZw-4h-RVV"/>
203222
<constraint firstItem="Nbf-aL-D4Q" firstAttribute="leading" secondItem="27y-ro-ncL" secondAttribute="leading" id="rHM-kR-Ebu"/>
204-
<constraint firstItem="2lf-ei-PaY" firstAttribute="top" secondItem="FB6-Ej-jmi" secondAttribute="bottom" constant="55" id="xhl-Hf-WDB"/>
223+
<constraint firstItem="2lf-ei-PaY" firstAttribute="top" secondItem="FB6-Ej-jmi" secondAttribute="bottom" constant="105" id="xhl-Hf-WDB"/>
205224
<constraint firstItem="TWl-ic-ODQ" firstAttribute="leading" secondItem="27y-ro-ncL" secondAttribute="leading" constant="14" id="zTT-qI-tld"/>
206225
</constraints>
207226
</view>
@@ -212,11 +231,12 @@
212231
<outlet property="changeDataCollectionBtn" destination="KCx-gs-cUi" id="MWc-Kk-IWX"/>
213232
<outlet property="disableEnableSDKBtn" destination="nUy-hl-LzV" id="Sm9-9g-Uc5"/>
214233
<outlet property="eventNameText" destination="M0T-f0-qfn" id="PJw-AR-bWa"/>
234+
<outlet property="programmaticTriggerNameText" destination="Qzz-aW-vHr" id="FaS-3C-yYa"/>
215235
</connections>
216236
</viewController>
217237
<placeholder placeholderIdentifier="IBFirstResponder" id="1YW-qT-fHJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
218238
</objects>
219-
<point key="canvasLocation" x="339.13043478260875" y="1420.108695652174"/>
239+
<point key="canvasLocation" x="338.39999999999998" y="1419.9400299850076"/>
220240
</scene>
221241
<!--Viewing Logs-->
222242
<scene sceneID="1fw-sb-9xA">
@@ -327,7 +347,7 @@
327347
<objects>
328348
<tableViewController id="PsL-F0-NPD" customClass="AutoDisplayMesagesTableVC" sceneMemberID="viewController">
329349
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="qfr-gm-4ZH">
330-
<rect key="frame" x="0.0" y="0.0" width="375" height="287.5"/>
350+
<rect key="frame" x="0.0" y="0.0" width="375" height="237.5"/>
331351
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
332352
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
333353
<prototypes>

0 commit comments

Comments
 (0)