2016-09-09 9 views
9

내 목표는 clang 형식을 실행하는 확장 프로그램을 만드는 것입니다. 내 코드는 다음과 같은 :Xcode 8 extension 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); 
} 

나는이 코드를 실행하려고 할 때 예외가 발생하기 때문에 그 시도-catch 블록이 필요한 이유. 예외 이유는 다음과 같습니다.

Error: launch path not accessible

내 clang 형식의 경로는/usr/local/bin/clang 형식입니다. 내가 발견 한 사실은/usr/local/bin에있는 응용 프로그램에 접근하려고하는 것을 좋아하지 않는다는 것입니다. 그러나/bin은 괜찮습니다 (예 :/bin/ls를 실행하려고해도 문제가 없습니다).

해봤 또 다른 방법이었다 발사 경로 및 인수 같은 설정/빈/bash는 실행이 성공적으로 작업을 시작

task.launchPath = [[[NSProcessInfo processInfo] environment] objectForKey:@"SHELL"]; 
task.arguments = @[@"-l", @"-c", @"/usr/local/bin/clang-format -style=LLVM someFile.m"]; 

을하지만, 다음과 같은 오류 출력 실패

/bin/bash: /etc/profile: Operation not permitted /bin/bash: /usr/local/bin/clang-format: Operation not permitted

첫 번째 오류 메시지는 사용자로 로그인을 시도하는 bash에서 -l 매개 변수를 호출하려고했기 때문입니다.

다른 폴더에 어떻게 액세스 할 수 있습니까? 사용하도록 설정해야하는 샌드 박스 환경 설정이 있습니까?

답변

1

나는 sandboxing 때문에 이것이 불가능하다고 생각합니다. clang 형식 실행 파일을 번들로 사용하여 거기에서 사용할 수 있습니다.

0

개인적으로 나는 완전히 잘못 생각한 것 같습니다. 확장 프로그램은 빠르다고합니다 (Xcode 확장 프로그램에서 동영상을 볼 때 여러 번 반복해서 들어 와서 나옵니다). 그리고 그들은 심각하게 제한되어 있습니다.

그러나 컨테이너 앱이 모든 해킹없이 확장을 위해이 처리를 수행 할 수도 있습니다. 단점은 버퍼를 내선과주고 받아야한다는 것입니다.

쉽지는 않지만 할 수 있습니다. 귀하의 컨테이너를 실행하는 쉬운 peasy 방법. 먼저 URL 유형이 포함되도록 컨테이너 앱의 Info.plist (Info.plist 확장이 아닌)를 수정하십시오. 확장에

Info.plist

는 다음을 실행하여 컨테이너 응용 프로그램을 "일어나"할 수 있습니다

let customurl = NSURL.init(string: “yoururlschemehere://") 
NSWorkspace.shared().open(customurl as! URL) 

둘 사이의 통신에 관해서는, 애플이 방법의 과다있다. 나, 나는 옛날 학교 다. 그래서 나는 DistributedNotificationCenter를 사용하고있다.

아직 시도하지는 않았지만 왜 컨테이너 앱에 clang과 채팅하는 데 문제가 있는지 알 수 없습니다. 설정에 컨테이너 앱을 사용하고 있습니다.

+0

굉장합니다, 감사합니다! 시도해 보겠습니다. –

+0

이것이 작동하는 경우 허용되는 답변으로 표시하십시오. –