我正在构建一个允许 deb 安装的越狱应用程序。
我坚持在另一个 View Controller 中显示输出或安装过程,类似于 iFile 和 Cydia 自己的安装程序。
有人知道如何让它显示吗?
我目前拥有的是表格 View 、点击文件、弹出操作表要求安装。按安装开始安装过程,同时打开另一个空白 UIView。我如何将该数据传递给打开的 View ?
更新 1 根据要求:
安装 deb 和推送新 View Controller 以显示输出的代码:
//Deb file extension
NSString *debFileExtension = [fileName pathExtension];
NSLog(@"fileExtension is: %@", externalFileExtension);
NSSet *supportedFileExtensions = [NSSet setWithObjects:@"deb", nil];
if ([supportedFileExtensions containsObject:[debFileExtension lowercaseString]]) {
documentController = nil;
NSString *actionSheetTitle = fileName;
BlockActionSheet *sheet = [BlockActionSheet sheetWithTitle:actionSheetTitle];
[sheet addButtonWithTitle:@"Install" block:^{
NSString *appsyncDebPath = [path stringByAppendingPathComponent:fileName];
NSString *cmdString=[NSString stringWithFormat:@"/usr/bin/dpkg -i %@",appsyncDebPath];
const char *cmdChar=[cmdString UTF8String];
system(cmdChar);
DebViewController * vc = [[DebViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
NSLog(@"Install pressed %@", cmdString);
}];
[sheet setDestructiveButtonWithTitle:@"Cancel" block:nil];
[sheet showInView:self.view];
}
由此 DebViewController 被调用。问题是在新 View 中显示输出或日志或 w/e。
常规的 UIView 可以工作吗?或者我需要一个特定的 View 来接收它吗?
更新 2:使用建议的 NSTask。
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 setLaunchPath: @"/usr/bin/dpkg"];
[task1 setArguments: [NSArray arrayWithObjects: @"-i", nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData * data = [file readDataToEndOfFile];
NSString * string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", string);
UITextView *txtview = [[UITextView alloc]initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height)];
txtview.text = string;
//some other setup like setting the font for the UITextView...
[txtview sizeToFit];
[self.view addSubview:txtview];
更新 3: 一切正常!减 1 项。
NSString *debPath = [path stringByAppendingPathComponent:fileName];
NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 setLaunchPath: @"/Applications/myapp.app/"];
[task1 setArguments: [NSArray arrayWithObjects: @"/usr/bin/dpkg", @"-i", debPath, nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData * data = [file readDataToEndOfFile];
OutputViewController * debOutput = [[OutputViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:debOutput];
[self.navigationController presentViewController:vc animated:YES completion:nil];
debOutput.output = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
所以上面提供的代码可以正常工作,接收 View Controller 显示输出。
唯一的问题是,它没有显示 deb 安装的完整输出。几乎就像它缩短了线路一样。我的输出设置如下:
UITextView *l = [[UITextView alloc] initWithFrame:CGRectMake(5, 0, self.view.frame.size.width-5, self.view.frame.size.height)];
l.editable = NO;
l.textAlignment = NSTextAlignmentLeft;
l.font=[UIFont boldSystemFontOfSize:14];
l.textColor = [UIColor whiteColor];
l.backgroundColor = [UIColor colorWithWhite:0.1f alpha:1.0f];
l.text = [NSString stringWithFormat: @"%@", output];
l.textContainer.lineBreakMode = NSLineBreakByWordWrapping;
[l release];
更新 4: 所以我最终做的是在 View 首次显示时在 viewDidLoad 中加载一些文本:
NSString *cmd0 = @"Running Debian Packager";
NSString *cmd1 = @"Executing Command: /usr/bin/dpkg -i";
NSString *cmd2 = @"Preparing - ";
NSString *cmd3 = @"Installing......Please wait...";
l.text = [NSString stringWithFormat:@"%@\n\n%@\n\n%@%@\n\n%@", cmd0, cmd1, cmd2, fileName, cmd3];
l.textContainer.lineBreakMode = NSLineBreakByWordWrapping;
[view addSubview:l];
然后在viewDidAppear中调用deb install进程,将上面的代码替换为输出:
//NSTask
NSString *debPath = [path stringByAppendingPathComponent:vc.fileName1];
NSTask *task1 = [[[NSTask alloc] init] autorelease];
NSPipe *pipe1 = [NSPipe pipe];
[task1 setLaunchPath: @"/Applications/myapp.app/process"];
[task1 setArguments: [NSArray arrayWithObjects:@"/usr/bin/dpkg", @"-i", debPath, @"2>/tmp/dpkg.log" ,nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];
NSFileHandle *file = [pipe1 fileHandleForReading];
NSData *data = [file readDataToEndOfFile];
NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSString *cmd3 = @"Success";
NSString *cmd4 = @"*If this package requires a respring, please do so above*";
NSString *dependencies = @"*You are seeing this message because this package requires the additional dependencies listed above*";
NSString *closeCydia = @"*If you are seeing this message, Cydia is probably open. Please close, and try to install the package again*";
//DPKG LOG FILE
NSError *error;
NSString *logPath = [NSString stringWithFormat:@"/tmp"];
NSString *dpkgLogFile = [logPath stringByAppendingPathComponent:@"dpkg.log"];
NSString *logContents = [NSString stringWithContentsOfFile:dpkgLogFile encoding:NSUTF8StringEncoding error:&error];
NSString *dependsString = @"dpkg: dependency problems";
NSString *lockString = @"dpkg: status database area is locked by another process";
if ([logContents containsString:lockString]) {
l.text = [NSString stringWithFormat:@"%@\n%@", logContents, closeCydia];
self.navigationController.navigationBar.topItem.rightBarButtonItem = nil;
}else if ([logContents containsString:dependsString]){
l.text = [NSString stringWithFormat:@"%@\n%@\n%@", string, logContents, dependencies];
self.navigationController.navigationBar.topItem.rightBarButtonItem = nil;
}else{
l.text = [NSString stringWithFormat:@"%@\n%@%@\n\n%@", string, logContents, cmd3, cmd4];
}
[view addSubview:l];
根据 deb 安装的内容,我自定义了输出,即它是否依赖,或者进程是否因为 Cydia 打开而被锁定。
总而言之,我对投票率感到满意。感谢 Nate 指导使用 NSTask,效果非常好。
唯一让它变得更好的方法是打印或读出它,类似于 Cydia 逐行处理的方式。
最佳答案
我建议使用 NSTask
来运行命令,而不是使用 system()
命令来运行 dpkg
命令行,可以更轻松地将输出捕获为 NSString
。一旦你有了一个字符串,你就可以将它复制到 TextView 中,或者任何你喜欢的地方。
NSTask
是 iOS 上的私有(private) API,但它在 OS X 上是公开的,因此有很多可用的文档。为了在您的项目中使用它,只需找到 NSTask.h header 的副本并将其复制到您的项目中(当然还有 #import
它)。
Here's an example of using NSTask to capture command line output在 UIApplication
中。
或者,another one .
如果您的安装过程可能需要一段时间,并且您希望您的 UI 在运行时响应,那么最好在后台运行执行任务的方法(例如使用 GCD) ,然后将生成的字符串写回主/UI 线程上的 UIView
(文本字段等)。
关于ios - 如何显示 deb install ios 的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361126/