脚本桥不工作(KVO,零值)
Scripting Bridge does not work(KVO,nil values)
我目前正在为 Spotify 编写一个应用程序扩展,允许我控制播放。我将 Spotify AppleScript API 与 Objective-C 中的脚本桥结合使用。首先我想问一下,Scripting API 支持Key Value Observing吗?因为当我添加观察者时,我没有从 API 收到任何通知,而当我尝试从脚本 API 手动获取数据时,我总是得到 nil 值,为什么?
我有以下代码:
-(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 对象设置了委托,但出现以下错误:
Error Domain=NSOSStatusErrorDomain Code=-600 "procNotFound: no
eligible process with specified descriptor"
UserInfo={ErrorNumber=-600}
这到底是什么意思? Spotify 在创建 SBApplication 时启动,那么为什么 SBApplication 告诉我它没有找到进程?我还查看了 Spotify Bundle 中的 Info.plist,它是可编写脚本的,那么为什么它不起作用?
提前感谢您的帮助!
任何应用程序的 AppleScript 脚本字典——你所说的 AppleScript API——不支持 KVO。
关于在 Cocoa 应用程序中使用脚本字典忘记 ScriptingBridge
。
AppleScriptObjC
(在 10.6 Snow Leopard 中引入)提供了一种与 AppleScript 交互的更简单的方法。您甚至可以在同一文件中使用 AppleScript 和类似 Objective-C 的术语完全在 AppleScriptObjC 中编写 Cocoa 应用程序。
我目前正在为 Spotify 编写一个应用程序扩展,允许我控制播放。我将 Spotify AppleScript API 与 Objective-C 中的脚本桥结合使用。首先我想问一下,Scripting API 支持Key Value Observing吗?因为当我添加观察者时,我没有从 API 收到任何通知,而当我尝试从脚本 API 手动获取数据时,我总是得到 nil 值,为什么? 我有以下代码:
-(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 对象设置了委托,但出现以下错误:
Error Domain=NSOSStatusErrorDomain Code=-600 "procNotFound: no eligible process with specified descriptor" UserInfo={ErrorNumber=-600}
这到底是什么意思? Spotify 在创建 SBApplication 时启动,那么为什么 SBApplication 告诉我它没有找到进程?我还查看了 Spotify Bundle 中的 Info.plist,它是可编写脚本的,那么为什么它不起作用?
提前感谢您的帮助!
任何应用程序的 AppleScript 脚本字典——你所说的 AppleScript API——不支持 KVO。
关于在 Cocoa 应用程序中使用脚本字典忘记 ScriptingBridge
。
AppleScriptObjC
(在 10.6 Snow Leopard 中引入)提供了一种与 AppleScript 交互的更简单的方法。您甚至可以在同一文件中使用 AppleScript 和类似 Objective-C 的术语完全在 AppleScriptObjC 中编写 Cocoa 应用程序。