2012-08-09 78 views
2

由于iPhone是沙盒应用程序,我无法访问/bin/文件夹。所以我使用SSH连接从iPhone获取/bin/date二进制文件,并将其包含在我的项目中。当我使用NSLog打印时,我的文件路径是正确的:/var/mobile/Applications/95078888-DDA8-4C1E-93DC-1F9E0A26E70A/Documents/date。我遇到的问题列在下面。有谁知道我可以如何解决这个错误?注意:如果我在模拟器中运行它,并使用此代码执行与Mac OSX兼容的任何二进制文件,但是当我尝试使用iPhone二进制文件在设备上运行它时,它会导致出现问题。在越狱iPhone上执行二进制文件

错误:

2012-08-09 14:23:13.757 TestBinary[7891:707] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'couldn't fork: errno 1'

First throw call stack: (0x359b388f 0x335d7259 0x359b3789 0x359b37ab 0x34deb915 0xda5af 0x3590d3fd 0x330cee07 0x330cedc3 0x330ceda1 0x330ceb11 0x330cf449 0x330cd92b 0x330cd319 0x330b3695 0x330b2f3b 0x336a522b 0x35987523 0x359874c5 0x35986313 0x359094a5 0x3590936d 0x336a4439 0x330e1cd5 0xd9ecd 0xd9e98)

terminate called throwing an exception

Program received signal: “SIGABRT”. Data Formatters temporarily unavailable, will re-try after a 'continue'. (Can't find dlopen function, so it is not possible to load shared libraries.)

mi_cmd_stack_list_frames: Not enough frames in stack.

mi_cmd_stack_list_frames: Not enough frames in stack.

代码调用号文件:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 

NSString *path = [NSString stringWithFormat:@"%@/date", documentsDirectory]; 

NSLog(@"%@", path); 

NSTask *task = [[NSTask alloc] init]; 
[task setLaunchPath: path]; 

NSPipe *pipe; 
pipe = [NSPipe pipe]; 
[task setStandardOutput: pipe]; 

NSFileHandle *file; 
file = [pipe fileHandleForReading]; 

[task launch]; 

NSData *data; 
data = [file readDataToEndOfFile]; 

NSString *string; 
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 

label.numberOfLines=0; 
label.text = string; 

[string release]; 
[task release]; 

我NSTask文件:

#import <Foundation/NSObject.h> 

@class NSString, NSArray, NSDictionary; 

@interface NSTask : NSObject 

- (id)init; 

- (void)setLaunchPath:(NSString *)path; 
- (void)setArguments:(NSArray *)arguments; 
- (void)setEnvironment:(NSDictionary *)dict; 
- (void)setCurrentDirectoryPath:(NSString *)path; 
- (void)setStandardInput:(id)input; 
- (void)setStandardOutput:(id)output; 
- (void)setStandardError:(id)error; 

- (NSString *)launchPath; 
- (NSArray *)arguments; 
- (NSDictionary *)environment; 
- (NSString *)currentDirectoryPath; 

- (id)standardInput; 
- (id)standardOutput; 
- (id)standardError; 

- (void)launch; 

- (void)interrupt; 
- (void)terminate; 

- (BOOL)suspend; 
- (BOOL)resume; 

- (int)processIdentifier; 
- (BOOL)isRunning; 

- (int)terminationStatus; 

@end 

@interface NSTask (NSTaskConveniences) 

+ (NSTask *)launchedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)arguments; 

- (void)waitUntilExit; 

@end 

FOUNDATION_EXPORT NSString * const NSTaskDidTerminateNotification; 
#endif 

编辑1:

我用下面的目录解压缩:https://github.com/samsoffes/ssziparchive

这是我的代码来解压缩并执行:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 

NSString *path2 = [[NSBundle mainBundle] pathForResource:@"date" ofType:@"zip"]; 
[SSZipArchive unzipFileAtPath: path2 toDestination:documentsDirectory]; 

NSString *path = [NSString stringWithFormat:@"%@/date", documentsDirectory]; 

NSFileManager* fileManager = [NSFileManager defaultManager]; 
NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:[fileManager attributesOfItemAtPath:path error:nil]]; 

[attributes setValue:[NSNumber numberWithShort: 0777] 
       forKey:NSFilePosixPermissions]; 
NSError* err; 
[fileManager setAttributes: attributes ofItemAtPath: path error: &err]; 

NSTask *task = [[NSTask alloc] init]; 
[task setLaunchPath: path]; 

NSPipe *pipe; 
pipe = [NSPipe pipe]; 
[task setStandardOutput: pipe]; 

NSFileHandle *file; 
file = [pipe fileHandleForReading]; 

[task launch]; 

NSData *data; 
data = [file readDataToEndOfFile]; 

NSString *string; 
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 

label.numberOfLines=0; 
label.text = string; 

[string release]; 
[task release]; 
+0

这没有回答我的问题。首先,我的设备已经越狱了,这是答案的一半,并且他们明确指出,如果您移植了头文件,那么它应该适用于iOS,尽管它不受Apple支持。我可以使用这个NSTask在其他文件上设备,他们工作正常。它只是我遇到的问题。 – MrHappyAsthma 2012-08-09 19:25:28

回答

1

我不知道究竟为什么正在发生的事情,但是当Xcode的构建,它以某种方式破坏date二进制文件。如果你看一下原来的date文件(项目文件夹下),然后找到Xcode的构建目录下的同一个文件(例如):

/Users/myusername/Library/Developer/Xcode/DerivedData/HelloJB-gsokzlpnejddadbccgrfkxnumkyl/Build/Products/Release-iphoneos/HelloJB.app 

你可以在这两个文件运行diff命令,它会告诉你这些二进制文件不同。这足以导致这个问题。

由于某种原因,Xcode正在寻找这种类型的资源,并为此做了一些事情。例如,我知道它试图在您的应用程序的png资源上使用某种pngcrush实用程序。也许这是相似的。

无论如何,我发现解决这个问题的一种方法是在您的Mac上压缩date文件。然后,在项目中包含date.zip作为捆绑资源。清理并建立。 Xcode不会破坏压缩文件。现在

,当你的应用程序启动时,它需要从它的捆绑资源解压date.zip文件,并存储解压缩后的版本文件,或缓存,或任何你想要它。您可能还需要记住设置执行权限。

See this for programmatically unzipping files

更新:

之后,你可能需要设置该文件具有可执行权限。像这样:

NSFileManager* fileManager = [NSFileManager defaultManager]; 
NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init]; 
NSNumber* permission = [NSNumber numberWithLong: 0755]; 
[attributes setObject:permission forKey: NSFilePosixPermissions]; 
NSError* err; 
[fileManager setAttributes: attributes ofItemAtPath: filePath error: &err]; 
+0

我使用该链接的zip函数,并且解压缩的很好,但我认为该文件在解压缩时不可执行。如何从应用内更改文件权限? (我只是将它解压缩到文档目录中)。 – MrHappyAsthma 2012-08-15 17:15:01

+0

@MHHappyAsthma,请参阅我上面的更新。 – Nate 2012-08-17 02:05:16

+0

这确实更改了权限。它导致文件根据终端“ls -al”可执行,但是我仍然得到以下错误:“由于未捕获异常'NSInternalInconsistencyException',原因:'could not fork:errno 1'”终止应用程序“。 *注意:这是在设备上。 – MrHappyAsthma 2012-08-19 15:56:45