2016-09-09 15 views
9

निष्पादित करना मेरा लक्ष्य क्लैंग-प्रारूप निष्पादित करने वाला एक्सटेंशन बनाना है। मेरे कोड इस तरह दिखता है:एक्सकोड 8 एक्सटेंशन एनएसटीस्क

- (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); 
} 

कारण मैं जरूरत है क्योंकि एक अपवाद फेंक दिया जाता है जब मैं इस कोड चलाने का प्रयास है कि कोशिश-कैच ब्लॉक है। अपवाद कारण है:

Error: launch path not accessible

मेरी बजना प्रारूप के लिए पथ/usr/स्थानीय/bin/बजना-स्वरूप है। मैंने जो खोजा है वह यह है कि मुझे/usr/local/bin में किसी एप्लिकेशन तक पहुंचने का प्रयास नहीं करना चाहिए, लेकिन/bin ठीक है (उदा। अगर मैं निष्पादित करने की कोशिश करता/bin/ls कोई समस्या नहीं है)।

एक अन्य समाधान मैंने कोशिश की थी इस तरह लांच पथ और तर्क की स्थापना करके चलाने के लिए/bin/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

पहला त्रुटि संदेश बैश में -l पैरामीटर को कॉल करने का प्रयास करने के कारण है, जो उपयोगकर्ता के रूप में लॉग इन करने का प्रयास करता है।

कोई विचार है कि मैं उन अन्य फ़ोल्डरों तक पहुंच कैसे सक्षम कर सकता हूं? क्या मुझे कुछ प्रकार की सैंडबॉक्स पर्यावरण सेटिंग सक्षम करने की आवश्यकता है?

उत्तर

1

मुझे लगता है कि सैंडबॉक्सिंग के कारण यह संभव नहीं है। आप क्लैंग-प्रारूप निष्पादन योग्य बंडल कर सकते हैं और वहां से इसका उपयोग कर सकते हैं।

0

व्यक्तिगत रूप से, मुझे लगता है कि आप इसे सब गलत कर रहे हैं। एक्सटेंशन त्वरित होने चाहिए (यदि आप एक्सकोड एक्सटेंशन पर वीडियो देखते हैं तो वह अंदर आने और बाहर निकलने के लिए कई बार दोहराता है)। और वे गंभीर रूप से सीमित हैं।

हालांकि, एक और है - कंटेनर ऐप सभी हैक्स के बिना आपके एक्सटेंशन के लिए यह प्रसंस्करण करने में सक्षम हो सकता है। नकारात्मकता यह है कि आपको विस्तार से और बफर को पास करना होगा।

यह आसान नहीं है, लेकिन यह किया जा सकता है। अपने कंटेनर को चलाने के लिए आसान peasy तरीका। सबसे पहले, कंटेनर ऐप की Info.plist (एक्सटेंशन Info.plist नहीं) को संशोधित करें ताकि उसके पास एक यूआरएल प्रकार हो।

Info.plist

अपने विस्तार में आप निम्न चलाकर कंटेनर एप्लिकेशन "जाग" कर सकते हैं:

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

दोनों के बीच संचार के लिए के रूप में, एप्पल ढेर सारे तरीकों के है। मैं, मैं पुराना स्कूल हूं, इसलिए मैं इस समय के लिए वितरित नोटिफिकेशन सेंटर का उपयोग कर रहा हूं।

हालांकि मैंने कोशिश नहीं की है, मुझे नहीं लगता कि क्यों कंटेनर ऐप को क्लैंग के साथ चैट करने का मुद्दा होना चाहिए (मैं सेटिंग्स के लिए कंटेनर ऐप का उपयोग कर रहा हूं)।

+0

बहुत बढ़िया, धन्यवाद! मैं इसे आज़मा दूंगा :) –

+0

यदि यह काम करता है, तो कृपया इसे स्वीकृत उत्तर के रूप में चिह्नित करें। –

संबंधित मुद्दे