2013-02-17 2 views
3

간단한 Objective-C 응용 프로그램을 작성하려고합니다. 상태 표시 줄에 단어를 표시하고 AppleScript를 통해 단어를 업데이트 할 수있는 응용 프로그램이 필요합니다. 솔직히 말해서, 나는 AppleScript에 대해 거의 알지 못하며 Objective-C에 대해서는 거의 모른다. 하지만 메뉴 항목이있는 메뉴 모음 응용 프로그램을 가져 오는 데 2 ​​시간 밖에 걸리지 않았고 "종료"와 같은 핵심 AppleScript 명령에 응답하기 때문에 어렵지 않을 수 있습니다. 따라서이 방법의 95 %에 해당합니다. 불행히도 다음 6 시간 동안이 애플리케이션에 AppleScript를 통해 가져다 놓을 수있는 간단한 속성을 제공하는 방법을 찾으려고했습니다. foobaz 방법은 내가 읽을 수있는 속성을 만들려고 노력 사용 된 하나 (*window은 내가 엑스 코드와 관련이없는 주어진 된 상용구의 일부입니다NSApplicationDelegate를 사용할 때 Apple의 SimpleScripting 예제가 작동하지 않습니다.

#import <Cocoa/Cocoa.h> 

@interface AppDelegate : NSObject <NSApplicationDelegate> { 
    NSWindow *window; 
    IBOutlet NSMenu *statusMenu; 
    NSStatusItem *statusItem; 
} 
@property (assign) IBOutlet NSWindow *window; 
- (NSString*) foobaz; 
@end 

: 여기

내 .H 코드 당면 문제에). 여기 내 .sdef 파일입니다 https://developer.apple.com/library/mac/#samplecode/SimpleScripting/Introduction/Intro.html

는 그러나, 나는 스크립트 편집기에서이 작업을 실행하려고했습니다 :

를 그냥 여기에 애플의 SimpleScripting 예처럼 설정 그래서있어

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd"> 
<dictionary xmlns:xi="http://www.w3.org/2003/XInclude"> 
    <xi:include 
    href="file:///System/Library/ScriptingDefinitions/CocoaStandard.sdef" 
    xpointer="xpointer(/dictionary/suite)"/> 
    <suite name="StatusMenuApp suite" code="smas" 
    description="StatusMenuApp specific classes."> 
    <class name="application" code="smaa" inhereits="application" 
     description="Application object."> 
     <cocoa class="AppDelegate"/> 
     <property name="foobaz" code="smas" type="text" access="r"/> 
    </class> 
    </suite> 
</dictionary> 

tell application "StautsMenuApp" 
    properties 
end tell 

그리고 난 그냥 사용자 지정 속성은 내가 그것을 실행하는 핵심 속성과 함께 표시되는 애플의 예와는 달리 전혀 foobaz없이 언급, 함께, 핵심 속성의 목록을 얻을.

나는 이것에 백가지 변형을 시도하고 백 가지의 예제를 읽었지만 아무 것도 얻을 수 없다고 느낀다. 어떤 도움을 주셔서 감사합니다.

답변

0

제가 알기로는 sdef에 문제가 있습니다. 이 줄의 코드는 "capp"여야합니다. 이것은 표준이며 모든 sdef 파일에서 동일합니다. Apple이 정의하므로 필요합니다. 이 같은 메소드에 액세스하는 것이 당신이 할 후에는 해당

<class name="application" code="smaa" inhereits="application" 
     description="Application object."> 

...

tell application "StautsMenuApp" to foobaz 
2

은 SDEF 파일과 함께 많은 문제가 있습니다. 자신의 "종류"(OSType 코드)를 정의 할 때

  1. 이 큰 문제가 아니지만은, 모두 소문자는 역사적으로 애플을 위해 예약되어 있습니다. 따라서 'Smas' 또는 'sMas'과 같은 것을 사용해야하지만 'smas'이 아닌 것은해야합니다.

  2. 웹 브라우저에서 오타가 있었으나 <class name="application" code="smaa" inhereits="application"... 줄에 inhereits의 철자가 틀렸을 수 있습니다. 자신의 추가 속성으로 기본 AppleScript application 클래스를 적절히 "확장"할 수 있도록 철자가 정확해야합니다. 이것이 AppleScript 편집기에서 기본 응용 프로그램 속성 만보고있는 이유 일 수 있습니다. (철자만으로 수정하면 문제가 해결 될 수 있지만 수정해야 할 사항이 있습니다).

  3. 당신은 당신의 "확장"application 애플 스크립트 클래스의 코코아 클래스 AppDelegate로 지정하려는

    하지만, 애플의 예에서 언급 된 것처럼 AppDelegateNSApplication에서 상속하지 않기 때문에이 문제가된다.sdef는 오히려 일반 old NSObject에서 상속받습니다.

