Reachability Runtime error - SCNetworkReachabilitySetDispatchQueue() failed: Permission denied - iphone

Here is my code:
Reachability *r = [Reachability reachabilityWithHostname:host];
r.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
});
};
r.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread with error alert
});
};
[r startNotifier];
Upon running the last statement, I get following error logged, and it never executes any of the reachableBlock or unreachableBlock.
SCNetworkReachabilitySetDispatchQueue() failed: Permission denied
For anyone wanting to know what I tried already, I also attempted this:
dispatch_async(dispatch_get_global_queue(0,0), ^{
[r startNotifier];
});
But this yields same result.
I logged an issue here.

This is no longer an issue.
By some mysterious reasons, I cleaned up build folder, reset iOS simulator, relaunched it and recompiled - and the error is gone. I didn't succeed following these steps at first, but doing them just for the sake of trying, and it worked!

Related

TestFlight TFLog not uploading when there is a crash

When TestFlight crashes I have a log I wish to upload with its crash report.
Following the instructions on their website I came up with this solution, but it doesn't seem to be sending the log I pass to TFLog. However it reports the crash just fine.
-(void)applicationDidFinishLaunching:(UIApplication *)application {
/*Setup crash handlers for TestFlight so we can send logs. */
NSSetUncaughtExceptionHandler(&testFlightHandleExceptions);
// create the signal action structure
struct sigaction newSignalAction;
// initialize the signal action structure
memset(&newSignalAction, 0, sizeof(newSignalAction));
// set SignalHandler as the handler in the signal action structure
newSignalAction.sa_handler = &testFlightSignalHandler;
// set SignalHandler as the handlers for SIGABRT, SIGILL and SIGBUS
sigaction(SIGABRT, &newSignalAction, NULL);
sigaction(SIGILL, &newSignalAction, NULL);
sigaction(SIGBUS, &newSignalAction, NULL);
[TestFlight takeOff:TESTFLIGHT_API_KEY];
}
void testFlightHandleExceptions(NSException *exception) {
[LogManager e: #"Sending crash to TestFlight" Tag:#"AppDelegate"];
TFLog(#"%#",[LogManager getLog]);
}
Where have I gone wrong? Or is there a better way in doing this?
There are two problems I can see with this:
testFlightHandleExceptions is going to be called after the crash and it's logs are recorded. Instead you need to be calling TFLog inside of LogManager every time you log something (before the crash). That's how it's meant to be used.
It is not ok to use objc inside of a signal handler. For that matter, most c isn't even allowed.
Hope that helps :)
Jason

clang failed with exit code 1 error

I have downloaded a sample code of OpenEars form the web, in that at a place these statements were using:
#autoreleasepool {
…
}
which was giving error: Unexpected '#' in program, then I replaced these lines of code with:
NSAutoreleasePool *pool = [NSAutoreleasePool new];
…
[pool drain];
and now I am getting error: "clang failed with exit code 1 error".
Does any one know how to solve this?
I am using XCode 3.2.5
You definitely want to go back to #autoreleasepool{} but it sounds like the issue is in the compiler/arguments though. That may be difficult to debug, depending on how old the project was. Are you using the latest Xcode, and if so, can you "upgrade project settings"?

Speakhere does NOT record after receive a phone call

