ios 如何将 iPhone OSStatus 代码转换为有用的东西?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2196869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:51:41  来源:igfitidea点击:

How do you convert an iPhone OSStatus code to something useful?

iosmacoscocoa-touchcocoaerror-handling

提问by matt

I am getting more than a little sick of this iPhone SDK and its documentation...

我对这个 iPhone SDK 和它的文档已经有点厌烦了……

I am calling AudioConverterNew

我打电话给 AudioConverterNew

in the documentation under Returns: it says "returns a status code" ... really...

在 Returns 下的文档中:它说“返回状态代码”......真的......

so far, through playing around with the parameters I have only been able to get two different errors neither of which are listed at the bottom of the Audio Converter reference.

到目前为止,通过调整参数,我只能得到两个不同的错误,这两个错误都没有列在 Audio Converter 参考的底部。

they are 'mrep' and '?tmf' (casting the OSStatus to a char array) but the specific codes aren't really the point.

它们是 'mrep' 和 '?tmf'(将 OSStatus 转换为 char 数组),但具体的代码并不是重点。

as far as I can tell, random error codes are defined in random files, so you can't just search one file, I can't find a help document that just lets you search for an error code to get more info, and from what I can tell, in OS X you can use GetMacOSStatusErrorString() to convert an error to something useful, but there is no iPhone equivalent?

据我所知,随机错误代码是在随机文件中定义的,所以你不能只搜索一个文件,我找不到一个帮助文档,它只能让你搜索错误代码以获取更多信息,并且从我能说的是,在 OS X 中,您可以使用 GetMacOSStatusErrorString() 将错误转换为有用的内容,但没有 iPhone 等效项?

any help would be greatly appreciated.

任何帮助将不胜感激。

EDIT:

编辑:

ok, so casting them gives them in reverse (something I checked for 'mrep' but was not there either way round) , fmt? is in the list for the Audio Converter api, and is pretty self explanatory if a bit vague, but fair enough, still 'perm' isn't there (although it might be something to do with the simulator not supporting aac decoding) and my general question still stands.

好的,所以将它们转换为反向(我检查了“mrep”,但无论如何都没有),fmt?在音频转换器 api 的列表中,如果有点模糊,它是非常不言自明的,但足够公平,仍然没有“烫发”(尽管它可能与不支持 aac 解码的模拟器有关)和我的一般问题仍然存在。

采纳答案by kennytm

No. Not completely.

不,不完全。

Some OSStatus are four-character-codes, so you can use (extracted from iPhone SDK's sample code "CAXException.h")

一些 OSStatus 是四字符代码,因此您可以使用(摘自 iPhone SDK 的示例代码“ CAXException.h”)

static char *FormatError(char *str, OSStatus error)
{
    // see if it appears to be a 4-char-code
    *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error);
    if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
        str[0] = str[5] = '\'';
        str[6] = '
NSString* ErrMsg = (__bridge_transfer NSString *) SecCopyErrorMessageString(theOSStatusError, NULL);
'; } else { // no, format it as an integer sprintf(str, "%d", (int)error); } return str; }

(See iOS/C: Convert "integer" into four character stringfor some more ways to convert fourcc into string, including Swift)

(请参阅iOS/C: Convert "integer" intoFour character string了解更多将fourcc转换为字符串的方法,包括Swift)

NSError's NSOSStatusErrorDomain is able to decode some OS errors. See @tomk's answer.

NSError 的 NSOSStatusErrorDomain 能够解码一些操作系统错误。请参阅@tomk 的回答

If you don't need to decode the number in program for the user, you may use the macerrorscript to manually find out the meaning, as mentioned in @lros's answer. The list of OSStatus supported can be found from its source code in /System/Library/Perl/Extras/5.18/Mac/Errors.pm.

如果您不需要为用户解码程序中的数字,您可以使用macerror脚本手动找出含义,如@lros的回答中所述。支持的 OSStatus 列表可以从其源代码中找到/System/Library/Perl/Extras/5.18/Mac/Errors.pm

There is also an online service http://osstatus.com/collecting errors from all public frameworks. They are still not really complete e.g. the mapping to -12792mentioned in the comment is missing. Probably it is a code from a private framework.

还有一个在线服务http://osstatus.com/从所有公共框架收集错误。它们仍然不完整,例如-12792缺少注释中提到的映射。可能它是来自私有框架的代码。

回答by tomk

OSStatus is a signed integer value. You cannot convert or "cast" it to a string. You can convert it to a NSError like this:

OSStatus 是一个有符号整数值。您不能将其转换或“强制转换”为字符串。您可以将其转换为 NSError 像这样:

NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];

NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];

回答by lros

I recently ran across another approach: the macerror command. Print out the OSStatus value as a signed integer. Then in a terminal window (on your Mac, not your iDevice!) type for example macerror -50. It will respond with a brief description. Obviously this is only helpful for you, during development.

我最近遇到了另一种方法:macerror 命令。将 OSStatus 值打印为有符号整数。然后在终端窗口(在您的 Mac 上,而不是您的 iDevice!)中输入例如macerror -50。它会回复一个简短的描述。显然,这仅在开发过程中对您有帮助。

回答by FlowUI. SimpleUITesting.com

This is available on macOS and for iOS from 11.3 and above.

这在 macOS 和 11.3 及更高版本的 iOS 上可用。

I know this is an old post, but I was reading the apple docsin a section related to keychains. They mention a method that is used to convert OSStatus errors into something readable.

我知道这是一个古老的职位,但我读苹果文档中涉及到钥匙链的部分。他们提到了一种用于将 OSStatus 错误转换为可读内容的方法。

SecCopyErrorMessageString

Returns a string explaining the meaning of a security result code.

SecCopyErrorMessageString (OSStatus status, void* reserved );

SecCopyErrorMessageString

返回解释安全结果代码含义的字符串。

SecCopyErrorMessageString (OSStatus status, void* reserved );

Useage:

用途:

- (NSString *)OSStatusToStr:(OSStatus)st
{
    switch (st) {
        case kAudioFileUnspecifiedError:
            return @"kAudioFileUnspecifiedError";

        case kAudioFileUnsupportedFileTypeError:
            return @"kAudioFileUnsupportedFileTypeError";

        case kAudioFileUnsupportedDataFormatError:
            return @"kAudioFileUnsupportedDataFormatError";

        case kAudioFileUnsupportedPropertyError:
            return @"kAudioFileUnsupportedPropertyError";

        case kAudioFileBadPropertySizeError:
            return @"kAudioFileBadPropertySizeError";

        case kAudioFilePermissionsError:
            return @"kAudioFilePermissionsError";

        case kAudioFileNotOptimizedError:
            return @"kAudioFileNotOptimizedError";

        case kAudioFileInvalidChunkError:
            return @"kAudioFileInvalidChunkError";

        case kAudioFileDoesNotAllow64BitDataSizeError:
            return @"kAudioFileDoesNotAllow64BitDataSizeError";

        case kAudioFileInvalidPacketOffsetError:
            return @"kAudioFileInvalidPacketOffsetError";

        case kAudioFileInvalidFileError:
            return @"kAudioFileInvalidFileError";

        case kAudioFileOperationNotSupportedError:
            return @"kAudioFileOperationNotSupportedError";

        case kAudioFileNotOpenError:
            return @"kAudioFileNotOpenError";

        case kAudioFileEndOfFileError:
            return @"kAudioFileEndOfFileError";

        case kAudioFilePositionError:
            return @"kAudioFilePositionError";

        case kAudioFileFileNotFoundError:
            return @"kAudioFileFileNotFoundError";

        default:
            return @"unknown error";
    }
}

It worked for me with my keychain OSStatus errors. Does it work for you? You will need Security.Frameworkadded to your project to use this method.

它对我的钥匙串 OSStatus 错误有用。对你起作用吗?您需要将Security.Framework添加到您的项目中才能使用此方法。

回答by Echo Lu

