2013-05-23 1 views
4

Objective-C로 작성한 내 OS X 응용 프로그램으로 파일을 여는 방법을 알고 싶습니다. Info.plist에 파일 형식을 등록했고 코드에 application:openFile:이 있습니다. 나는 해결 된 것으로 표시되었던 this post에 의해 모든 것을했다.objective-c로 작성된 자신의 응용 프로그램으로 파일 열기

문제는 응용 프로그램이 실행되는 동안 내 파일을 끌어서 놓는 경우에만 작동한다는 것입니다. 하지만 파일을 두 번 클릭하면 작동하지 않습니다. 그것은 내 응용 프로그램을 시작하지만 끌어서 놓기 만하면 시작되지 않습니다. 따라서 application:openFile:에있는 코드는 두 번 클릭 할 때 실행되지 않지만 파일을 드래그 앤 드롭 할 때만 실행됩니다.

편집 :

내 코드, 그리고 내가 무엇을 달성하기 위해 노력하고 대한 좀 더 세부 사항. 다른 앱에 대한 래퍼 애플리케이션을 만들었습니다. 다른 앱을 "HelperApp.app"라고 부르 자. 이 HelperApp는 내 래퍼 앱의 /Contents/ 폴더 안에 있습니다. 래퍼 앱에서 새로운 파일 유형을 지정 했으니 Info.plist 파일에서 ".ha"라고 부르 자. 이 파일에는 몇 가지 인수 명령이 들어 있습니다. 사용자가 ".ha"파일 인 파일을 클릭하면 래퍼 응용 프로그램이이 파일의 인수를 읽고 HelperApp를 설정 한 다음 HelperApp를 시작합니다. 이 HelperApp는 인수에 따라 다른 것들을 열어 놓고 있습니다. 아래에서 내 코드를 확인할 수 있습니다.

나는 최신 Xcode가 어떻게 그것을 창조하는지 디폴트로 AppDelegate.hAppDelegate.mm가있다. 난 그냥 "@end"전에 내 AppDelegate.h이 라인을 추가 :

- (BOOL)processFile:(NSString *)file; 

나는 이러한 기능을 가지고 내 AppDelegate.mm :

#import "AppDelegate.h" 
#import "ArgumentParser.h" 

@implementation AppDelegate 

- (void)dealloc 
{ 
    [super dealloc]; 
} 

- (BOOL)application:(NSApplication *)WrapperApp openFile:(NSString *)filename 
{ 
    return [self processFile:filename]; 
} 

- (BOOL)processFile:(NSString *)file 
{ 
    NSLog(@"The following file has been dropped or selected: %@",file); 

    std::string path = [file cStringUsingEncoding:[NSString defaultCStringEncoding]]; 

    ArgumentParser parser = ArgumentParser(); 
    parser.getArgumentfromFile(path); 
    parser.setArgumentinFile();  // <== This is the "corrupted" function 

    NSBundle *mainBundle = [NSBundle mainBundle]; 
    NSString *helperAppPath = [[mainBundle bundlePath] 
          stringByAppendingString:@"/Contents/HelperApp.app"]; 
    [[NSWorkspace sharedWorkspace] launchApplication:helperAppPath]; 

    return YES; 
} 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    // Insert code here to initialize your application 
} 

손상된 기능 - setArgumentinFile() :

void ArgumentParser::setArgumentinFile() { 
    std::string content = ""; // The file content 
    std::fstream file; 

    file.open("HelperApp.app/Contents/Wrapper/HelperApp.app/Contents/Info.plist"); 

    // Open the file and modify the arguments 
    if(file.is_open()) { 
     std::stringstream stream; 
     stream << file.rdbuf(); 

     std::string line = ""; 
     bool isIt = false; 

     while(getline(stream, line)) { 
      // This line is the argument list, which needs to be modifyed 
      if(isIt) { 
       int index = (int)line.find_last_of("<"); 
       std::string start = line.substr(0, index); 
       std::string end = line.substr(index, std::string::npos); 
       std::string argument_list = start + " " + _argument + end; 
       content += argument_list + '\n'; 
       isIt = false; 
      } 
      // Save the rest of the file so we can overwrite it 
      else { 
       content += line + '\n'; 
      } 
      // Next line is the argument list 
      if(line.find("WineProgramArguments") != std::string::npos) { 
       isIt = true; 
      } 
     } 

     file.flush(); 
     file.close(); 
    } 
    else { 
     file.flush(); 
     file.close(); 
     throw std::runtime_error("File isn't opened"); 
    } 


    file.open("HelperApp.app/Contents/Wrapper/HelperApp.app/Contents/Info.plist", std::ios::out); 

    // Open the file and overwrite it with the modifyed argument 
    if(file.is_open()) { 
     file << content; 

     file.flush(); 
     file.close(); 
    } 
    else { 
     file.flush(); 
     file.close(); 
     throw std::runtime_error("File isn't opened"); 
    } 
} 

