Mục tiêu của tôi là tạo tiện ích mở rộng thực thi định dạng clang. Mã của tôi trông giống như sau:Mở rộng Xcode 8 thực hiện NSTask
- (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler
{
NSError *error = nil;
NSURL *executableURL = [[self class] executableURL];
if (!executableURL)
{
NSString *errorDescription = [NSString stringWithFormat:@"Failed to find clang-format. Ensure it is installed at any of these locations\n%@", [[self class] clangFormatUrls]];
completionHandler([NSError errorWithDomain:SourceEditorCommandErrorDomain
code:1
userInfo:@{NSLocalizedDescriptionKey: errorDescription}]);
return;
}
NSMutableArray *args = [NSMutableArray array];
[args addObject:@"-style=LLVM"];
[args addObject:@"someFile.m"];
NSPipe *outputPipe = [NSPipe pipe];
NSPipe *errorPipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
task.launchPath = executableURL.path;
task.arguments = args;
task.standardOutput = outputPipe;
task.standardError = errorPipe;
@try
{
[task launch];
}
@catch (NSException *exception)
{
completionHandler([NSError errorWithDomain:SourceEditorCommandErrorDomain
code:2
userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Failed to run clang-format: %@", exception.reason]}]);
return;
}
[task waitUntilExit];
NSString *output = [[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile]
encoding:NSUTF8StringEncoding];
NSString *errorOutput = [[NSString alloc] initWithData:[[errorPipe fileHandleForReading] readDataToEndOfFile]
encoding:NSUTF8StringEncoding];
[[outputPipe fileHandleForReading] closeFile];
[[errorPipe fileHandleForReading] closeFile];
int status = [task terminationStatus];
if (status == 0)
{
NSLog(@"Success: %@", output);
}
else
{
error = [NSError errorWithDomain:SourceEditorCommandErrorDomain
code:3
userInfo:@{NSLocalizedDescriptionKey: errorOutput}];
}
completionHandler(error);
}
Lý do tôi cần khối try-catch đó là vì ngoại lệ được ném khi tôi cố gắng chạy mã này. Lý do ngoại lệ là:
Error: launch path not accessible
Đường dẫn cho định dạng clang của tôi là/usr/local/bin/clang-format. Những gì tôi phát hiện ra là nó không giống như tôi đang cố gắng truy cập vào một ứng dụng trong/usr/local/bin, nhưng/bin là ok (ví dụ: Nếu tôi cố gắng thực thi/bin/ls thì không có vấn đề gì).
Một giải pháp tôi đã cố gắng là để chạy/bin/bash bằng cách thiết lập các con đường ra mắt và lập luận như thế này:
task.launchPath = [[[NSProcessInfo processInfo] environment] objectForKey:@"SHELL"];
task.arguments = @[@"-l", @"-c", @"/usr/local/bin/clang-format -style=LLVM someFile.m"];
này sẽ khởi chạy thành công nhiệm vụ, nhưng nó không thành công với sản lượng lỗi sau:
/bin/bash: /etc/profile: Operation not permitted /bin/bash: /usr/local/bin/clang-format: Operation not permitted
Thông báo lỗi đầu tiên là do cố gắng gọi tham số -l trong bash, cố gắng đăng nhập với tư cách người dùng.
Bất kỳ ý tưởng nào về cách tôi có thể bật quyền truy cập vào các thư mục khác? Có một số loại thiết lập môi trường sandbox tôi cần phải kích hoạt?
Tuyệt vời, cảm ơn! Tôi sẽ thử :) –
Nếu công trình này hoạt động, vui lòng đánh dấu nó là câu trả lời được chấp nhận. –