我目前正在为Spotify编写一个应用程序扩展,允许我控制播放。我将Spotify AppleScript API与Objective-C中的Scripting Bridge结合使用。我想问的第一件事是,Scripting API是否支持Key Value Observing?因为当我添加观察者时,我不会从API收到任何通知,当我尝试从Scripting API手动获取数据时,我总是得到零值,为什么?我有以下代码:
-(id)init
{
self=[super init];
if(self)
{
spotify=[SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
//Not sure if KVO is implemented,so I use this to get data from the API
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(observeValueForKeyPath) userInfo:nil repeats:YES];
if([self isSpotifyRunning])
{
//Useless?
[spotify addObserver:self forKeyPath:@"currentTrack" options:NSKeyValueObservingOptionNew context:nil];
[spotify addObserver:self forKeyPath:@"playerPosition" options:NSKeyValueObservingOptionNew context:nil];
[spotify addObserver:self forKeyPath:@"playerState" options:NSKeyValueObservingOptionNew context:nil];
[self.playBackSlider setTarget:self];
[self.playBackSlider setAction:@selector(sliderDidMove:)];
if(spotify.playerState==SpotifyEPlSPaused||spotify.playerState==SpotifyEPlSStopped)
{
[self.playButton setStringValue:@"Play"];
}
else
{
[self.playButton setStringValue:@"Stop"];
}
}
}
return self;
}
-(void)observeValueForKeyPath
{
[self.titleTextField setStringValue:spotify.currentTrack.name];
[self.artistTextField setStringValue:spotify.currentTrack.artist];
[self.currentPlayBackPositionTextField setStringValue:[self formatTime:spotify.playerPosition]];
[self.remainingTimeTextField setStringValue:[self formatTime:spotify.currentTrack.duration]];
[self.playBackSlider setMaxValue:spotify.currentTrack.duration];
[self.playBackSlider setDoubleValue:spotify.playerPosition];
[self.playBackSlider setDoubleValue:spotify.playerPosition];
[self.currentPlayBackPositionTextField setStringValue:[self formatTime:spotify.playerPosition]];
if(spotify.playerState==SpotifyEPlSPaused||spotify.playerState==SpotifyEPlSStopped)
{
[self.playButton setStringValue:@"Play"];
}
else
{
[self.playButton setStringValue:@"Stop"];
}
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if([keyPath isEqualToString:@"currentTrack"])
{
[self.titleTextField setStringValue:spotify.currentTrack.name];
[self.artistTextField setStringValue:spotify.currentTrack.artist];
[self.currentPlayBackPositionTextField setStringValue:[self formatTime:spotify.playerPosition]];
[self.remainingTimeTextField setStringValue:[self formatTime:spotify.currentTrack.duration]];
[self.playBackSlider setMaxValue:spotify.currentTrack.duration];
[self.playBackSlider setDoubleValue:spotify.playerPosition];
}
else if([keyPath isEqualToString:@"playerPosition"])
{
[self.playBackSlider setDoubleValue:spotify.playerPosition];
[self.currentPlayBackPositionTextField setStringValue:[self formatTime:spotify.playerPosition]];
}
else if([keyPath isEqualToString:@"playerState"])
{
if(spotify.playerState==SpotifyEPlSPaused||spotify.playerState==SpotifyEPlSStopped)
{
[self.playButton setStringValue:@"Stop"];
}
else
{
[self.playButton setStringValue:@"Play"];
}
}
}
编辑:我已经为SBApplication对象设置了一个委托,我得到了以下错误:
错误域=NSOSStatusErrorDomain Code=-600"procNotFound:no具有指定描述符的合格进程"UserInfo={ErrorNumber=-600}
这到底是什么意思?Spotify在创建SBA应用程序时启动,那么为什么SBA应用软件告诉我它没有找到流程呢?我还看了一下Spotify捆绑包中的Info.plist,它是可编写脚本的,那么为什么它不起作用呢?
提前感谢您的帮助!
任何应用程序的AppleScript脚本字典(您称之为AppleScript API)都不支持KVO。
关于在Cocoa应用程序中使用脚本字典,请忘记ScriptingBridge
。
AppleScriptObjC
(在10.6 Snow Leopard中引入)提供了一种更容易与AppleScript交互的方式。您甚至可以在同一文件中使用AppleScript和类似Objective-C的术语,在AppleScriptObjC中完全编写Cocoa应用程序。