Here is the code I wrote, hope it save you some typing... er, don't know how to make it show up correctly.

这是我写的代码,希望它可以为您节省一些打字...呃,不知道如何让它正确显示。

    guard status == errSecSuccess else {
        throw  NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: SecCopyErrorMessageString(status, nil) ?? "Undefined error"])
    }

回答by Earlz

I recently found this really nice website that's worked for every status value I've thrown at it. It's a lot more user friendly than grepping through the framework header files: http://www.osstatus.com/

我最近发现了这个非常好的网站,它适用于我投入的每个状态值。它比通过框架头文件 grep 更加用户友好:http: //www.osstatus.com/

回答by Roman Mykitchak

I combined a few answers. Actually I were looking something like ?throw errorForStatusCode(status)”. But in the end achieved:

我结合了几个答案。实际上我看起来像 ?throw errorForStatusCode(status)”。但最终实现了:

let isDebug = true

//**************************
// OSStatus extensions for logging
//**************************
extension OSStatus {
    //**************************
    func asString() -> String? {
        let n = UInt32(bitPattern: self.littleEndian)
        guard let n1 = UnicodeScalar((n >> 24) & 255), n1.isASCII else { return nil }
        guard let n2 = UnicodeScalar((n >> 16) & 255), n2.isASCII else { return nil }
        guard let n3 = UnicodeScalar((n >>  8) & 255), n3.isASCII else { return nil }
        guard let n4 = UnicodeScalar( n        & 255), n4.isASCII else { return nil }
        return String(n1) + String(n2) + String(n3) + String(n4)
    } // asString

    //**************************
    func detailedErrorMessage() -> String? {
        switch(self) {
        //***** AUGraph errors
        case kAUGraphErr_NodeNotFound:             return "AUGraph Node Not Found"
        case kAUGraphErr_InvalidConnection:        return "AUGraph Invalid Connection"
        case kAUGraphErr_OutputNodeErr:            return "AUGraph Output Node Error"
        case kAUGraphErr_CannotDoInCurrentContext: return "AUGraph Cannot Do In Current Context"
        case kAUGraphErr_InvalidAudioUnit:         return "AUGraph Invalid Audio Unit"

        //***** MIDI errors
        case kMIDIInvalidClient:     return "MIDI Invalid Client"
        case kMIDIInvalidPort:       return "MIDI Invalid Port"
        case kMIDIWrongEndpointType: return "MIDI Wrong Endpoint Type"
        case kMIDINoConnection:      return "MIDI No Connection"
        case kMIDIUnknownEndpoint:   return "MIDI Unknown Endpoint"
        case kMIDIUnknownProperty:   return "MIDI Unknown Property"
        case kMIDIWrongPropertyType: return "MIDI Wrong Property Type"
        case kMIDINoCurrentSetup:    return "MIDI No Current Setup"
        case kMIDIMessageSendErr:    return "MIDI Message Send Error"
        case kMIDIServerStartErr:    return "MIDI Server Start Error"
        case kMIDISetupFormatErr:    return "MIDI Setup Format Error"
        case kMIDIWrongThread:       return "MIDI Wrong Thread"
        case kMIDIObjectNotFound:    return "MIDI Object Not Found"
        case kMIDIIDNotUnique:       return "MIDI ID Not Unique"
        case kMIDINotPermitted:      return "MIDI Not Permitted"

        //***** AudioToolbox errors
        case kAudioToolboxErr_CannotDoInCurrentContext: return "AudioToolbox Cannot Do In Current Context"
        case kAudioToolboxErr_EndOfTrack:               return "AudioToolbox End Of Track"
        case kAudioToolboxErr_IllegalTrackDestination:  return "AudioToolbox Illegal Track Destination"
        case kAudioToolboxErr_InvalidEventType:         return "AudioToolbox Invalid Event Type"
        case kAudioToolboxErr_InvalidPlayerState:       return "AudioToolbox Invalid Player State"
        case kAudioToolboxErr_InvalidSequenceType:      return "AudioToolbox Invalid Sequence Type"
        case kAudioToolboxErr_NoSequence:               return "AudioToolbox No Sequence"
        case kAudioToolboxErr_StartOfTrack:             return "AudioToolbox Start Of Track"
        case kAudioToolboxErr_TrackIndexError:          return "AudioToolbox Track Index Error"
        case kAudioToolboxErr_TrackNotFound:            return "AudioToolbox Track Not Found"
        case kAudioToolboxError_NoTrackDestination:     return "AudioToolbox No Track Destination"

        //***** AudioUnit errors
        case kAudioUnitErr_CannotDoInCurrentContext: return "AudioUnit Cannot Do In Current Context"
        case kAudioUnitErr_FailedInitialization:     return "AudioUnit Failed Initialization"
        case kAudioUnitErr_FileNotSpecified:         return "AudioUnit File Not Specified"
        case kAudioUnitErr_FormatNotSupported:       return "AudioUnit Format Not Supported"
        case kAudioUnitErr_IllegalInstrument:        return "AudioUnit Illegal Instrument"
        case kAudioUnitErr_Initialized:              return "AudioUnit Initialized"
        case kAudioUnitErr_InvalidElement:           return "AudioUnit Invalid Element"
        case kAudioUnitErr_InvalidFile:              return "AudioUnit Invalid File"
        case kAudioUnitErr_InvalidOfflineRender:     return "AudioUnit Invalid Offline Render"
        case kAudioUnitErr_InvalidParameter:         return "AudioUnit Invalid Parameter"
        case kAudioUnitErr_InvalidProperty:          return "AudioUnit Invalid Property"
        case kAudioUnitErr_InvalidPropertyValue:     return "AudioUnit Invalid Property Value"
        case kAudioUnitErr_InvalidScope:             return "AudioUnit InvalidScope"
        case kAudioUnitErr_InstrumentTypeNotFound:   return "AudioUnit Instrument Type Not Found"
        case kAudioUnitErr_NoConnection:             return "AudioUnit No Connection"
        case kAudioUnitErr_PropertyNotInUse:         return "AudioUnit Property Not In Use"
        case kAudioUnitErr_PropertyNotWritable:      return "AudioUnit Property Not Writable"
        case kAudioUnitErr_TooManyFramesToProcess:   return "AudioUnit Too Many Frames To Process"
        case kAudioUnitErr_Unauthorized:             return "AudioUnit Unauthorized"
        case kAudioUnitErr_Uninitialized:            return "AudioUnit Uninitialized"
        case kAudioUnitErr_UnknownFileType:          return "AudioUnit Unknown File Type"
        case kAudioUnitErr_RenderTimeout:             return "AudioUnit Rendre Timeout"

        //***** AudioComponent errors
        case kAudioComponentErr_DuplicateDescription:   return "AudioComponent Duplicate Description"
        case kAudioComponentErr_InitializationTimedOut: return "AudioComponent Initialization Timed Out"
        case kAudioComponentErr_InstanceInvalidated:    return "AudioComponent Instance Invalidated"
        case kAudioComponentErr_InvalidFormat:          return "AudioComponent Invalid Format"
        case kAudioComponentErr_NotPermitted:           return "AudioComponent Not Permitted "
        case kAudioComponentErr_TooManyInstances:       return "AudioComponent Too Many Instances"
        case kAudioComponentErr_UnsupportedType:        return "AudioComponent Unsupported Type"

        //***** Audio errors
        case kAudio_BadFilePathError:      return "Audio Bad File Path Error"
        case kAudio_FileNotFoundError:     return "Audio File Not Found Error"
        case kAudio_FilePermissionError:   return "Audio File Permission Error"
        case kAudio_MemFullError:          return "Audio Mem Full Error"
        case kAudio_ParamError:            return "Audio Param Error"
        case kAudio_TooManyFilesOpenError: return "Audio Too Many Files Open Error"
        case kAudio_UnimplementedError:    return "Audio Unimplemented Error"

        default: return nil
        } // switch(self)
    } // detailedErrorMessage

