Pria Pria - 11 months ago 89
Objective-C Question

Firebase remote config crashing (objective c iOS)

I am having trouble fetching information from Firebase RemoteConfig. On app install, I have a language selection screen before the MainController view controller. On the MainController View controller, I am doing a RemoteConfig fetch. It works the first time, when the language selection screen is shown before the MainController view controller. But, from the next time, it crashes on this particular line:

[self.remoteConfig fetchWithExpirationDuration:expirationDuration completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {

With the following exception:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSTaggedPointerString firstObject]: unrecognized selector sent to instance 0xa0000000000616a2'
*** First throw call stack:
0 CoreFoundation 0x000000010d20134b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010cc6221e objc_exception_throw + 48
2 CoreFoundation 0x000000010d270f34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x000000010d186c15 ___forwarding___ + 1013
4 CoreFoundation 0x000000010d186798 _CF_forwarding_prep_0 + 120
5 English 0x0000000107f44e1b -[GIPLocale googleLanguageWithAppleLanguages:] + 33
6 English 0x0000000107f45396 -[GIPLocale recalculateLocale] + 54
7 English 0x0000000107f44c26 -[GIPLocale initWithLanguageMappings:] + 99
8 English 0x0000000107f44b77 __25+[GIPLocale googleLocale]_block_invoke + 41
9 libdispatch.dylib 0x000000010da900cd _dispatch_client_callout + 8
10 libdispatch.dylib 0x000000010da751fc dispatch_once_f + 501
11 English 0x0000000107f44b4c +[GIPLocale googleLocale] + 42
12 English 0x0000000107f42d06 +[RCNDevice deviceLocale] + 31
13 English 0x0000000107f43344 +[RCNDevice hasDeviceContextChanged:projectIdentifier:] + 325
14 English 0x0000000107f3e133 -[RCNConfigFetch fetchAllConfigsWithExpirationDuration:completionHandler:] + 150
15 English 0x0000000107f3577f -[FIRRemoteConfig fetchWithExpirationDuration:completionHandler:] + 77

UPDATE: It doesn't matter if I show the language selection screen or not. It always works on a fresh install and stops working from next launches.

This is my full code I am using.

//Display select language settings
if (![[NSUserDefaults standardUserDefaults] boolForKey:DISPLAY_LANGUAGE_SETTING])
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:TRUE forKey:DISPLAY_LANGUAGE_SETTING];
[defaults synchronize];
//Display Language Screen
AGSelectLanguageViewController *languageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"AGSelectLanguageViewController"];
self.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:languageViewController animated:NO completion:nil];

[self configFireBase];

// Firebase Configuration
self.remoteConfig = [FIRRemoteConfig remoteConfig];
//Enabling development mode
FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] initWithDeveloperModeEnabled:YES];
self.remoteConfig.configSettings = remoteConfigSettings;

//Set default Remote Config values
[self.remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"];

[self fetchConfig];

- (void)fetchConfig {
_discount_percentage = self.remoteConfig[DISCOUNT_PERCENTAGE].numberValue.floatValue;

long expirationDuration = 3600;

if (self.remoteConfig.configSettings.isDeveloperModeEnabled) {
expirationDuration = 0;

[self.remoteConfig fetchWithExpirationDuration:expirationDuration completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
if (status == FIRRemoteConfigFetchStatusSuccess) {
NSLog(@"Config fetched!");
[self.remoteConfig activateFetched];
} else {
NSLog(@"Config not fetched");
NSLog(@"Error %@", error.localizedDescription);

Where am I wrong? Please help.

Answer Source

The GIPLocale class does some mapping between Google and Apple names for locales, and as part of that it pulls the app's locales from NSUserDefaults:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];

I am guessing that somewhere that defaults entry is getting set to just a string or similar rather than an array - check if you're referencing that string anywhere in your app.