I'm working on a project that need record and analyze sound, every think is ok when i use speak here.
But when some one call my phone, the record stop and when the app return, it never record again.
I try to restart the recorder by press record, but i get this error:
Error: couldn't get input channel count ('!cat')
Error: couldn't enable metering (-50)
ERROR: metering failed
I also try to restart by call StartRecord(....) but nothing different. So anyone can help me
if (inInterruptionState == kAudioSessionEndInterruption)
THIS->recorder->StartRecord(CFSTR("recordedFile.caf"));
An app must stop recording in any audio session interrupt listener begin interruption callback if it ever wants to start recording again. Otherwise, a force quit and restart by the user may be required.
I've been having the same problem with SpeakHere and found this solution by (hours and hours of) trial and error. Try this: get rid of the references to playbackWasInterrupted (commented out below), but leave in the other player-related directives. Somehow this re-enables the recorder! If anyone could explain why this works, I would love to know!
Under void interruptionListener, change
else if ((inInterruptionState == kAudioSessionEndInterruption)&& THIS->playbackWasInterrupted))
to
else if (inInterruptionState == kAudioSessionEndInterruption)
//&& THIS->playbackWasInterrupted)
and then comment out or delete the "playbackWasInterrupted" line below:
{
// we were playing back when we were interrupted, so reset and resume now
THIS->player->StartQueue(true);
[[NSNotificationCenter defaultCenter] postNotificationName:#"playbackQueueResumed" object:THIS];
// THIS->playbackWasInterrupted = NO;
}
just from memory - when returning to foreground (in the corresponding notification handler), you need to call
AudioSessionSetActive (true)
or something similar. As I said, I only read it on a related question - no garanties.
Good Luck, nobi

iPhone Socket gets closed unexpected

Well at least unexpected for me... This is the situation:
I open a Socket using the following code:
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)ipaddress , 3333,&readStream, &writeStream);
if(!CFReadStreamOpen(readStream) || !CFWriteStreamOpen(writeStream))
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection error"
message:#"There has been a connection error, please ensure your internet connection is working"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return;
}
This all goes fine, next thing I do is setup a callback:
CFStreamClientContext ctxt = {0,(void*)NULL,NULL,NULL,NULL};
static const CFOptionFlags kReadNetworkEvents = kCFStreamEventEndEncountered |
kCFStreamEventErrorOccurred |
kCFStreamEventHasBytesAvailable |
kCFStreamEventOpenCompleted |
kCFStreamEventNone;
CFReadStreamSetClient(readStream, kReadNetworkEvents, ReadStreamClientCallBack, &ctxt);
CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
Also works fine, I'll list the callback method to be complete:
static void ReadStreamClientCallBack( CFReadStreamRef stream, CFStreamEventType type, void *clientCallBackInfo ) {
switch (type)
{
case kCFStreamEventEndEncountered:
{
break;
}
case kCFStreamEventErrorOccurred:
break;
case kCFStreamEventHasBytesAvailable:
{
[this stopListen];
UInt8 buffer[1024];
int count = CFReadStreamRead(stream, buffer, 1024);
CFStreamStatus status = CFReadStreamGetStatus(this.readStream);
CFErrorRef error = CFReadStreamCopyError (this.readStream);
CFStringRef errorCode = CFErrorCopyDescription(error);
// Bunch of other irrelevant code
Now what goes wrong: All this code works perfectly fine as long as I'm staying in the application, even if I exit the application and enter it again it works still fine. If I enter standby while the application is open it also works fine. However if I exit the application, put my phone on standby, get my phone out of standby and reenter the application, the call back immediatly gets called, with eventtype kCFStreamEventHasBytesAvailable, even though I'm 100% sure no bytes have been send. If I then call CFReadStreamRead it returns -1 to me, since this means an error occured I figured out the error code which is 57, this mean that the socket has been closed.
Am I overlooking a certain aspect of socket programming on the iPhone? I must admit I'm new to it. Is it not possible to keep a TCP Socket open while out of the application (and entering standby)?
I have tried to call CFReadStreamOpen again which returned false to me.
I'm lost here, please help!
Thanks in advance
Part of the multi-tasking features in 4.0+ require extra coding to support keeping connections alive and performing tasks in the background. You are probably just a victim of the OS taking back those resources since you didn't "opt-in" for them at the appropriate time.
This section covers the basics of backgrounding:
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
Specifically this:
Be prepared to handle connection
failures in your network-based
sockets. The system may tear down
socket connections while your
application is suspended for any
number of reasons. As long as your
socket-based code is prepared for
other types of network failures, such
as a lost signal or network
transition, this should not lead to
any unusual problems. When your
application resumes, if it encounters
a failure upon using a socket, simply
reestablish the connection.
However, there are three very special things that you can do in the background, and if you do you should declare them in your Info.plist to be a good App citizen. These three values are in the UIBackgroundModes property and they are audio location and voip
You can request more time for your task by registering a block (even though it isn't guarunteed you'll get it) like this:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
See also A Short Practical Guide to Blocks for a quick overview and the Concurrency Programming Guide for more detailed information.

Using Reachability for Internet *or* local WiFi?

I've searched SO for the answer to this question, and it's not really addressed, at least not to a point where I can make it work.
I was originally only checking for Internet reachability, using:
self.wwanReach = [Reachability reachabilityWithHostName:#"www.apple.com"];
[wwanReach startNotifer];
I now need to support a local WiFi connection (in the absence of reaching the Internet in general), and when I found +reachabilityForLocalWiFi, I also noticed there was +reachabilityForInternetConnection. I figured I could use these, instead of hard-coding "www.apple.com" in there, but alas, when I use:
self.wwanReach = [Reachability reachabilityForInternetConnection];
[wwanReach startNotifer];
self.wifiReach = [Reachability reachabilityForLocalWiFi];
[wifiReach startNotifer];
the reachability callback that I've set up "never" gets called, for values of "never" up to 10, 12, 15 minutes or so (which was as long as my patience lasted. (User's patience will be much less, I'm sure.) Switching back to +reachabilityWithHostName: works within seconds. I also tried each "pair" individually, in case there was an issue with two notifiers in progress simultaneously, but that made no difference.
So: what is the appropriate way to determine reachability to either the Internet/WWAN or a local Wifi network (either one, or both)?
[This particular use case is an iPhone or iPad connecting to a Mac mini computer-to-computer network; I'm sure other situations apply.]
Use this function to check if wifi is on
- (BOOL)isWifiOn {
Reachability* wifiReach = [Reachability reachabilityForLocalWiFi];
NetworkStatus netStatus = [wifiReach currentReachabilityStatus];
return (netStatus==ReachableViaWiFi);
}
similar code can be used to check reachabilityForInternetConnection but you have to check
(netStatus==ReachableViaWiFi)
if you care that it's over wifi AND
(netStatus==ReachableViaWWAN)
if you care that it's over WWAN
I ran int the same problem. What I found in the end is that for WWAN or WiFi reachability, the notification callback is only called when there is a network change.
In other words, check the current reachability immediately after you create the reachability object. Do not wait for the notification, because the notification will only be posted when next network change happens.
For Internet/WWAN:
self.wwanReach = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [wwanReach currentReachabilityStatus];
if (networkStatus == ReachableViaWWAN) {
// do something
}
For WiFi:
self.wifiReach = [Reachability reachabilityForLocalWiFi];
NetworkStatus networkStatus = [wifiReach currentReachabilityStatus];
if (networkStatus == ReachableViaWiFi) {
// do something
}
The reachability example from apple shows you how to use a notification, which is an event push model and supposed to be efficient, but I found that the notifications weren't always working properly for me. Sometimes they wouldn't fire, other times they would provide wrong information. So I ended up polling with a 2 second repeating timer, and checking for wifi with a procedure like the one described by stinkbutt above. Here's a good reference for timer implementation.
I'm not sure if this is your problem, but I noticed that it matters when you call startNotifier. I was having a similar problem with never receiving notifications (but with shorter values for "never" -- I guess I'm not as paitent) until I moved the startNotifier call into some UI code, specifically applicationDidFinishLaunching.