UIAutomation not enabled in Settings error message - ios

When I am writing a tweak application with
[[UIATarget localTarget].frontMostApp isVisible] in main.mm main function, I get the exception saying
* exception UIAutomation is not enabled on this device. UIAutomation must be enabled in Settings. *
But I have Enabled Settings->Developer->Enable Automation UI in device. iOS version:8.1.2 and 8.0.1 jail broken.
int main(int argc, char **argv, char **envp)
{
#autoreleasepool {
#try
{
[[UIATarget localTarget].frontMostApp isVisible];
if ([UIATarget localTarget].springboard.pid == nil)
{
return 0;
}
}
#catch (NSException *exception)
{
NSLog(#"*** exception %# ***",exception);
return 0;
}
}
}
I have seen this link https://github.com/kif-framework/KIF/issues/707 and some Apple reference documents for UIATarget frontMostApp but I found no solution so far.
Is this problem with the iOS version ? How can I solve this? Any help is appreciated.

Your UIAuomation settings plist will be separately created for each application in case of tweaks.
Enable it in /private/var/mobile/Containers/Data/Application/XXXXXXXX-ACAB-4FC9-AE3E-XXXXXX/Library/Preferences/com.apple.UIAutomation.plist and Reboot your device to get rid of this error.

Related

Unit tests with designated AppDelegate crashes on XCode 7

