ios - 如何显示 deb install ios 的输出

标签 ios objective-c uiview jailbreak deb

我正在构建一个允许 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 outputUIApplication 中。

或者,another one .

如果您的安装过程可能需要一段时间,并且您希望您的 UI 在运行时响应,那么最好在后台运行执行任务的方法(例如使用 GCD) ,然后将生成的字符串写回主/UI 线程上的 UIView(文本字段等)。

关于ios - 如何显示 deb install ios 的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361126/

相关文章:

ios - 无法在Ionic 3中添加iOS平台

iphone - 在 objective-c(iphone 版本)中做观察者/可观察者的最好方法是什么

ios - 如何通过标签访问 NSMutablearray 中的对象?

ios - 无法保存与扩展程序共享的网址

iphone - 如何在绘图应用程序中撤消和重做操作

iPhone截图从后台返回全白

ios - 在html中更改默认字体颜色创建NSAttributedString

ios - 同时对两个 UIView 进行动画处理(粘在一起)

iPhone iOS 如何将 UILongPressGestureRecognizer 和 UITapGestureRecognizer 添加到同一个控件并防止冲突?

ios - SwiftUI View 无法正确呈现为UIImage