processFile 함수에서 위의 함수를 AppDelegate에 주석 처리하면 모든 것이 "부드럽게"작동합니다. 래퍼 앱이 시작되고 HelperApp가 기본 인수로 시작된다는 의미입니다. 그래서 여기에 오류가 있어야합니다 ...

+0

이전 사본을 실행 중입니다. 내 솔루션을 참조하십시오. –

답변

0

문제는 내 기능에서 잘못된 경로를 부여했기 때문입니다. Xcode에서 앱을 시작한 경우이 경로가 작동했지만 앱을 단독으로 시작한 경우에는 작동하지 않았습니다.

여기 내 문제를 해결 한 post입니다!

4

-application:openFile:을 구현 한 경우 등록한 유형의 파일을 두 번 클릭 할 때이 파일을 호출해야합니다. 앱이 실행된다고 말하면 OS가 앱을 사용하여 파일을 열려고합니다. openFile : 아래 applicationDidFinishLaunching를 받기 전에 메시지 :. 사용자가 두 번 클릭하여 파일의 대리인이 응용 프로그램을 수신하는 응용 프로그램을 시작한 경우

다음은 문서에서 유용한 참고입니다 (applicationWillFinishLaunching : 응용 프로그램 전에 을 전송됩니다 openFile :를) 당신이 파일을 열기 전에 수행해야합니다 -applicationDidFinishLaunching:에서 아무것도하는 경우

그래서, 그 문제가 될 수 있습니다. 앱 초기화 코드를 -applicationWillFinishLaunching:으로 옮기는 것이 좋습니다.

+0

나에게 의미가있다. 너 내 쿠키있어. –

+0

안녕하세요, 귀하의 제안에 감사드립니다. 하지만 "applicationDidFinishLaunching"함수에는 아무 것도 없습니다. 내가 성취하려는 것에 대해 좀 더 자세한 설명을 추가했습니다. 시간이 있으면 확인해보십시오. – Silex

1

알아 냈습니다. 파일 아이콘을 두 번 클릭하면 응용 프로그램이 실행되고 다른 작업은 올바르게 수행됩니다. 그러나 귀하의 행동에 응답하는 신청서가 귀하가 마지막으로 작성한 신청서 일 필요는 없습니다. 아마도 응용 프로그램의 이전 사본이 응답하고있을 것입니다. 라이브러리> 개발자> Xcode> DrivedData를 살펴보십시오.응용 프로그램에 대한 많은 폴더가 표시되어야합니다. 마우스 오른쪽 버튼을 클릭하고 빌드 한 후 Finder에서 표시를 선택하여 응용 프로그램 폴더를 찾을 수 있습니다. 그 (것)들을 전부 버리고, 새로운 신청을 건설하십시오. 그런 다음 두 번 클릭하고 지금 무슨 일이 일어나는지보십시오.

+0

힌트를 가져 주셔서 감사합니다.하지만 불행히도이 작업을 여러 번 수행해 봤습니다. 깨끗한 빌드를 시도하고, 빌드 디렉토리 + 빌드를 정리하고, 수동으로 폴더를 삭제 한 다음 빌드하고 여전히 똑같은 일이 발생합니다. +1 좋은 힌트 tho. – Silex

+0

시간이 있다면 어떤 기능이 손상되었는지, 편집 부분을 수정했는지 확인하십시오. – Silex

+0

문제가 해결되지 않아 유감 스럽습니다. 모든 폴더가 삭제 되었습니까? 나는 수천 마리를 버렸습니다. 그리고 더블 클릭 문제가 해결되었습니다. 내 소중한 시간을 낭비했다. 어쨌든, EDIT는 무엇입니까? setArgumentinFile 또는 그 이하의 코드 라인에 대해 이야기하고 있다면, 나는 단서가 없다. –

1

파일을 마우스 오른쪽 버튼으로 클릭하고 더블 클릭하면 다르게 동작합니다!

애플 문서 : openFile :

사용자는 대리인이 응용 프로그램 수신을 두 번 클릭하여 파일을하여 응용 프로그램을 시작한 경우 아래 applicationDidFinishLaunching를 받기 전에 메시지를 :. (applicationWillFinishLaunching는 : 응용 프로그램 전에 전송됩니다 openFile :.)

내가 추측했던 애플 문서는 정보의 중요한 부분을 생략

... 그 오른쪽 클릭 - Finder에서> '열기로' 운영 더블 클릭과 동일합니다. 그 NOT!

응용 프로그램 : openFile : applicationDidFinishLaunching 후에 발생합니다.이 경우!

내 머리를 한 시간 동안 긁고 있습니다.

관련 문제