Crash after receiving a Voip Push - ios

While testing Voip Pushes i came across this error
2016-10-19 14:03:26.809 linphone[332:33741] Can't endBackgroundTask: no background task exists with identifier c6, or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.
Oct 19 14:03:26 linphone[332] <Notice>: ios/(honeAppDelegate.m:492 ) PushKit received with payload : <PKPushPayload: 0x14ee5b30>
Oct 19 14:03:26 linphone[332] <Notice>: ios/(honeAppDelegate.m:494 ) incoming voip notfication: {
aps = {
alert = Testando;
};
}
2016-10-19 14:03:26.818 linphone[332:33741] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x18e5c760
2016-10-19 14:03:26.821 linphone[332:33741] Crash: -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x18e5c760
2016-10-19 14:03:26.902 linphone[332:33741] Stack Trace: (
0 CoreFoundation 0x24bff933 <redacted> + 150
1 libobjc.A.dylib 0x2439ae17 objc_exception_throw + 38
2 CoreFoundation 0x24c052b5 <redacted> + 0
3 CoreFoundation 0x24c02ee1 <redacted> + 700
4 CoreFoundation 0x24b2e238 _CF_forwarding_prep_0 + 24
5 linphone 0x0002ee2f -[LinphoneAppDelegate processRemoteNotification:] + 214
6 linphone 0x00030f15 __78-[LinphoneAppDelegate pushRegistry:didReceiveIncomingPushWithPayload:forType:]_block_invoke_2 + 96
7 libdispatch.dylib 0x012ddb7f _dispatch_call_block_and_release + 10
8 libdispatch.dylib 0x012ddb6b _dispatch_client_callout + 22
9 libdispatch.dylib 0x012e2655 _dispatch_main_queue_callback_4CF + 1680
10 CoreFoundation 0x24bc1b6d <redacted> + 8
11 CoreFoundation 0x24bc0067 <redacted> + 1574
12 CoreFoundation 0x24b0f229 CFRunLoopRunSpecific + 520
13 CoreFoundation 0x24b0f015 CFRunLoopRunInMode + 108
14 GraphicsServices 0x260ffac9 GSEventRunModal + 160
15 UIKit 0x291e3189 UIApplicationMain + 144
16 linphone 0x0002b949 main + 124
17 libdyld.dylib 0x247b7873 <redacted> + 2
)
2016-10-19 14:03:26.907 linphone[332:33741] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x18e5c760'
*** First throw call stack:
(0x24bff91b 0x2439ae17 0x24c052b5 0x24c02ee1 0x24b2e238 0x2ee2f 0x30f15 0x12ddb7f 0x12ddb6b 0x12e2655 0x24bc1b6d 0x24bc0067 0x24b0f229 0x24b0f015 0x260ffac9 0x291e3189 0x2b949 0x247b7873)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Here is the code XCode points me to when the app crashes.
- (void)processRemoteNotification:(NSDictionary *)userInfo {
NSDictionary *aps = [userInfo objectForKey:#"aps"];
if (aps != nil) {
NSDictionary *alert = [aps objectForKey:#"alert"];
if (alert != nil) {
NSString *loc_key = [alert objectForKey:#"loc-key"];
/* if we receive a remote notification, it is probably because our TCP background socket was no more working.
As a result, break it and refresh registers in order to make sure to receive incoming INVITE or MESSAGE*/
if (linphone_core_get_calls(LC) == NULL) { // if there are calls, obviously our TCP socket shall be working
//linphone_core_set_network_reachable(LC, FALSE);
if (!linphone_core_is_network_reachable(LC)) {
LinphoneManager.instance.connectivity = none; //Force connectivity to be discovered again
[LinphoneManager.instance setupNetworkReachabilityCallback];
}
if (loc_key != nil) {
NSString *callId = [userInfo objectForKey:#"call-id"];
if (callId != nil) {
[LinphoneManager.instance addPushCallId:callId];
} else {
LOGE(#"PushNotification: does not have call-id yet, fix it !");
}
if ([loc_key isEqualToString:#"IC_MSG"]) {
[self fixRing];
}
}
}
}
}
LOGI(#"Notification %# processed", userInfo.description);
}
As you can see, I do receive the push notification but only on the log, it wont pop on my phone and the app crashes.

You are accessing the value for key "loc-key" in "alert" dictionary and in the payload "alert" dictionary doesn't have the value for this key, therefore it is crashing at NSString *loc_key = [alert objectForKey:#"loc-key"];

I ran into the same issue. The server side was pushing notifications containing only the "Incoming Notification" string. Thus, the objectForKey:#"loc-key" would crash - The push notification did not contain strings in the expected format. To work around this, I checked the contents of the push notifications from the server. For legacy push servers, a comparison of alert to "Incoming Notification" would yield true. In this case, I would then set alert to nil to bypass the crash.
NSDictionary *alert = [aps objectForKey:#"alert"];
BOOL result = [alert isEqual:#"Incoming Notification"];
if (result == true)
{
if (linphone_core_get_calls(LC) == NULL) { // if there are calls, obviously our TCP socket shall be working
if (!linphone_core_is_network_reachable(LC)) {
LinphoneManager.instance.connectivity = none; //Force connectivity to be discovered again
[LinphoneManager.instance setupNetworkReachabilityCallback];
}
}
alert = nil;
}
if (alert != nil) {
...
}

Related

UIMenuController crashes on macOS Monterey

My iOS app uses UIMenuController to show the Copy/Paste context menu. When I launch the app on macOS 12.0 and control-click (right click) with the mouse or the trackpad, the app crashes upon showing the menu with this crash log:
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: title)'
Last Exception Backtrace:
0 CoreFoundation 0x1be758118 __exceptionPreprocess + 220
1 libobjc.A.dylib 0x1be4a9808 objc_exception_throw + 60
2 CoreFoundation 0x1be828464 -[__NSCFString characterAtIndex:].cold.1 + 0
3 CoreFoundation 0x1be835270 -[__NSDictionaryM setObject:forKey:].cold.3 + 0
4 CoreFoundation 0x1be691590 -[__NSDictionaryM setObject:forKey:] + 904
5 UIKitCore 0x1e5b85998 -[_UIMenuBarItem properties] + 124
6 UIKitMacHelper 0x1d3bc7058 UINSNSMenuItemFromUINSMenuItem + 96
7 UIKitMacHelper 0x1d3bc6d60 _insertUINSMenuItemsIntoNSMenu + 844
8 UIKitMacHelper 0x1d3bc67c0 UINSNSMenuFromUINSMenu + 152
9 UIKitMacHelper 0x1d3bc6690 -[UINSMenuController _createNSMenu:forContextMenu:] + 92
10 UIKitMacHelper 0x1d3c3505c -[UINSMenuController _prepareToShowContextMenu:activityItemsConfiguration:] + 144
11 UIKitMacHelper 0x1d3c349c0 -[UINSMenuController showContextMenu:inWindow:atLocationInWindow:activityItemsConfiguration:] + 312
12 libdispatch.dylib 0x1be44ce60 _dispatch_call_block_and_release + 32
13 libdispatch.dylib 0x1be44ebac _dispatch_client_callout + 20
14 libdispatch.dylib 0x1be45d0ac _dispatch_main_queue_callback_4CF + 944
15 CoreFoundation 0x1be719e60 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
I tried the same with several iOS apps from other developers and all of them crash on macOS when I right-click with the mouse.
Has anyone found a workaround?
It's possible to fix this by swizzling the properties method on the private _UIMenuBarItem class. Obviously this comes with the usual disclaimer that this might get you rejected by Apple (but in practice that doesn't seem to cause rejections that often).
Here's the fix: The basic idea is to wrap the original method call in a #try/#catch block. The crash happens because the original implementation sometimes tries to insert a nil value for the title key into an NSDictionary. This workaround catches that exception and then returns a dummy dictionary to satisfy the caller.
UIMenuBarItemMontereyCrashFix.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// Helper class to apply a fix to prevent a crash on macOS Monterey when a user right-clicks in a text field
#interface UIMenuBarItemMontereyCrashFix : NSObject
/// Apply the crash fix. It will only be applied the first time it's called, subsequent calls are no-ops.
/// It will only have an effect when called on macOS Monterey or later.
+ (void)applyCrashFixIfNeeded;
#end
NS_ASSUME_NONNULL_END
UIMenuBarItemMontereyCrashFix.m
#import "UIMenuBarItemMontereyCrashFix.h"
#import <objc/runtime.h>
static BOOL hasCrashFixBeenApplied = NO;
#implementation UIMenuBarItemMontereyCrashFix
/// Apply the crash fix. It will only be applied the first time it's called, subsequent calls are no-ops.
+ (void)applyCrashFixIfNeeded
{
if (#available(macOS 12.0, *)) {} else {
// Bail if we are not running on Monterey
return;
}
if (!hasCrashFixBeenApplied) {
Class UnderscoreUIMenuBarItem = NSClassFromString(#"_UIMenuBarItem");
SEL selector = sel_getUid("properties");
Method method = class_getInstanceMethod(UnderscoreUIMenuBarItem, selector);
IMP original = method_getImplementation(method);
// The crash happens because in some instances the original implementation
// tries to insert `nil` as a value for the key `title` into a dictionary.
// This is how the fix works:
// We wrap the original implementation call in a #try/#catch block. When the
// exception happens, we catch it, and then return a dummy dictionary to
// satisfy the caller. The dummy has `isEnabled` set to NO, and `isHidden` set
// to YES.
IMP override = imp_implementationWithBlock(^id(id me) {
#try {
id res = ((id (*)(id))original)(me);
return res;
}
#catch(NSException *exception) {
return #{
#"allowsAutomaticKeyEquivalentLocalization" : #0,
#"allowsAutomaticKeyEquivalentMirroring" : #0,
#"defaultCommand" : #0,
#"identifier":#"com.apple.menu.application",
#"imageAlwaysVisible" : #0,
#"isAlternate" : #0,
#"isEnabled" : #0,
#"isHidden" : #1,
#"isSeparatorItem" : #0,
#"keyEquivalent" : #"",
#"keyEquivalentModifiers" : #0,
#"remainsVisibleWhenDisabled" : #0,
#"state" : #0,
#"title" : #""
};
}
});
method_setImplementation(method, override);
hasCrashFixBeenApplied = YES;
}
}
#end
Remember to add UIMenuBarItemMontereyCrashFix.h to your bridging header so you can call it from Swift. Then simply call UIMenuBarItemMontereyCrashFix.applyIfNeeded() somewhere during your app's startup sequence (for example in your AppDelegate).

Updating city in iOS Contacts postalAddress

I’m new to iOS (Swift) development, and I’ve been tinkering with this all week. I am trying to update only the city of the postal addresses of a contact from iOS Contacts, and leave the rest of the postal address (street, ZIP code, etc.) intact. I figured I could just get a mutable copy of the contact.postalAddress using postalAddress.mutableCopy(), and then write to mutableCopy.city = “New City”. However, when I try this I get a -[CNLabeledValue mutableCopyWithZone:]: unrecognized selector sent to instance error. My current solution is to create a new address filled with values from the old address, but it seems there should be a better way (like copying the old address and just changing the city, like I’m trying to do). Is there something I’m missing? Thanks!
So, what I want to work:
func updateContact(contact: CNContact) -> BooleanLiteralType{
var success = false
let store = CNContactStore()
do {
let updContact = contact.mutableCopy() as! CNMutableContact
var addrArray = [CNLabeledValue<CNPostalAddress>]()
for postAddress in updContact.postalAddresses{
let curLabel = postAddress.label
var address = postAddress.mutableCopy() as! CNMutablePostalAddress
address.city = "Cityville"
let curAddrLabeledVal = CNLabeledValue<CNPostalAddress>(label:curLabel, value:address)
addrArray.append(curAddrLabeledVal)
}
updContact.postalAddresses = addrArray
let req = CNSaveRequest()
req.update(updContact)
try store.execute(req)
success = true
}
catch let err{
print(err)
}
return success
}
This results in the following exception:
2020-05-26 00:06:19.537517+0200 My App[78089:4168944] -[CNLabeledValue mutableCopyWithZone:]: unrecognized selector sent to instance 0x600001388b80
2020-05-26 00:06:19.545537+0200 My App[78089:4168944] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CNLabeledValue mutableCopyWithZone:]: unrecognized selector sent to instance 0x600001388b80'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23e3cf0e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50ba89b2 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23e5dc34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x00007fff23e4190c ___forwarding___ + 1436
4 CoreFoundation 0x00007fff23e43bf8 _CF_forwarding_prep_0 + 120
5 My App 0x00000001015b4898 $s12My_App13updateContact7contactSbSo9CNContactC_tF + 1048
6 My App 0x00000001015bf3f1 $s12My_App11ContentViewV4bodyQrvg7SwiftUI05TupleD0VyAE0D0PAEE7opacityyQrSdFQOyAiEE5frame5width6height9alignmentQr12CoreGraphics7CGFloatVSg_ArE9AlignmentVtFQOyAA11ProgressBarV_Qo__Qo__AE010NavigationD0VyAiEE010navigationS5Items7leading8trailingQrqd___qd_0_tAeHRd__AeHRd_0_r0_lFQOyAiEE0uS5TitleyQrAE4TextVFQOyAE4ListVys5NeverOAE7ForEachVySaySo9CNContactCGSSAE6HStackVyAE0T4LinkVyAA10ContactRowVAA13ContactDetailVGGGG_Qo__AE6ButtonVyA4_GA29_Qo_GtGyXEfU_A30_yXEfU_yycfU2_yycfU_ + 465
7 My App 0x00000001015bf8f0 $sIeg_IeyB_TR + 48
8 libdispatch.dylib 0x0000000101877f11 _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x0000000101878e8e _dispatch_client_callout + 8
10 libdispatch.dylib 0x000000010187b2d8 _dispatch_queue_override_invoke + 1022
11 libdispatch.dylib 0x000000010188a399 _dispatch_root_queue_drain + 351
12 libdispatch.dylib 0x000000010188aca6 _dispatch_worker_thread2 + 135
13 libsystem_pthread.dylib 0x00007fff51c089f7 _pthread_wqthread + 220
14 libsystem_pthread.dylib 0x00007fff51c07b77 start_wqthread + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
This is the solution that works, but as you can see it’s not really what I want as it requires me to define all postalAddress attributes:
func updateContact(contact: CNContact) -> BooleanLiteralType{
var success = false
let store = CNContactStore()
do {
let updContact = contact.mutableCopy() as! CNMutableContact
var addrArray = [CNLabeledValue<CNPostalAddress>]()
for postAddress in updContact.postalAddresses{
let curLabel = postAddress.label
let address = CNMutablePostalAddress()
address.street = postAddress.value.street
address.city = "Cityville"
address.postalCode = postAddress.value.postalCode
address.state = postAddress.value.state
address.country = postAddress.value.country
address.isoCountryCode = postAddress.value.isoCountryCode
address.subAdministrativeArea = postAddress.value.subAdministrativeArea
address.subLocality = postAddress.value.subLocality
let curAddrLabeledVal = CNLabeledValue<CNPostalAddress>(label:curLabel, value:address)
addrArray.append(curAddrLabeledVal)
}
updContact.postalAddresses = addrArray
let req = CNSaveRequest()
req.update(updContact)
try store.execute(req)
success = true
}
catch let err{
print(err)
}
return success
}
Any help is much appreciated!

Unable to Show onComingCall ViewController for my iOS VoIP Application

I want my App to show IncomingCall ViewController, when App Receives Some Incoming Call.
This is my Code that I uses to show Incoming Call.. From my ContactsViewController, which is Active View when Incoming Call take places.
- (void)showIncomigCallVC{
[self performSegueWithIdentifier:#"segueToIncomingCallVC" sender:nil];
}
This is my Code, that is called by Library.
/* Callback called by the library upon receiving incoming call */
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
pjsip_rx_data *rdata)
{
pjsua_call_info ci;
PJ_UNUSED_ARG(acc_id);
PJ_UNUSED_ARG(rdata);
pjsua_call_get_info(call_id, &ci);
PJ_LOG(3,(THIS_FILE, "....\n\n\n Incoming call from %.*s!! \n\n\n",
(int)ci.remote_info.slen,
ci.remote_info.ptr));
ContactsViewController *incomingCallVC = [[ContactsViewController alloc]init];
[incomingCallVC showIncomigCallVC];
/* Automatically answer incoming calls with 200/OK */
pjsua_call_answer(call_id, 200, NULL, NULL);
}
And This is my Console Output:
20:39:37.482 XCPjsua.c ......
Incoming call from <sip:eeshaMiss12#ekiga.net>!!
2017-01-16 20:39:37.494 simpleVoIP[922:19652] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<ContactsViewController: 0x7bea3d00>) has no segue with identifier 'segueToIncomingCallVC''
*** First throw call stack:
(
0 CoreFoundation 0x03a14212 __exceptionPreprocess + 194
1 libobjc.A.dylib 0x034d3e66 objc_exception_throw + 52
2 UIKit 0x01a69893 -[UIViewController shouldPerformSegueWithIdentifier:sender:] + 0
3 simpleVoIP 0x00089ba6 -[ContactsViewController showIncomigCallVC] + 70
4 simpleVoIP 0x00086caf on_incoming_call + 255
5 simpleVoIP 0x000fc273 pjsua_call_on_incoming + 3811
6 simpleVoIP 0x00103294 mod_pjsua_on_rx_request + 84
7 simpleVoIP 0x0012938f pjsip_endpt_process_rx_data + 351
8 simpleVoIP 0x00128bf2 endpt_on_rx_msg + 546
9 simpleVoIP 0x0012fba1 pjsip_tpmgr_receive_packet + 849
10 simpleVoIP 0x001315ec udp_on_read_complete + 316
11 simpleVoIP 0x0014b8e0 ioqueue_dispatch_read_event + 704
12 simpleVoIP 0x0014d5b2 pj_ioqueue_poll + 946
13 simpleVoIP 0x001290c3 pjsip_endpt_handle_events2 + 163
14 simpleVoIP 0x00102023 worker_thread + 99
15 simpleVoIP 0x0014eb96 thread_main + 86
16 libsystem_pthread.dylib 0x04c8a11b _pthread_body + 184
17 libsystem_pthread.dylib 0x04c8a063 _pthread_body + 0
18 libsystem_pthread.dylib 0x04c8993e thread_start + 34
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I am Beginner, any Recommendation will be appreciated.. Thanks in Advance
You are experiencing the crash, because you are programatically allocating your ContactsViewController, instead of using from the storyboard.
When you do this:
ContactsViewController *incomingCallVC = [[ContactsViewController alloc]init];
[incomingCallVC showIncomigCallVC];
You are creating an instance of ContactsViewController, what has nothing to do with the one created in our storyboard.
It would be possible to overcome on this, however, you are trying to make a segue call on a viewController, what has only been loaded to the memory, but is not visible at all. That will never work, it will always crash.
I would recommend to show your viewController, whatever is behind the segue, straight away, instead of creating a viewController and show it with a segue.
EDIT:
Using the code below, you should be able to present your desired UIViewController subclass from the end of your callback function.
// Lets get keywindow
UIWindow* keyWindow = [[[UIApplication sharedApplication] delegate] window];
keyWindow.frame = [UIScreen mainScreen].bounds;
// Lets get `IncomingCallViewController` from storyboard
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"TheNameOfYourStoryboard" bundle:nil];
// do not forget to set the identifier of your viewController on the storyboard as "IncomingCallViewController"
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"IncomingCallViewController"];
// Lets present the keyWindow from the main thread
dispatch_async(dispatch_get_main_queue(), ^{
keyWindow.rootViewController = vc;
[keyWindow makeKeyAndVisible];
});

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.
-(void)viewDidAppear:(BOOL)animated{
//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];
}
-(void)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.
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.

CoreData could not fulfill a fault with unmodified relationship

I have a entity A, it has a relationship B.
Here is a array fetched from CoreData:
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"isSynchronized = NO"];
NSManagedObjectContext *context = [NSManagedObjectContext MR_contextForCurrentThread];
NSArray * newWordsToSynchronize = [A MR_findAllWithPredicate:predicate inContext:context];
NSMutableArray * newWordsParameters = [NSMutableArray arrayWithCapacity:[asToSynchronize count]];
[newWordsToSynchronize enumerateObjectsUsingBlock:^(A * a, NSUInteger idx, BOOL * stop) {
NSLog(#"============= may have some problem ============");
NSLog(#"[a hasFaultForRelationshipNamed:#\"b\"] = %d", [a hasFaultForRelationshipNamed:#"b"]);
NSLog(#"a.word = %#", a.word);
NSLog(#"a.b.objectID = %#", a.b.objectID);
NSLog(#"a.managedObjectContext = %#", a.managedObjectContext);
NSLog(#"a.b.managedObjectContext = %#", [a.b managedObjectContext]);
NSLog(#"a.b.managedObjectContext = %#", [a.b managedObjectContext]);
NSLog(#"a.managedObjectContext = %#", a.managedObjectContext);
NSDictionary *paramDictionary = #{
#"nbook" : a.b.name,
#"lang" : a.lang,
...
};
[newWordsParameters addObject:paramDictionary];
}];
The [a.b managedObjectContext] method may return nil when I call it at second time and then the app goes crash.
Crash log from console:
2014-01-20 14:29:14.561 MyApp[10563:2e07] a.b.objectID = 0x1754e940 <x-coredata://DFC4F956-D5AC-4264-8717-C07090CA9547/B/p1>
2014-01-20 14:29:14.561 MyApp[10563:2e07] a.managedObjectContext = <NSManagedObjectContext: 0x1754bc00>
2014-01-20 14:29:14.561 MyApp[10563:2e07] a.b.managedObjectContext = <NSManagedObjectContext: 0x1754bc00>
2014-01-20 14:29:14.562 MyApp[10563:2e07] a.b.managedObjectContext = (null)
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x1754e940 <x-coredata://DFC4F956-D5AC-4264-8717-C07090CA9547/B/p1>''
*** First throw call stack:
(
0 CoreFoundation 0x037495e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x034cc8b6 objc_exception_throw + 44
2 CoreData 0x031a233b _PFFaultHandlerLookupRow + 2715
3 CoreData 0x031a1897 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
4 CoreData 0x031a1473 _PF_FulfillDeferredFault + 259
5 CoreData 0x031a12c6 _sharedIMPL_pvfk_core + 70
6 CoreData 0x031e7130 _pvfk_5 + 32
7 MyApp 0x00181b00 __68-[CichangAHTTPEngine synchronizeAsOnCompletion:failure:]_block_invoke + 1760
8 CoreFoundation 0x037435eb __NSArrayEnumerate + 571
9 CoreFoundation 0x03743196 -[NSArray enumerateObjectsWithOptions:usingBlock:] + 102
10 CoreFoundation 0x037430a5 -[NSArray enumerateObjectsUsingBlock:] + 53
11 MyApp 0x0018105b -[CichangAHTTPEngine synchronizeAsOnCompletion:failure:] + 1179
12 MyApp 0x00185d9e __65-[CichangAHTTPEngine downloader:didFinishedDownloadObject:]_block_invoke_3 + 2030
13 libdispatch.dylib 0x040717f8 _dispatch_call_block_and_release + 15
14 libdispatch.dylib 0x040864b0 _dispatch_client_callout + 14
15 libdispatch.dylib 0x04074eeb _dispatch_root_queue_drain + 287
16 libdispatch.dylib 0x04075137 _dispatch_worker_thread2 + 39
17 libsystem_pthread.dylib 0x04412dab _pthread_wqthread + 336
18 libsystem_pthread.dylib 0x04416cce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type _NSCoreDataException
I found that B will be deallocated after first [a.b managedObjectContext] calling.
I think it was mainly caused by Core Data 1550 error (If I do not call [a.b managedObjectContext], Core Data will reports "The operation couldn’t be completed. (Cocoa error 1550.)"). But what may cause 1550 error and how to fix it?
1550 error report:
Error Domain=NSCocoaErrorDomain Code=1550 "The operation couldn’t be completed. (Cocoa error 1550.)" UserInfo=0x167269c0 {NSLocalizedDescription=The operation couldn’t be completed. (Cocoa error 1550.), Dangling reference to an invalid object.=null, NSValidationErrorObject=<A: 0x16bab420> (entity: A; id: 0x16baae50 <x-coredata://A85EE9AB-97C1-43C1-B92E-A6C906F0C1A8/A/p168> ; data: {
date = "2014-01-21 02:32:00 +0000";
expect = "2014-01-21 02:31:59 +0000";
isSynchronized = 1;
lang = en;
last = "2014-01-21 02:01:59 +0000";
level = 1;
b = "0x16bab460 <x-coredata://A85EE9AB-97C1-43C1-B92E-A6C906F0C1A8/B/p1>";
status = "-1";
studycount = 0;
trans = "v. \U6d4b\U91cf\Uff0c\U6743\U8861 ";
word = measure;
}), NSAffectedObjectsErrorKey=(
"<B: 0x16babd70> (entity: B; id: 0x16bab460 <x-coredata://A85EE9AB-97C1-43C1-B92E-A6C906F0C1A8/B/p1> ; data: <fault>)"
), NSValidationErrorKey=newWordBook, NSValidationErrorValue=<B: 0x16babd70> (entity: B; id: 0x16bab460 <x-coredata://A85EE9AB-97C1-43C1-B92E-A6C906F0C1A8/B/p1> ; data: <fault>), NSValidationErrorShouldAttemptRecoveryKey=true}
If the 1550 error happened, "CoreData could not fulfill a fault" crash will more easer to cause.
“Core Data could not fulfill fault” really means that there was a deletion. There was data in the persistent store. Then managed object representing this data was created. The object was a fault. Then the data in the store was deleted. Then some property of an object was accessed and Core Data tried to fulfill the fault, but couldn’t.
If you’re not doing explicit deletions, then also make sure that implicit deletions are not happening. Deletion behind the scenes could happen when one of your relationships was configured with the cascade deletion rule.
In your example this could happen if the relationship from A to B was configured with cascade rule, and object A was deleted.

Resources