나는 SDEF를 다시 작성합니다 방법에 이동하기 전에, 나는 기본적인 아이디어는 애플의 예를 SDEF 기본 AppleScript로 application 클래스에 사용자 정의 속성을 추가하기 위해 노력하는 방법 뒤에 무엇인지 검토합니다. AppleScript application 클래스는 NSApplication 코코아 클래스에 해당합니다. 응용 프로그램을 실행하면 OS X은 NSApplication (또는 해당 하위 클래스, 응용 프로그램의 Info.plist 파일에있는 NSPrincipalClass 항목에 지정된대로) 인스턴스를 만듭니다. 이 인스턴스는 응용 프로그램을 관리합니다. Cocoa에서는 추가 AppleScript 속성을 기존 NSApplication 클래스에 추가하는 두 가지 방법이 있습니다. 1) 추가 속성이 포함 된 NSApplication의 사용자 지정 하위 클래스 만들기 또는 2) Objective-C 범주를 사용하여 기존 NSApplication 클래스를 as- 입니다. (코코아에서, Objective-C 카테고리는 서브 클래 싱이 도입 할 수있는 잠재적 인 복잡성없이 기존 클래스에 추가 기능을 추가하는 방법입니다.) Apple의 SimpleScripting 예제는 후자의 접근법 (Objective-C 카테고리)을 사용하여 추가 기능을 추가합니다.

다음은 SDEF를 다시 작성하는 방법입니다.

SimpleScriptingAppDelegate.sdef :

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd"> 
<dictionary xmlns:xi="http://www.w3.org/2003/XInclude"> 
    <xi:include 
    href="file:///System/Library/ScriptingDefinitions/CocoaStandard.sdef" 
    xpointer="xpointer(/dictionary/suite)"/> 
    <suite name="StatusMenuApp suite" code="SSAD" 
       description="StatusMenuApp-specific classes."> 
     <class name="application" code="capp" inherits="application" 
           description="Application object."> 
      <cocoa class="NSApplication"/> 
      <property name="foobaz" code="Foob" 
       description="Description of the foobaz property." type="text"> 
       <cocoa key="foobaz"/> 
      </property> 
     </class> 
    </suite> 
</dictionary> 

당신은 내가 표준 AppleScript를 application 클래스에서 상속 사용자 정의 애플 스크립트 application 클래스를 만드는거야 것을 지정한 것을 알 수 있습니다. 나는이 커스텀의 코코아 클래스가 인 것을 NSApplication으로 지정했다. 이름이 foobaz이고 유형이 text 인 사용자 정의 AppleScript 속성을 추가했습니다. (AppleScript text 클래스는 Cocoa NSString 클래스에 해당합니다. 또한 중요한 것은이 사용자 지정 속성에 액세스하는 코코아 키가 foobaz임을 지정했습니다. 이 "코코아 키"는 속성 값을 제공하는 데 사용되는 Objective-C 메서드의 이름을 지정합니다. 위에 정의 된 구성은 NSApplication 개체의 공유 인스턴스에서 foobaz 메서드를 호출하여 사용자 지정 foobaz 속성을 가져올 수 있음을 지정합니다.

MDNSApplicationScriptingAdditions.h을 : : 아래 그림과 같이

사물의 코코아 측면에서 그것을 구현하기 위해, 나는 NSApplication(MDScriptingAdditions) 범주를 정의

@interface NSApplication (MDScriptingAdditions) 

- (NSString *)foobaz; 
- (void)setFoobaz:(NSString *)aFoobaz; 

@end 

MDNSApplicationScriptingAdditions.m :

#import "MDNSApplicationScriptingAdditions.h" 
#import "AppDelegate.h" 

@implementation NSApplication (MDScriptingAdditions) 

- (NSString *)foobaz { 
    return [(AppDelegate *)[NSApp delegate] foobaz]; 
} 

- (void)setFoobaz:(NSString *)aFoobaz { 
    return [(AppDelegate *)[NSApp delegate] setFoobaz:aFoobaz]; 
} 
@end 

나는 기본적으로이 방법들의 처리를로 전달한다는 것을 알 수있다.클래스를 사용하면 어떻게 설정했는지 알 수 있습니다.

AppDelegate.h :

@interface AppDelegate : NSObject <NSApplicationDelegate> { 
    IBOutlet NSWindow     *window; 
    IBOutlet NSTextField    *foobazTextField; 

    NSString       *foobaz; 
} 
- (NSString *)foobaz; 
- (void)setFoobaz:(NSString *)aFoobaz; 
@end 

이 설정이 사용자가 얻을 애플 스크립트를 통해 사용자 정의 foobaz 속성을 설정할 수 있습니다.

enter image description here

샘플 프로젝트 : SimpleScriptingAppDelegate.zip

값을 설정하면 아래 이미지와 같이 사용자가 같은 설정 값으로 변경합니다 foobaz: 텍스트 필드에 표시된 값의 원인이됩니다