1 |
efrain |
1 |
/*
|
|
|
2 |
* Copyright 2018 Google
|
|
|
3 |
*
|
|
|
4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
5 |
* you may not use this file except in compliance with the License.
|
|
|
6 |
* You may obtain a copy of the License at
|
|
|
7 |
*
|
|
|
8 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
9 |
*
|
|
|
10 |
* Unless required by applicable law or agreed to in writing, software
|
|
|
11 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
13 |
* See the License for the specific language governing permissions and
|
|
|
14 |
* limitations under the License.
|
|
|
15 |
*/
|
|
|
16 |
|
|
|
17 |
#import <TargetConditionals.h>
|
|
|
18 |
#if TARGET_OS_IOS
|
|
|
19 |
|
|
|
20 |
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
|
|
|
21 |
|
|
|
22 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/Banner/FIRIAMBannerViewController.h"
|
|
|
23 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/Card/FIRIAMCardViewController.h"
|
|
|
24 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/FIRCore+InAppMessagingDisplay.h"
|
|
|
25 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.h"
|
|
|
26 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMRenderingWindowHelper.h"
|
|
|
27 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/ImageOnly/FIRIAMImageOnlyViewController.h"
|
|
|
28 |
#import "FirebaseInAppMessaging/Sources/DefaultUI/Modal/FIRIAMModalViewController.h"
|
|
|
29 |
#import "FirebaseInAppMessaging/Sources/Private/Util/FIRIAMTimeFetcher.h"
|
|
|
30 |
#import "FirebaseInAppMessaging/Sources/Public/FirebaseInAppMessaging/FIRInAppMessaging.h"
|
|
|
31 |
|
|
|
32 |
@implementation FIRIAMDefaultDisplayImpl
|
|
|
33 |
|
|
|
34 |
+ (void)load {
|
|
|
35 |
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
36 |
selector:@selector(didReceiveConfigureSDKNotification:)
|
|
|
37 |
name:kFIRAppReadyToConfigureSDKNotification
|
|
|
38 |
object:nil];
|
|
|
39 |
}
|
|
|
40 |
|
|
|
41 |
+ (void)didReceiveConfigureSDKNotification:(NSNotification *)notification {
|
|
|
42 |
FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID100010",
|
|
|
43 |
@"Got notification for kFIRAppReadyToConfigureSDKNotification. Setting display "
|
|
|
44 |
"component on headless SDK.");
|
|
|
45 |
|
|
|
46 |
FIRIAMDefaultDisplayImpl *display = [[FIRIAMDefaultDisplayImpl alloc] init];
|
|
|
47 |
[FIRInAppMessaging inAppMessaging].messageDisplayComponent = display;
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
+ (NSBundle *)getViewResourceBundle {
|
|
|
51 |
static NSBundle *resourceBundle;
|
|
|
52 |
static dispatch_once_t onceToken;
|
|
|
53 |
Class myClass = [self class];
|
|
|
54 |
|
|
|
55 |
dispatch_once(&onceToken, ^{
|
|
|
56 |
NSString *bundledResource;
|
|
|
57 |
|
|
|
58 |
// When using SPM, Xcode scopes resources to a target, creating a bundle.
|
|
|
59 |
#if SWIFT_PACKAGE
|
|
|
60 |
// FIAM only provides default UIs for iOS. FIAM for tvOS will not attempt to provide a default
|
|
|
61 |
// display.
|
|
|
62 |
bundledResource = @"Firebase_FirebaseInAppMessaging_iOS";
|
|
|
63 |
#else
|
|
|
64 |
bundledResource = @"InAppMessagingDisplayResources";
|
|
|
65 |
#endif // SWIFT_PACKAGE
|
|
|
66 |
|
|
|
67 |
NSBundle *containingBundle;
|
|
|
68 |
NSURL *bundleURL;
|
|
|
69 |
// The containing bundle is different whether FIAM is statically or dynamically linked.
|
|
|
70 |
for (containingBundle in @[ [NSBundle mainBundle], [NSBundle bundleForClass:myClass] ]) {
|
|
|
71 |
bundleURL = [containingBundle URLForResource:bundledResource withExtension:@"bundle"];
|
|
|
72 |
if (bundleURL != nil) break;
|
|
|
73 |
}
|
|
|
74 |
|
|
|
75 |
if (bundleURL == nil) {
|
|
|
76 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100007",
|
|
|
77 |
@"FIAM Display Resource bundle "
|
|
|
78 |
"is missing: not contained within bundle %@",
|
|
|
79 |
containingBundle);
|
|
|
80 |
return;
|
|
|
81 |
}
|
|
|
82 |
|
|
|
83 |
resourceBundle = [NSBundle bundleWithURL:bundleURL];
|
|
|
84 |
|
|
|
85 |
if (resourceBundle == nil) {
|
|
|
86 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100007",
|
|
|
87 |
@"FIAM Display Resource bundle "
|
|
|
88 |
"is missing: not contained within bundle %@",
|
|
|
89 |
containingBundle);
|
|
|
90 |
}
|
|
|
91 |
});
|
|
|
92 |
return resourceBundle;
|
|
|
93 |
}
|
|
|
94 |
|
|
|
95 |
+ (void)displayCardViewWithMessageDefinition:(FIRInAppMessagingCardDisplay *)cardMessage
|
|
|
96 |
displayDelegate:(id<FIRInAppMessagingDisplayDelegate>)displayDelegate {
|
|
|
97 |
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
98 |
NSBundle *resourceBundle = [self getViewResourceBundle];
|
|
|
99 |
|
|
|
100 |
if (resourceBundle == nil) {
|
|
|
101 |
NSError *error =
|
|
|
102 |
[NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
103 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
104 |
userInfo:@{NSLocalizedDescriptionKey : @"Resource bundle is missing."}];
|
|
|
105 |
[displayDelegate displayErrorForMessage:cardMessage error:error];
|
|
|
106 |
return;
|
|
|
107 |
}
|
|
|
108 |
|
|
|
109 |
FIRIAMTimerWithNSDate *timeFetcher = [[FIRIAMTimerWithNSDate alloc] init];
|
|
|
110 |
FIRIAMCardViewController *cardVC =
|
|
|
111 |
[FIRIAMCardViewController instantiateViewControllerWithResourceBundle:resourceBundle
|
|
|
112 |
displayMessage:cardMessage
|
|
|
113 |
displayDelegate:displayDelegate
|
|
|
114 |
timeFetcher:timeFetcher];
|
|
|
115 |
|
|
|
116 |
if (cardVC == nil) {
|
|
|
117 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100011",
|
|
|
118 |
@"View controller can not be created.");
|
|
|
119 |
NSError *error = [NSError
|
|
|
120 |
errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
121 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
122 |
userInfo:@{NSLocalizedDescriptionKey : @"View controller could not be created"}];
|
|
|
123 |
[displayDelegate displayErrorForMessage:cardMessage error:error];
|
|
|
124 |
return;
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
UIWindow *displayUIWindow = [FIRIAMRenderingWindowHelper windowForBlockingView];
|
|
|
128 |
displayUIWindow.rootViewController = cardVC;
|
|
|
129 |
[displayUIWindow setHidden:NO];
|
|
|
130 |
});
|
|
|
131 |
}
|
|
|
132 |
|
|
|
133 |
+ (void)displayModalViewWithMessageDefinition:(FIRInAppMessagingModalDisplay *)modalMessage
|
|
|
134 |
displayDelegate:
|
|
|
135 |
(id<FIRInAppMessagingDisplayDelegate>)displayDelegate {
|
|
|
136 |
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
137 |
NSBundle *resourceBundle = [self getViewResourceBundle];
|
|
|
138 |
|
|
|
139 |
if (resourceBundle == nil) {
|
|
|
140 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
141 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
142 |
userInfo:@{@"message" : @"resource bundle is missing"}];
|
|
|
143 |
[displayDelegate displayErrorForMessage:modalMessage error:error];
|
|
|
144 |
return;
|
|
|
145 |
}
|
|
|
146 |
|
|
|
147 |
FIRIAMTimerWithNSDate *timeFetcher = [[FIRIAMTimerWithNSDate alloc] init];
|
|
|
148 |
FIRIAMModalViewController *modalVC =
|
|
|
149 |
[FIRIAMModalViewController instantiateViewControllerWithResourceBundle:resourceBundle
|
|
|
150 |
displayMessage:modalMessage
|
|
|
151 |
displayDelegate:displayDelegate
|
|
|
152 |
timeFetcher:timeFetcher];
|
|
|
153 |
|
|
|
154 |
if (modalVC == nil) {
|
|
|
155 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100004",
|
|
|
156 |
@"View controller can not be created.");
|
|
|
157 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
158 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
159 |
userInfo:@{}];
|
|
|
160 |
[displayDelegate displayErrorForMessage:modalMessage error:error];
|
|
|
161 |
return;
|
|
|
162 |
}
|
|
|
163 |
|
|
|
164 |
UIWindow *displayUIWindow = [FIRIAMRenderingWindowHelper windowForBlockingView];
|
|
|
165 |
displayUIWindow.rootViewController = modalVC;
|
|
|
166 |
[displayUIWindow setHidden:NO];
|
|
|
167 |
});
|
|
|
168 |
}
|
|
|
169 |
|
|
|
170 |
+ (void)displayBannerViewWithMessageDefinition:(FIRInAppMessagingBannerDisplay *)bannerMessage
|
|
|
171 |
displayDelegate:
|
|
|
172 |
(id<FIRInAppMessagingDisplayDelegate>)displayDelegate {
|
|
|
173 |
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
174 |
NSBundle *resourceBundle = [self getViewResourceBundle];
|
|
|
175 |
|
|
|
176 |
if (resourceBundle == nil) {
|
|
|
177 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
178 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
179 |
userInfo:@{}];
|
|
|
180 |
[displayDelegate displayErrorForMessage:bannerMessage error:error];
|
|
|
181 |
return;
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
FIRIAMTimerWithNSDate *timeFetcher = [[FIRIAMTimerWithNSDate alloc] init];
|
|
|
185 |
FIRIAMBannerViewController *bannerVC =
|
|
|
186 |
[FIRIAMBannerViewController instantiateViewControllerWithResourceBundle:resourceBundle
|
|
|
187 |
displayMessage:bannerMessage
|
|
|
188 |
displayDelegate:displayDelegate
|
|
|
189 |
timeFetcher:timeFetcher];
|
|
|
190 |
|
|
|
191 |
if (bannerVC == nil) {
|
|
|
192 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100008",
|
|
|
193 |
@"Banner view controller can not be created.");
|
|
|
194 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
195 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
196 |
userInfo:@{}];
|
|
|
197 |
[displayDelegate displayErrorForMessage:bannerMessage error:error];
|
|
|
198 |
return;
|
|
|
199 |
}
|
|
|
200 |
|
|
|
201 |
UIWindow *displayUIWindow = [FIRIAMRenderingWindowHelper windowForNonBlockingView];
|
|
|
202 |
displayUIWindow.rootViewController = bannerVC;
|
|
|
203 |
[displayUIWindow setHidden:NO];
|
|
|
204 |
});
|
|
|
205 |
}
|
|
|
206 |
|
|
|
207 |
+ (void)displayImageOnlyViewWithMessageDefinition:
|
|
|
208 |
(FIRInAppMessagingImageOnlyDisplay *)imageOnlyMessage
|
|
|
209 |
displayDelegate:
|
|
|
210 |
(id<FIRInAppMessagingDisplayDelegate>)displayDelegate {
|
|
|
211 |
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
212 |
NSBundle *resourceBundle = [self getViewResourceBundle];
|
|
|
213 |
|
|
|
214 |
if (resourceBundle == nil) {
|
|
|
215 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
216 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
217 |
userInfo:@{}];
|
|
|
218 |
[displayDelegate displayErrorForMessage:imageOnlyMessage error:error];
|
|
|
219 |
return;
|
|
|
220 |
}
|
|
|
221 |
|
|
|
222 |
FIRIAMTimerWithNSDate *timeFetcher = [[FIRIAMTimerWithNSDate alloc] init];
|
|
|
223 |
FIRIAMImageOnlyViewController *imageOnlyVC =
|
|
|
224 |
[FIRIAMImageOnlyViewController instantiateViewControllerWithResourceBundle:resourceBundle
|
|
|
225 |
displayMessage:imageOnlyMessage
|
|
|
226 |
displayDelegate:displayDelegate
|
|
|
227 |
timeFetcher:timeFetcher];
|
|
|
228 |
|
|
|
229 |
if (imageOnlyVC == nil) {
|
|
|
230 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100006",
|
|
|
231 |
@"Image only view controller can not be created.");
|
|
|
232 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
233 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
234 |
userInfo:@{}];
|
|
|
235 |
[displayDelegate displayErrorForMessage:imageOnlyMessage error:error];
|
|
|
236 |
return;
|
|
|
237 |
}
|
|
|
238 |
|
|
|
239 |
UIWindow *displayUIWindow = [FIRIAMRenderingWindowHelper windowForBlockingView];
|
|
|
240 |
displayUIWindow.rootViewController = imageOnlyVC;
|
|
|
241 |
[displayUIWindow setHidden:NO];
|
|
|
242 |
});
|
|
|
243 |
}
|
|
|
244 |
|
|
|
245 |
#pragma mark - protocol FIRInAppMessagingDisplay
|
|
|
246 |
- (void)displayMessage:(FIRInAppMessagingDisplayMessage *)messageForDisplay
|
|
|
247 |
displayDelegate:(id<FIRInAppMessagingDisplayDelegate>)displayDelegate {
|
|
|
248 |
if ([messageForDisplay isKindOfClass:[FIRInAppMessagingModalDisplay class]]) {
|
|
|
249 |
FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID100000", @"Display a modal message.");
|
|
|
250 |
[self.class displayModalViewWithMessageDefinition:(FIRInAppMessagingModalDisplay *)
|
|
|
251 |
messageForDisplay
|
|
|
252 |
displayDelegate:displayDelegate];
|
|
|
253 |
|
|
|
254 |
} else if ([messageForDisplay isKindOfClass:[FIRInAppMessagingBannerDisplay class]]) {
|
|
|
255 |
FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID100001", @"Display a banner message.");
|
|
|
256 |
[self.class displayBannerViewWithMessageDefinition:(FIRInAppMessagingBannerDisplay *)
|
|
|
257 |
messageForDisplay
|
|
|
258 |
displayDelegate:displayDelegate];
|
|
|
259 |
} else if ([messageForDisplay isKindOfClass:[FIRInAppMessagingImageOnlyDisplay class]]) {
|
|
|
260 |
FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID100002", @"Display an image only message.");
|
|
|
261 |
[self.class displayImageOnlyViewWithMessageDefinition:(FIRInAppMessagingImageOnlyDisplay *)
|
|
|
262 |
messageForDisplay
|
|
|
263 |
displayDelegate:displayDelegate];
|
|
|
264 |
} else if ([messageForDisplay isKindOfClass:[FIRInAppMessagingCardDisplay class]]) {
|
|
|
265 |
FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID100009", @"Display a card message.");
|
|
|
266 |
[self.class displayCardViewWithMessageDefinition:(FIRInAppMessagingCardDisplay *)
|
|
|
267 |
messageForDisplay
|
|
|
268 |
displayDelegate:displayDelegate];
|
|
|
269 |
|
|
|
270 |
} else {
|
|
|
271 |
FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID100003",
|
|
|
272 |
@"Unknown message type %@ "
|
|
|
273 |
"Don't know how to handle it.",
|
|
|
274 |
messageForDisplay.class);
|
|
|
275 |
NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain
|
|
|
276 |
code:FIAMDisplayRenderErrorTypeUnspecifiedError
|
|
|
277 |
userInfo:@{}];
|
|
|
278 |
[displayDelegate displayErrorForMessage:messageForDisplay error:error];
|
|
|
279 |
}
|
|
|
280 |
}
|
|
|
281 |
@end
|
|
|
282 |
|
|
|
283 |
#endif // TARGET_OS_IOS
|