如何处理返回NSError的PyObjC方法?
我正在尝试让我的PyObjC应用在用户点击按钮时录音。我想使用AVAudioRecorder这个类。我的代码是:
@IBAction
def startRecording_(self, sender):
audioPath = '~/Desktop/recordTest.mp3'
audioPathStr = NSString.stringByExpandingTildeInPath(audioPath)
audioURL = NSURL.fileURLWithPath_(audioPathStr)
audioSettings = {'AVFormatIDKey': 'kAudioFormatAppleIMA4', 'AVSampleRateKey': 1600.0, 'AVNumberOfChannelsKey': 1 }
audioDict = NSDictionary.dictionaryWithDictionary_(audioSettings)
(recorder, error) = AVAudioRecorder.alloc().initWithURL_settings_error_(audioURL, audioDict, objc.nil)
recorder.record()
当我运行上面的代码时,出现了以下错误:
<type 'exceptions.TypeError'>: 'NoneType' object is not iterable
看起来initWithURL_settings_error_
这个方法的第三个参数需要一个可迭代的对象。但是,我以为在使用PyObjC的方法时,如果需要一个错误参数,我可以传入objc.nil
或者None
。
当我在一个NSString的方法上使用类似的语法时:
(names, error) = NSString.stringWithContentsOfFile_encoding_error_(u"/usr/share/dict/propernames", NSASCIIStringEncoding, objc.nil)
代码是可以运行的。
为什么我调用AVAudioRecord方法时不行?是因为这个方法需要一个outError,而NSString的方法只需要一个error吗?
1 个回答
3
这段代码在使用AVFoundation这个类时出问题了,因为PyObjC没有关于这个框架的元数据描述。简单来说,它知道最后一个参数是一个对象的指针,但不知道这个指针是用来作为引用输出参数的。
如果你想手动检查PyObjC对这个参数的了解,可以这样做:
>> import AVFoundation
>>> AVFoundation.AVAudioRecorder.initWithURL_settings_error_.__metadata__( ['arguments'][-1]
{'null_accepted': True, 'already_retained': False, 'type': '^@', 'already_cfretained': False}
这里的类型应该是"o^@"。
这是使用苹果版本的PyObjC:你可以用“import AVFoundation”来导入这个框架,这样就会使用AVFoundation框架里的BridgeSupport数据文件。不过很遗憾,这些数据不完整,没有关于这个方法的信息,所以这里的类型就错了。
对于这个特定的方法,使用PyObjC的元数据API来修复这个问题是相对简单的:
import objc
objc.registerMetaDataForSelector(b"AVAudioRecorder", b"initWithURL:settings:error:",
dict(
arguments={
4: dict(type_modifier=objc._C_OUT),
}
))
不过,要修复AVFoundation的所有元数据就会复杂得多 :-(