I have an application that is using the MultiPeer Connectivity framework. Every time the application becomes active in AppDelegate, I make a new MCSession a MCNearbyBrowserService, and a MCNearbyAdvertiserService and call start browsing and start advertising. Then every time the application becomes inactive in AppDelegate, I stop browsing and advertising and set everything to nil. I find that MCNearbyBrowserService causes a crash in its syncQueue:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** - [__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'
*** First throw call stack:
(0x2de3ee8b 0x381396c7 0x2dd7caef 0x2dd7c8b3 0x2f648167 0x2f6493af 0x3861e103 0x38622e77 0x3861ff9b 0x38623751 0x386239d1 0x3874ddff 0x3874dcc4)
libc++abi.dylib: terminating with uncaught exception of type NSException
sometimes when the app reopens.
Here is my code for applicationDidBecomeActive:
self.myIdentifier = [[MCPeerID alloc] initWithDisplayName:[self.class createHash:20]];
self.mainSession = [[MCSession alloc] initWithPeer:self.myIdentifier];
self.mainSession.delegate = self;
peerAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.myIdentifier discoveryInfo:nil serviceType: service];
peerAdvertiser.delegate = self;
peerBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.myIdentifier serviceType: service];
peerBrowser.delegate = self;
acceptReset = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(reset) userInfo:nil repeats:YES];
acceptPosts = true;
[peerBrowser startBrowsingForPeers];
[peerAdvertiser startAdvertisingPeer];
self.isBrowsing = true;
and here is my code for applicationWillResignActive:
[acceptReset invalidate];
[peerAdvertiser stopAdvertisingPeer];
[peerBrowser stopBrowsingForPeers];
[self.mainSession disconnect];
self.mainSession = false;
self.isBrowsing = false;
The full code can be viewed here: http://pastebin.com/E3wY6U4N
I remember running into this issue, and the quick fix was to nil out the delegates and release the browser and advertiser. So assuming your App Delegate has a strong property for each the setup method would look like:
self.peerAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.myIdentifier discoveryInfo:nil serviceType: service];
self.peerAdvertiser.delegate = self;
self.peerBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.myIdentifier serviceType: service];
self.peerBrowser.delegate = self;
And then when the app enters the background (or otherwise wants to stop browsing/advertising):
self.peerAdvertiser.delegate = nil;
[self.peerAdvertiser stopAdvertisingPeer];
self.peerAdvertiser = nil;
self.peerBrowser.delegate = nil;
[self.peerBrowser stopBrowsingForPeers];
self.peerBrowser = nil;
[self.mainSession disconnect];
I'd also recommend against creating a new MCPeerID on each app launch, as Multipeer Connectivity has a habit of discovering old peers, and you'll end up discovering your 'former self' on each relaunch.
Related
I have two targets in my workspace an iOS App (Bundle id: com.gotit.iphone.gotit, App Group: group.com.gotit.iphone.gotit) and an share extension (Bundle id: group.com.gotit.iphone.gotit.Got-it, App Group: group.com.gotit.iphone.gotit).
I can use my share extension without problem but sometimes (not all the time) when I directly come back to my iOS app I have this error and my app crashes :
Attempted to create a task in a session that has been invalidated
2015-07-22 16:31:21.999 iphone[6095:717111] *** Assertion failure in -[BDBOAuth1SessionManager setDelegate:forTask:], /Users/gautier/Documents/Dev/gotit/iOS/iPhone/trunk/iphone/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m:449
2015-07-22 16:31:22.001 iphone[6095:717111] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: task'
*** First throw call stack:
(0x1865a02d8 0x1982140e4 0x1865a0198 0x187454ed4 0x100547340 0x1005476d8 0x100549190 0x100522084 0x100520a38 0x1000c94a8 0x1000d9f9c 0x1000d9d8c 0x18b02ff08 0x18b1bb2bc 0x18b0cde84 0x18b0cdc50 0x18b0cdbd0 0x18b0156f4 0x18a951db8 0x18a94c820 0x18a94c6c4 0x18a94be58 0x18a94bbd8 0x18a945300 0x1865582a4 0x186555230 0x186555610 0x1864812d4 0x18fedf6fc 0x18b07ef40 0x1000d6fac 0x1988bea08)
libc++abi.dylib: terminating with uncaught exception of type NSException
I use AFNetworking (with BDBOAuth1SessionManager) and this is how I create my networkManager :
+ (instancetype)create {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[[self class] alloc] init];
});
return _sharedClient;
}
+ (instancetype)sharedClient {
if (!_sharedClient) {
[GotItClient create];
}
return _sharedClient;
}
- (id)init {
self = [super init];
if (self) {
NSURL *baseURL = [NSURL URLWithString:kSCGotItClientAPIURL];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:#"group.com.gotit.iphone.gotit"];
sessionConfiguration.sharedContainerIdentifier = #"group.com.gotit.iphone.gotit";
_networkManager = [[BDBOAuth1SessionManager alloc]
initWithBaseURL:baseURL
sessionConfiguration:sessionConfiguration
consumerKey:kSCGotItClientKey
consumerSecret:kSCGotItClientSecret
shareDefaultGroupId:#"group.com.gotit.iphone.gotit"];
_networkManager.responseSerializer = [[AFJSONResponseSerializer alloc] init];
//4 operations at same time
[[_networkManager operationQueue] setMaxConcurrentOperationCount:20];
}
return self;
}
Tell me if you need more code
I'm adding Google Admob Fullscreen ads
m_interstitial = [[GADInterstitial alloc] initWithAdUnitID:ADMOB_FS_ID]; // crash here!!!
m_interstitial.delegate = self;
GADRequest* request = [GADRequest request];
request.testDevices = #[ #"XXXXXXXXXXXXXXXXXXXXXXXxxx" ];
[m_interstitial loadRequest:request];
But the app is crash at the init line.
I'm using the Admob ios sdk 7.3.1.
The crash report is below
2015-06-03 00:22:17.077 XXX[17213:4624660] -[GADInterstitialViewController setSlot:]: unrecognized selector sent to instance 0x14e4b6f0
2015-06-03 00:22:17.079 XXX[17213:4624660] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GADInterstitialViewController setSlot:]: unrecognized selector sent to instance 0x14e4b6f0'
*** First throw call stack:
(0x29e9a5a7 0x37a80c77 0x29e9fa6d 0x29e9d949 0x29dceb68 0x1dc9f4 0x19b8b4 0xd3923 0xe488d 0x2d3b437b 0x2d418553 0x2d4184dd 0x2d3945e7 0x29e61275 0x29e5e959 0x29e5ed5b 0x29dabb51 0x29dab963 0x312ea1a9 0x2d3fdc91 0x102011 0x38029aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException
Whats the matter?
EDIT: My whole code is below
in AppDelegate.m
- (void)showNag
{
// GAD full
// m_interstitial = [[GADInterstitial alloc] initWithAdUnitID:ADMOB_FS_ID];
m_interstitial = [[GADInterstitial alloc] init];
m_interstitial.adUnitID = ADMOB_FS_ID;
m_interstitial.delegate = self;
GADRequest* request = [GADRequest request];
request.testDevices = #[ #"251a8278d43c4c1468ce2d807a0ccc72" ];
[m_interstitial loadRequest:request];
}
viewcontroller.m
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
AppDelegate* delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[delegate showNag];
}
I got it. I had the named GADViewController.h/m files. They made conflict with the GAD framework. The framework also has the same named files. I renamed my files and it works now.
I have a code that checks if an internet connection is there. If there is no internet, I display an alert. Here is the code:
- (void)testInternetConnection
{
__unsafe_unretained typeof(self) weakSelf = self;
internetReachableFoo = [Reachability reachabilityWithHostname:#"www.your-voc.com"];
// Internet is reachable
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
internetActivated = YES;
NSLog(#"Yayyy, we have the interwebs!");
});
};
// Internet is not reachable
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
internetActivated = NO;
if(alertLoaded == NO){
if(weakSelf.isViewLoaded && weakSelf.view.window){
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Pas de connexion internet" message:#"Une connexion est requise pour utiliser l'application" delegate:weakSelf cancelButtonTitle:nil otherButtonTitles:#"Réessayer", #"Mode hors-ligne", nil];
[alert show];
alertLoaded = YES;
}
}
NSLog(#"Someone broke the internet :(");
});
};
[internetReachableFoo startNotifier];
}
I use the isViewLoaded and view.window to be sure to only display the alert if the current window is the one that is loaded and displayed.
But some times, when I shut down the wifi, my simulator crashes with the following error;
-[UIScrollViewDelayedTouchesBeganGestureRecognizer isViewLoaded]: unrecognized selector sent to instance 0x7fbe73da4060
2014-12-05 14:16:57.142 [838:117938] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIScrollViewDelayedTouchesBeganGestureRecognizer isViewLoaded]: unrecognized selector sent to instance 0x7fbe73da4060'
What is wrong?
Thanks a lot
UPDATE: I use Tony Million's version of Reachability, so the testInternetConnection method is called whenever the internet status changes.
Your weakSelf variable is probably a weak pointer and is already released when code reaches this point.
when minimizing the application, all is well, but when I try to deploy the boom going on, this error
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
-(void) applicationDidEnterBackground:(UIApplication *)application
{
NSDate *alertTime = [[NSDate date] dateByAddingTimeInterval:5];
UIApplication* app = [[UIApplication sharedApplication] init];
UILocalNotification* notifyAlarm = [[UILocalNotification alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:kAllNews]];
NSError *error = nil;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
NSError *jsonParsingError = nil;
sortArray = [NSJSONSerialization JSONObjectWithData:response options:0 error:&jsonParsingError];
if (notifyAlarm)
{
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"news"])
{
newsNew = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"news"]];
}
if (newsNew.count > sortArray.count) {
notifyAlarm.fireDate = alertTime;
notifyAlarm.timeZone = [NSTimeZone defaultTimeZone];
notifyAlarm.repeatInterval = 0;
notifyAlarm.soundName = #"Glass.aiff";
notifyAlarm.alertAction = #"Gipoteza";
notifyAlarm.alertBody = #"Добавлена новая новость";
[app scheduleLocalNotification:notifyAlarm];
}
}
}
A couple of suggestions:
First; did you try putting your code in applicationWillResignActive instead?
Why are you getting a reference to UIApplication in your code? You already have that as a parameter to the method...
Try putting breakpoints in your code to see exactly where this error occurs. I would guess it happens on the last line: [app scheduleLocalNotification:notifyAlarm], and that it happens because your notifyAlarm object for some reason is nil. Use your debugger to step through the code to see if that object does indeed get set.
Also; be aware that your code has a maximum of 5 seconds from deactivation until it becomes suspended. When suspended; no code can run. If, for example, your NSURLConnection request for some reason takes long to respond, your app will be suspended before the code is finished.
Request:
- (void) getMyImageWithContestOfFace{
currentApiCall = getMyImageFb;
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"SELECT pic FROM user WHERE uid=me()",#"query",
nil];
AppDelegate *delegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
[[delegate facebook] requestWithMethodName:#"fql.query"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
}
Parsing:
...
case getMyImageFb:{
flag = TRUE;
imageWithFace = [[UIImage alloc] init];
imageWithFace = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[result objectForKey:#"pic"]]]];
}
break;
...
When i call it i catch very strange exeption:
*2011-11-10 00:30:30.661 FaceGraph[1699:f803] I have some information
2011-11-10 00:30:30.664 FaceGraph[1699:f803] -[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x6d3d470
2011-11-10 00:30:30.666 FaceGraph[1699:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x6d3d470'
First throw call stack:
(0x15d9052 0x176ad0a 0x15daced 0x153ff00 0x153fce2 0x254db 0xb6d6 0xbcf7 0xc9ba59 0xc99e94 0xc9aeb7 0xc99e4f 0xc99fd5 0xbdef6a 0x3b8bbbd 0x3c585ea 0x3b82298 0x3c5816b 0x3b82137 0x15ad97f 0x1510b73 0x1510454 0x150fdb4 0x150fccb 0x14c2879 0x14c293e 0x2a6a9b 0x2332 0x22a5)
terminate called throwing an exceptionsharedlibrary apply-load-rules all
Current language: auto; currently objective-c
No idea why. The most strange that i did it before ABSOLUTELY the same, and it worked fine.
I can't find the difference between my old projects and current. Maybe somebody have the same problem?? If you need more code - ask for it.
thanks
Well, the exception seems to be quite clear: result is probably an array and not a dictionary.
PS: The line imageWithFace = [[UIImage alloc] init]; is totally superfluous given the line that follows it. You should remove it.
I forgot to add:
if ([result isKindOfClass:[NSArray class]]){
result = [result objectAtIndex:0];
}
in result-parsing function.