    //**************************
    func debugLog(filePath: String = #file, line: Int = #line, funcName: String = #function) {
        guard isDebug, self != noErr else { return }
        let fileComponents = filePath.components(separatedBy: "/")
        let fileName = fileComponents.last ?? "???"

        var logString = "OSStatus = \(self) in \(fileName) - \(funcName), line \(line)"

        if let errorMessage = self.detailedErrorMessage() { logString = errorMessage + ", " + logString }
        else if let errorCode = self.asString()           { logString = errorCode    + ", " + logString }

        NSLog(logString)
    } // debugLog
} // extension OSStatus

SecCopyErrorMessageString is available from iOS 11.3 https://developer.apple.com/documentation/security/1542001-security_framework_result_codes

SecCopyErrorMessageString 可从 iOS 11.3 https://developer.apple.com/documentation/security/1542001-security_framework_result_codes 获得

回答by Albrecht

Use the OSX calc program. Select "programmer" mode in presentation menu. Then type your code in decimal représentation. Then choose the "ascii" button and the calc will show you the 4 char translation such as "!init", "!cat", etc...

使用 OSX 计算程序。在演示菜单中选择“程序员”模式。然后以十进制表示形式键入您的代码。然后选择“ascii”按钮,计算器将向您显示 4 个字符的翻译,例如“!init”、“!cat”等...

回答by KerCodex

I created an OSStatus extension that you may find useful. It logs a full error message for audio related errors, otherwise when possible the four-character-code, otherwise the OSStatus number that you could look-up in https://www.osstatus.com

我创建了一个 OSStatus 扩展,您可能会发现它很有用。它会记录音频相关错误的完整错误消息,否则可能会记录四字符代码,否则会记录您可以在https://www.osstatus.com 中查找的 OSStatus 编号

It furthers adds useful information like the file, the function and the line where the error occurred.

它进一步添加了有用的信息,如文件、函数和发生错误的行。

Here is the code:

这是代码:

//***** Create audioGraph
NewAUGraph(&audioGraph).debugLog()

//***** Testing .debugLog() OSStatus extension
kAUGraphErr_InvalidAudioUnit.debugLog()
OSStatus(560226676).debugLog()
OSStatus(-125).debugLog()

And usage would be:

用法是:

##代码##

The resulting logs for the three tests:

三个测试的结果日志:

2018-11-12 19:41:48.427606+0100 HexaSynth[5875:102611] AUGraph Invalid Audio Unit, OSStatus = -10864 in SoftSynthesizer.swift - init(soundFontFileName:), line 40

2018-11-12 19:41:48.427606+0100 HexaSynth[5875:102611] AUGraph 无效音频单元,SoftSynthesizer.swift 中的 OSStatus = -10864 - init(soundFontFileName:),第 40 行

2018-11-12 19:41:48.428403+0100 HexaSynth[5875:102611] !dat, OSStatus = 560226676 in SoftSynthesizer.swift - init(soundFontFileName:), line 41

2018-11-12 19:41:48.428403+0100 HexaSynth[5875:102611] !dat, OSStatus = 560226676 in SoftSynthesizer.swift - init(soundFontFileName:), line 41

2018-11-12 19:41:48.428638+0100 HexaSynth[5875:102611] OSStatus = -125 in SoftSynthesizer.swift - init(soundFontFileName:), line 42

2018-11-12 19:41:48.428638+0100 HexaSynth[5875:102611] OSStatus = -125 in SoftSynthesizer.swift - init(soundFontFileName:),第 42 行

回答by sprhawk

Most time maybe you just need to find the error code in the .h files

大多数情况下,您可能只需要在 .h 文件中找到错误代码

I just made a python script to find the code (when you debug/print a osstatus code)

我刚刚制作了一个python脚本来查找代码(当您调试/打印osstatus代码时)

https://github.com/sprhawk/MyGist/blob/master/tools/find_osstatus_error.py

https://github.com/sprhawk/MyGist/blob/master/tools/find_osstatus_error.py