My unit test target crashes on Xcode 7.
I perform unit tests on my project with a designated app delegate class, different from my regular app delegate . The UnitTestAppDelegate is not a member of the app target, only of the test target.
In Xcode 6 it is working, the correct delegate is used, But in Xcode 7 (beta 6) the app crashes when trying to load to test delegate. I test using simulators, both iOS 8 and 9.
The file is not known to the app target:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to instantiate the UIApplication delegate instance. No class named UnitTestAppDelegate is loaded.'
My main.m file looks like this:
int main(int argc, char* argv[])
{
int returnValue;
#autoreleasepool
{
if (NSClassFromString(#"XCTest") != nil)
{
//use the test delegate
returnValue = UIApplicationMain(argc, argv, nil, #"UnitTestAppDelegate");
}
else
{
//use the normal delegate
returnValue = UIApplicationMain(argc, argv, nil, #"AppDelegate");
}
}
return returnValue;
}
I'm also attaching a screen shot of how my scheme is configured (the run and test are in the same scheme, although I also tried separating them).
Adding my UnitTestAppDelegate as a member of the app target fixes the crash, but I obviously don't want to add the file to my app.
Anyone else encountered this?
Any ideas?
See this related comment about the same issue as seen in Xcode 7 beta 6: http://qualitycoding.org/app-delegate-for-tests/#comment-63240

Does any know how to bypass entitlements in iOS 8?

As you aware that the famous _XPConnectionHasEntitlement has no longer works in iOS 8, is there anyother way to bypass the entitlements with the tweaks that requires entitlements? I come to know that _BSAuditTokenTaskHasEntitlement might solve the issue, but I can't get through it.
I'm using following snippet of code to hook into backboardd & assertionsd.
static int (*orig_BSAuditTokenTaskHasEntitlement)(id connection, NSString *entitlement);
static int hooked_BSAuditTokenTaskHasEntitlement(id connection, NSString *entitlement) {
NSLog(#"Got it.");
if (xpc_connection_get_pid(connection) == [[UIDevice currentDevice] __qrwaGetPIDForProcess:#"SpringBoard"] && [entitlement isEqualToString:#"com.apple.multitasking.unlimitedassertions"]) {
return 1;
} else {
return orig_BSAuditTokenTaskHasEntitlement(connection, entitlement);
}
}
%ctor {
%init;
MSHookFunction(((int *)MSFindSymbol(NULL, "_BSAuditTokenTaskHasEntitlement")), (int*) hooked_BSAuditTokenTaskHasEntitlement, (int**) &orig_BSAuditTokenTaskHasEntitlement);
}
The problem with it, the NSLog statements never printed. So I feel that something wrong with syntax of the function _BSAuditTokenTaskHasEntitlement, but not sure.
If anyone points me right direction, I appreciate their help.

iOS - Catching exceptions in main()

So, I had an idea to catch unanticipated exceptions in main and try to cleanup and exit gracefully:
int main(int argc, char *argv[])
{
#autoreleasepool
{
//return UIApplicationMain(argc, argv, nil, NSStringFromClass([GRWAppDelegate class]));
#try
{
int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([GRWAppDelegate class]));
return retVal;
}
#catch (NSException *exception)
{
[Utilities setPreferencesDefaults];
}
}
}
This does catch exceptions and updates the preference defaults.
I then thought, why exit at all, just cleanup and relaunch, so I wrapped everything in a while loop:
int main(int argc, char *argv[])
{
while (YES)
{
#autoreleasepool
{
...
}
}
}
Of course I wouldn't be here if that actually worked. Problem is, once it again executes
retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([GRWAppDelegate class]));
it immediately throws a new exception:
Assertion failure in void UIApplicationInstantiateSingleton(Class)(), /SourceCache/UIKit/UIKit-2380.17/UIApplication.m:2037
NSInternalInconsistencyException
#"There can only be one UIApplication instance."
Makes sense, so is there a way I can discard the existing singleton and replace it with a new one? (although I guess it's not really a singleton if I can)
Purpose is, I don't ever want the app to crash giving a bad user experience. Even if their state isn't completely restored, I would think that would still be better than just unexpectedly exiting.
I can try to handle possible expected exceptions, but this is to try to catch things that I haven't foreseen.
This should really only catch VERY unusual circumstances, so if it can't be done it's not that big of a deal, but I was wondering how best to deal with this type of situation.
That won't work because the exception mechanism does not cleanup properly when thrown across stack frames. Since you are catching the exception in main the exception has crossed several stack frames.
Apple explicitly states that exceptions are only to be used for unrecoverable programming errors.
See SO answer by bbum:
"Any exception that passes through system framework code will leave said framework in an undefined state.. Catching said exceptions and trying to recover from it will lead to memory leaks, undefined behaviour and crashing."
Also by bbum.
From Apple docs:
Important: You should reserve the use of exceptions for programming or unexpected runtime errors such as out-of-bounds collection access, attempts to mutate immutable objects, sending an invalid message, and losing the connection to the window server. You usually take care of these sorts of errors with exceptions when an application is being created rather than at runtime.
You can create a top level exception handler and set it as your default exception handler when you app first launches. The best place to do this would be the AppDelegate's applicationDidFinishLaunching: method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&exceptionHandler);
// some UI configuration here..
return YES;
}
void exceptionHandler(NSException *exception)
{
[Utilities setPreferencesDefaults];
// You can also write exception message into a log file as well.
NSLog(#"Stack trace: %#", [exception callStackReturnAddresses]);
}

Can NSLog be disabled from appearing in device's console? [duplicate]

This question already has answers here:
How do I disable NSLog?
(15 answers)
Closed 8 years ago.
I have a builded application that is running on device. I open device's console view in XCode's Organizer window. I assume (for the sake of this question) that NSLog(#"Some string") gets called.
Is there any way, may be an option in device, or application's settings, that would disable this log from appearing in console?
Edit: I'm not interested in replacing NSLog by other solution that can achieve this effect. The purpose of this question is to fully understand NSLog's functionality.
(Thanks to #MartinR for encouraging me to pull my finger out on this answer and to correctly identify that you cannot just close stdout/stderr, as the next open() will re-use those file descriptors, but to redirect stdout/stderr to the infamous /dev/null).
logControl.h:
#pragma once
extern void stopLogging();
extern void startLogging();
logControl.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static int loggingStopped = 0;
static int oldStdout = -1;
static int oldStderr = -1;
void stopLogging() {
if (!loggingStopped) {
oldStdout = dup(1);
oldStderr = dup(2);
int devNull = open("/dev/null", O_WRONLY);
dup2(devNull, 1);
dup2(devNull, 2);
close(devNull);
loggingStopped = 1;
}
}
void startLogging() {
if (loggingStopped && oldStdout >= 0 && oldStderr >= 0) {
dup2(oldStdout, 1);
close(oldStdout);
oldStdout = -1;
dup2(oldStderr, 2);
close(oldStderr);
oldStderr = -1;
loggingStopped = 0;
}
}
This works at runtime, not compile time, which I believe is what you are asking. Simply call stopLogging() or startLogging() as required.
NOTE: There is no error-checking to speak of, so that could be improved perhaps.
Add this line given below in your .pch file in Xcode.
#define NSLog(...)
It will disable all NSLogs.
for more alternatives see the link
#if TARGET_IPHONE_SIMULATOR
//Simulator
#else
// Device
#define NSLog
#endif
Add this in your .pch file this will disable NSLog only for device alone not for simulator.
Add below code to .pch file
#ifdef DEBUG
# define NSLog(...) NSLog(__VA_ARGS__)
#else
# define NSLog(...) /* */
#endif
And in Build Settings, search "Preprocessor Macros" and remove "DEBUG=1" written in it.
and Thats it, you will not see any logs in your console now.

How can I catch EPIPE in my NSFIleHandle handling?

I'm having a problem with EPIPE in my iOS app, and it's not being caught in the #try/#catch/#finally block. How can I catch this signal (SIGPIPE, likely)...
I've built a "web proxy" into my app that will handle certain kinds of URLs - in this error case, it seems that the remote end (also in my app, but hiding in the iOS libraries) closes its end of the socket. I don't get a notification (should I? Is there something I should register for with the NSFileHandle that might help here?).
I've based this proxy on HTTPServer that Matt Gallagher put together (available here), and the problem is in a subclass of the HTTPRequestHandler class he put together. Here's the code (this code is the equivalent of the startResponse method in the base class):
-(void)proxyTS:(SSProxyTSResource *)proxyTS didReceiveResource:(NSData *)resource
{
NSLog(#"[%# %#]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
CFHTTPMessageRef response =
CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(response,
(CFStringRef)#"Content-Type",
(__bridge CFStringRef)s_MIMEtype);
CFHTTPMessageSetHeaderFieldValue(response,
(CFStringRef)#"Connection",
(CFStringRef)#"close");
CFHTTPMessageSetBody(response,
(__bridge CFDataRef)resource);
CFDataRef headerData = CFHTTPMessageCopySerializedMessage(response);
#try
{
NSLog(#" -> writing %u bytes to filehandle...",[((__bridge NSData *)headerData) length]);
[self.fileHandle writeData:(__bridge NSData *)headerData];
}
#catch (NSException *exception)
{
// Ignore the exception, it normally just means the client
// closed the connection from the other end.
}
#finally
{
NSLog(#" *ding*");
CFRelease(headerData);
CFRelease(response);
[self.server closeHandler:self];
}
}
And here's what shows up in the console log when it crashes:
Jan 15 14:55:10 AWT-NoTouch-iPhone-1 Streamer[1788] <Warning>: [SSProxyTSResponseHandler proxyTS:didReceiveResource:]
Jan 15 14:55:10 iPhone-1 Streamer[1788] <Warning>: -> writing 261760 bytes to filehandle...
Jan 15 14:55:11 iPhone-1 com.apple.launchd[1] (UIKitApplication:com.XXX.Streamer[0xf58][1788]) <Warning>: (UIKitApplication:com.XXX.Streamer[0xf58]) Exited abnormally: Broken pipe: 13
It seems that because the other end closed the pipe the write() fails, so if someone can point me at how I can either discover that it's already closed and not try to write data to it OR whatever will make it not crash my program that would be very helpful.
The immediate problem of crashing with SIGPIPE is solved. I'm not entirely giggly about this solution, but at least the app doesn't crash. It's not clear that it's working 100% correctly, but it does seem to be behaving quite a bit better.
I've resolved this issue by examining further what's going on. In doing some research, I found that perhaps I should be using NSFileHandle's writeabilityHandler property to install a block to do the writing. I'm not fully sold on that approach (it felt convoluted to me), but it might help.
Writability-handler solution:
In doing some web searching on writeabilityHandler, I stumbled on Bert Leung's blog entry on some issues he was having in a similar area. I took his code and modified it as follows, replacing the #try/#catch/#finally block above with this code:
self.pendingData = [NSMutableData dataWithData:(__bridge NSData *)(headerData)];
CFRelease(headerData);
CFRelease(response);
self.fileHandle.writeabilityHandler = ^(NSFileHandle* thisFileHandle)
{
int amountSent = send([thisFileHandle fileDescriptor],
[self.pendingData bytes],
[self.pendingData length],
MSG_DONTWAIT);
if (amountSent < 0) {
// errno is provided by system
NSLog(#"[%# %#] Error while sending response: %d", NSStringFromClass([self class]), NSStringFromSelector(_cmd), errno);
// Setting the length to 0 will cause this handler to complete processing.
self.pendingData.length = 0;
} else {
[self.pendingData replaceBytesInRange:NSMakeRange(0, amountSent)
withBytes:NULL
length:0];
}
if ([self.pendingData length] == 0) {
thisFileHandle.writeabilityHandler = nil;
// Hack to avoid ARC cycle with self. I don't like this, but...
[[NSNotificationCenter defaultCenter] postNotification:self.myNotification];
}
};
That worked fine but it didn't solve the problem. I was still getting SIGPIPE/EPIPE.
SIGPIPE be gone!
This wasn't a surprise, exactly, as this does pretty much the same thing as the former writeData: did but does it using send() instead. The key difference though is that using send() allows errno to be set. This was quite helpful, actually - I was getting a couple of error codes (in errno), such as 54 (Connection reset by peer) and 32 (Broken pipe). The 54's were fine, but the 32's resulted in the SIGPIPE/EPIPE. Then it dawned on me - perhaps I should just ignore SIGPIPE.
Given that thought, I added a couple of hooks into my UIApplicationDelegate in application:didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self installSignalHandlers];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
...
and applicationWillTerminate::
- (void)applicationWillTerminate:(UIApplication *)application
{
// Saves changes in the application's managed object context before the application terminates.
[self removeSignalHandlers];
[self saveContext];
}
-(void)installSignalHandlers
{
signal(SIGPIPE,SIG_IGN);
}
-(void)removeSignalHandlers
{
signal(SIGPIPE, SIG_DFL);
}
Now at least the app doesn't crash. It's not clear that it's working 100% correctly, but it does seem to be behaving.
I also switched back to the #try/#catch/#finally structure because it's more direct. Further, after ignoring SIGPIPE, the #catch block does get triggered. Right now, I'm logging the exception, but only so I can see that it's working. In the released code, that log will be disabled.

Resources