如何处理返回NSError的PyObjC方法?

时间:2014-07-18 16:53:35

标签: python objective-c cocoa avaudiorecorder pyobjc

我正在尝试让PyObjC应用程序在用户单击按钮时录制音频。我正在尝试使用AVAuidioRecorder类。我的代码是:

@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.nilNone传递给该参数。

当我在NSString方法上使用类似语法时:

(names, error) = NSString.stringWithContentsOfFile_encoding_error_(u"/usr/share/dict/propernames", NSASCIIStringEncoding, objc.nil)

代码运行。

为什么我对AVAudioRecord方法的调用不起作用?是因为当NSString方法调用错误时,该方法需要 outError 吗?

1 个答案:

答案 0 :(得分:2)

该代码不适用于此AVFoundation类,因为PyObjC没有该框架的元数据描述。因此它确实知道最后一个参数是什么类型的参数,它只知道它是指向一个对象的指针,但不知道它被用作传递引用的输出参数。

手动检查PyObjC对此参数的了解::

>> import AVFoundation
>>> AVFoundation.AVAudioRecorder.initWithURL_settings_error_.__metadata__( ['arguments'][-1]
{'null_accepted': True, 'already_retained': False, 'type': '^@', 'already_cfretained': False}

这里的类型应该是“o ^ @”。

这是Apple的PyObjC版本:您可以在该版本中使用“import AVFoundation”,这将使用AVFoundation框架内的BridgeSupport数据文件。遗憾的是,数据不完整,并且没有关于此方法的信息,这就是为什么类型错误的原因。

通过使用PyObjCs元数据API来解决此特定方法相当容易:

import objc
objc.registerMetaDataForSelector(b"AVAudioRecorder", b"initWithURL:settings:error:",
        dict(
            arguments={
               4: dict(type_modifier=objc._C_OUT),
            }
        ))

修复所有AVFoundation的元数据将会更有效: - (