【问题标题】:How to handle PyObjC method that returns NSError?如何处理返回 NSError 的 PyObjC 方法?
【发布时间】:2014-07-18 16:53:34
【问题描述】:

我试图让我的 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 方法的调用不起作用?是不是因为方法调用 outError 而 NSString 方法调用 error

【问题讨论】:

  • 在语义上,您应该使用 Noneobjc.NULL 作为该参数,但 objc.nil 应该可以工作。我不认为这是该异常的根源。您确定您创建的 URL 不是 None,并且该文件存在于该路径中吗?另外,请注意,您不必像这样将 Python dict 转换为 NSDictionary;您可以将 dict 作为参数传入,桥会为您处理它。
  • @JoshCaswell URL 不是None,我认为该文件不应该存在于该路径中,因为这个 AVAudioRecorder 应该创建该文件,而不是读取它。

标签: python objective-c cocoa avaudiorecorder pyobjc


【解决方案1】:

代码不适用于此 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 的元数据将是更多工作:-(

【讨论】:

  • 你怎么导入AVFoundation它不在pyobjc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2021-04-03
  • 2020-04-11
  • 1970-01-01
相关资源
最近更新 更多