9

cocoa スクリプト ブリッジを使用して新しいユーザー プレイリストを作成しようとしていますが、うまく動作しないようです。私はこれまでに持っています:

iTunesApplication *iTunes = [SBApplication 
                            applicationWithBundleIdentifier:@"com.apple.iTunes"];
SBElementArray *iSources = [iTunes sources];
iTunesSource *library = nil;
for (iTunesSource *source in iSources) {
    if ([[source name] isEqualToString:@"Library"]) {
        library = source;
        break;
    }
}

// could not find the itunes library
if (!library) {
    NSLog(@"Could not connect to the iTunes library");
    return;
}

// now look for our playlist
NSString *playlistName = @"new playlist";
SBElementArray *playlists = [library userPlaylists];
iTunesUserPlaylist *playlist = nil;
for (iTunesUserPlaylist *thisList in playlists) {
    if ([[thisList name] isEqualToString:playlistName]) {
        playlist = thisList;
        break;
    }
}

// if the playlist was not found, create it
if (!playlist) {
    playlist = [[[iTunes classForScriptingClass:@"playlist"] alloc] init];
    [playlist setName:playlistName];
    [[library userPlaylists] insertObject:playlist atIndex:0];
}

プレイリストの名前を追加しようとすると、次のエラー メッセージが表示されます。

iTunesBridge[630:80f] *** -[SBProxyByClass setName:]: オブジェクトはまだコンテナに追加されていません。セレクターが認識されない

誰かが私を正しい方向に向けることができますか?

4

5 に答える 5

10

エラー メッセージは、プレイリストなどの Scripting Bridge オブジェクトは、関連する SBElementArray に追加されるまでメッセージを受信できないことを示しているため、プレイリストを配列に追加する前にプロパティを設定しようとすると失敗します。

最も簡単な解決策は、コードの最後の 2 行を次のように再配置することです。

// if the playlist was not found, create it
if (!playlist) {
    playlist = [[[iTunes classForScriptingClass:@"playlist"] alloc] init];
    [[library userPlaylists] insertObject:playlist atIndex:0];
    [playlist setName:playlistName];
}

もう1つのオプションはinitWithProperties:、別の回答に対するコメントによると、どちらを使用するかです。

于 2011-04-25T22:08:50.190 に答える
5

新しいアプリケーション オブジェクトの作成は、SB ではひどく難読化されています。疑似 Cocoa 風の alloc-init-insert 手順は、実際に下で行われていることとは似ていません。alloc-init は、後続のメソッド呼び出しで操作できる通常のオブジェクトを作成するように見えますが、結果は実際には、唯一の関数が「配列」に「挿入」されるシムであり、その時点で SB は実際のmakeイベントをターゲットプロセス。( SB の批判については、こちらこちらも参照してください。)

IIRC、実際に初期プロパティを指定できる唯一のポイントは-initWithProperties:. オブジェクトが「挿入」された後にそれらを設定できますが、それはまったく別の操作 (作成されるオブジェクトの初期状態を指定するのではなく、既に存在するオブジェクトを操作すること) であるため、注意しないと意図しない結果を簡単にもたらす可能性があります。 .

いずれにせよ、プレイリストがまだ存在しない場合、通常は次のようにして新しいプレイリストを作成します。

set playlistName to "new playlist"
tell application "iTunes"
    if not (exists playlist playlistName) then
        make new playlist with properties {name:playlistName}
    end if
end tell

そして、FWIW、objc-appscriptを使用して、ObjC でそれを行う方法を次に示します(これは私が書いたので、SB を使用する必要はありません)。

#import "ITGlue/ITGlue.h"

NSString *playlistName = @"new playlist";

ITApplication *itunes = [ITApplication applicationWithName: @"iTunes"];
ITReference *playlist = [[itunes playlists] byName: playlistName];

if ([[[playlist exists] send] boolValue])
    playlist = [playlist getItem];
else
    playlist = [[[[itunes make] new_: [ITConstant playlist]] 
                      withProperties: [NSDictionary dictionaryWithObject: playlistName
                                                                  forKey: [ITConstant name]]] send];

(objc-appscript の欠点は、アプリケーション バンドルにフレームワークのコピーをビルドして埋め込む必要があることです。利点は、より機能的で、アプリケーションの互換性の問題が発生しにくく、難読化が少ないことです。さらに、appscript の上記の AppleScript によって送信された Apple イベントを ObjC 構文に変換するASTranslateツール - 参照とコマンドを構築する方法を理解するときに非常に便利です。)

于 2009-12-29T16:54:42.273 に答える
2

[[source name] isEqualToString:@"Library"]英語以外のシステムでは確実に機能しないという簡単なメモ。iTunesSource *library = [[_iTunes sources] objectAtIndex: 0];最初のソース アイテムが一番上にあるので、単純に使用する方がよい場合があります。たとえば、メイン ライブラリです。

于 2010-07-29T05:06:51.503 に答える
2

これは、ライブラリを確実に識別するために行ったことです。私はそれを間違っている可能性があります。

- (iTunesSource *)iTunesLibrary
{
  NSArray *librarySource = [[[self iTunes] sources] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"kind == %@", [NSAppleEventDescriptor descriptorWithTypeCode:iTunesESrcLibrary]]];
  if ([[librarySource lastObject] exists]) {
    return [librarySource lastObject];
  }
  return nil;
}
于 2011-11-19T05:36:39.090 に答える
1

EyeTunesを調べる必要があります。これは、Objective-Cを使用してiTunesと対話するためのオープンソースフレームワークです。EyeTunesを使用してコードを作成すると、コードははるかに単純に見えます。

http://www.liquidx.net/eyetunes/

于 2009-12-29T16:57:02.817 に答える