создайте плей-лист iTunes со сценариями моста

Я пытаюсь создать новый пользовательский плей-лист с помощью моста сценариев какао, но, может казаться, не заставляю его работать. Я имею до сих пор:

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:]: объект еще не был добавлен к контейнеру; селектор, не распознанный

Кто-либо может указать на меня в корректном направлении?

9
задан user151019 3 June 2012 в 19:02
поделиться

3 ответа

Создание новых объектов приложения страшно затруднено в SB. Процедура псевдо-какао-иш alloc-init-insert не имеет никакого сходства с тем, что на самом деле происходит внизу. В то время как аллокалитив-иннит создаёт обычный объект, которым можно манипулировать с последующими вызовами методов, в результате получается шайба, единственная функция которой должна быть "вставлена" в "массив", и в этот момент 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, используя objc-appscript (который я написал, чтобы мне не пришлось использовать SB, natch):

#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 ASTranslate для преобразования событий Apple, посылаемых вышеприведенным AppleScript, в синтаксис ObjC - очень удобно, когда вы выясняете, как построить ваши ссылки и команды)

.
5
ответ дан 4 December 2019 в 10:32
поделиться

Вы должны заглянуть в EyeTunes. Это фреймворк с открытым исходным кодом для взаимодействия с iTunes с помощью Objective-C. Ваш код выглядел бы намного проще, если бы вы сделали это через EyeTunes.

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

1
ответ дан 4 December 2019 в 10:32
поделиться

Замечу, что [[имя источника] isEqualToString: @ "Library"] определенно не работает в неанглоязычных системах. Возможно, лучше просто использовать iTunesSource * library = [[_iTunes sources] objectAtIndex: 0]; , поскольку первый исходный элемент находится вверху, например основная библиотека.

2
ответ дан 4 December 2019 в 10:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: