目前我正在尝试通过 ScriptingBridge 实现对多个版本的 iTunes 的支持。
例如,属性的方法签名playerPosition
从 (10.7) 更改
@property NSInteger playerPosition; // the player’s position within the currently playing track in seconds.
到 (11.0.5)
@property double playerPosition; // the player’s position within the currently playing track in seconds
对于我的应用程序中最新的头文件和较旧的 iTunes 版本,此属性的返回值将始终为 3。同样的事情反过来。
所以我继续创建了三个不同的 iTunes 头文件,11.0.5、10.7 和 10.3.1 via
sdef /path/to/application.app | sdp -fh --basename applicationName
对于每个版本的 iTunes,我调整了基本名称以包含版本,例如 iTunes_11_0_5.h。这导致头文件中的接口以它们的特定版本号为前缀。我的目标是/是对我要与正确版本的接口一起使用的对象进行类型转换。
iTunes 的路径是通过一种NSWorkspace
方法获取的,然后我从中创建一个 NSBundle 并CFBundleVersion
从 infoDictionary 中提取它。
三个不同的版本(11.0.5、10.7、10.3.1)也被声明为常量,我通过以下方式与用户的 iTunes 版本进行比较
[kiTunes_11_0_5 compare:versionInstalled options:NSNumericSearch]
然后我检查每个结果是否等于NSOrderedSame
,这样我就知道用户安装了哪个版本的 iTunes。
用 if 语句实现这个有点失控,因为我需要在课堂上的许多不同地方进行这些类型转换,然后我开始意识到这会导致很多重复的代码,并进行了修改和思考这是为了找到一个不同的解决方案,一个更“最佳实践”的解决方案。
一般来说,我需要对我使用的对象进行动态类型转换,但我根本找不到一个不会导致大量重复代码的解决方案。
编辑
if ([kiTunes_11_0_5 compare:_versionString options:NSNumericSearch] == NSOrderedSame) {
NSLog(@"%@, %@", kiTunes_11_0_5, _versionString);
playerPosition = [(iTunes_11_0_5_Application*)_iTunes playerPosition];
duration = [(iTunes_11_0_5_Track*)_currentTrack duration];
finish = [(iTunes_11_0_5_Track*)_currentTrack finish];
} else if [... and so on for each version to test and cast]