3

簡単なObjective-Cアプリケーションを作成しようとしています。ステータスバーに単語を表示し、AppleScriptを介して単語を更新できるアプリが必要です。正直なところ、私はAppleScriptについてはほとんど知らず、Objective-Cについても何も知りません。しかし、メニュー項目があり、「quit」などのコアAppleScriptコマンドに応答するメニューバーアプリを入手するのに2時間しかかからなかったので、それほど難しいことではありません。残念ながら、私は次の6時間かけて、このアプリケーションにAppleScriptを介して取得および設定できる単純なプロパティを与える方法を見つけようとしました。

これが私の.hコードです:

#import <Cocoa/Cocoa.h>

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

このfoobazメソッドは、読み取り可能なプロパティを作成するために使用していたものです(*windowXCodeによって提供された定型文の一部であり、当面の問題には関係ありません)。これが私の.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="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>

だから私はここでAppleのSimpleScriptingの例のようにセットアップしました:https ://developer.apple.com/library/mac/#samplecode/SimpleScripting/Introduction/Intro.html

ただし、スクリプトエディタでこれを実行してみました。

tell application "StautsMenuApp"
    properties
end tell

そして、Appleの例とは異なり、コアプロパティのリストを取得するだけで、foobaz何も言及されていません。Appleの例では、カスタムプロパティを実行すると、コアプロパティの横に表示されます。

これについて100のバリエーションを試し、100の例を読んだように感じますが、何も機能しません。どんな助けでも大歓迎です。

4

2 に答える 2

2

SDEF ファイルには多くの問題があります。

  1. これは大きな問題ではありませんが、独自の「タイプ」(OSTypeコード) を定義する場合、すべての小文字は歴史的に Apple 用に予約されています。'Smas'したがって、 orのようなことを行う必要がありますが、そうではありませ'sMas''smas'

  2. これは Web ブラウザのここでのタイプミスである可能性がありますがinhereits、行のスペルが間違っています<class name="application" code="smaa" inhereits="application"...application基本 AppleScriptクラスを独自の追加プロパティで適切に「拡張」できるように、スペルが正しいことが重要です。これが、AppleScript Editor でデフォルトのアプリケーション プロパティしか表示されない理由である可能性があります。(スペルを修正するだけで問題が解決する場合もありますが、他の修正も行う必要があります)。

  3. application「拡張」 AppleScript クラスの Cocoa クラスが であることを指定しようとしていますが、Apple の例 .sdef で指定されているように継承されず、plain-old から継承さAppDelegateれるため、これは問題があります。AppDelegateNSApplicationNSObject

SDEF を書き直す方法に移る前に、Apple のサンプル SDEF がカスタム プロパティをデフォルトの AppleScriptapplicationクラスに追加する方法の背後にある基本的な考え方を確認します。AppleScriptクラスはCocoa クラスapplicationに対応します。NSApplicationアプリケーションを起動すると、OS X はインスタンス(またはアプリケーションの Info.plist ファイルのエントリでNSApplication指定されたそのサブクラス)を作成します。NSPrincipalClassこのインスタンスは、アプリケーションを管理します。Cocoa では、追加の AppleScript プロパティを既存のクラスに追加する方法が 2 つありますNSApplication。1)NSApplication追加のプロパティを含むカスタム サブクラスを作成するか、2) Objective-C カテゴリを使用して既存のクラスを拡張します。NSApplicationクラスそのまま。(Cocoa では、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>

application標準の AppleScript クラスを継承するカスタム AppleScript クラスを作成していることを指定していることにお気付きでしょうapplication。このカスタムの Cocoa クラスapplicationNSApplication. foobaz名前がでタイプがのカスタム AppleScript プロパティを追加しましたtext。(AppleScripttextクラスは CocoaNSStringクラスに対応します)。また重要なことは、このカスタム プロパティにアクセスするための Cocoa キーが であることを指定したことですfoobaz。この「Cocoa キー」は、プロパティの値を提供するために使用される Objective-C メソッドの名前を指定します。foobazfoobazNSApplication

これを Cocoa 側で実装するために、以下に示すように(MDScriptingAdditions)カテゴリを定義しました。NSApplication

MDNSApplicationScriptingAdditions.h:

@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クラスに転送していることがわかります。これは、設定したい方法です。

AppDelegate.h:

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

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

foobazこの設定により、 AppleScript を介してカスタム プロパティを取得および設定できます。値を設定すると、foobaz:テキスト フィールドに表示される値が、下の画像に示すように設定した値に変更されます。

ここに画像の説明を入力

サンプル プロジェクト: SimpleScriptingAppDelegate.zip

于 2013-02-20T22:54:13.723 に答える
0

私が手に負えない唯一のことは、あなたのsdefの問題です。この行のコードは「capp」である必要があります。これは標準であり、これはどの sdef ファイルでも同じです。Appleによって定義されているので、それが必要です。

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

それを行った後、次のようにそのメソッドにアクセスします...

tell application "StautsMenuApp" to foobaz
于 2013-02-18T21:25:30.757 に答える