我对这款iPhone SDK及其文档感到有点不舒服......
我打电话给AudioConverterNew
在返回下的文档中:它说“返回状态代码”......真的......
到目前为止,通过使用参数我只能得到两个不同的错误,这两个错误都没有列在音频转换器参考的底部。
它们是'mrep'和'?tmf'(将OSStatus转换为char数组)但具体代码并不是真正重要的。
据我所知,随机错误代码是在随机文件中定义的,因此您不能只搜索一个文件,我找不到只是让您搜索错误代码以获取更多信息的帮助文档,并且我可以告诉你,在OS X中,你可以使用GetMacOSStatusErrorString()将错误转换为有用的东西,但没有iPhone等价?
任何帮助将不胜感激。
编辑:
好的,所以投射它们反过来(我检查'mrep',但不是那里的任何一种方式),fmt?在音频转换器api的列表中,如果有点模糊,但是很公平,仍然'perm'不存在(尽管它可能与模拟器不支持aac解码有关)和我的一般问题仍然存在。
不,不完全。
一些OSStatus是四字符代码,因此您可以使用(从iPhone SDK示例代码中提取“qazxsw poi”)
CAXException.h
(有关将fourcc转换为字符串的更多方法,请参阅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] = '\0';
} else {
// no, format it as an integer
sprintf(str, "%d", (int)error);
}
return str;
}
,包括Swift)
NSError的NSOSStatusErrorDomain能够解码一些操作系统错误。见iOS/C: Convert "integer" into four character string。
如果您不需要为用户解码程序中的数字,您可以使用@tomk's answer脚本手动找出其含义,如macerror
中所述。支持的OSStatus列表可以从@lros's answer的源代码中找到。
还有一个在线服务/System/Library/Perl/Extras/5.18/Mac/Errors.pm
从所有公共框架收集错误。它们仍然不是很完整,例如缺少评论中提到的http://osstatus.com/映射。可能它是来自私有框架的代码。
如果要创建命令行实用程序,以便在开发和支持期间使用,那么您仍然可以使用已弃用的Carbon方法,即使在10.9(Mavericks)中也是如此。您显然无法在提交给Apple的应用程序中使用此功能,以便将其包含在App Store中。
https://github.com/sprhawk/MyGist/blob/master/tools/find_osstatus_error.py
编译:
#import <Foundation/Foundation.h>
#import <CoreServices/CoreServices.h>
int main(int argc, const char **argv)
{
@autoreleasepool {
for (int i = 1; i < argc; i++) {
char *endp;
long value = strtol(argv[i], &endp, 10);
if (*endp == '\0') {
printf("%10ld: %s (%s)\n",
value,
GetMacOSStatusCommentString((OSStatus)value),
GetMacOSStatusErrorString((OSStatus)value));
} else {
fprintf(stderr, "Invalid OSStatus code '%s' ignored\n", argv[i]);
}
}
}
}
把它复制到你的$ clang -fobjc-arc -o osstatus osstatus.m -framework Foundation -framework CoreServices
的某个地方:
$PATH
并从日志文件或错误报告中提供错误代码:
$ cp osstatus ~/bin
如果没有描述字符串,则可以方便地将OSStatus值转换为看起来像四个字符定义的字符串。至少那时你可以grep标题,希望找到关于状态意味着什么的评论。
$ osstatus -47
-47: File is busy (delete) (fBsyErr)
这不是OP问题的直接答案,但我认为对于关注这些OSStatus返回码的人来说它会有用:
在Xcode文档(管理器)中搜索关键字“结果代码”,我们在“系统指南”结果中获得或多或少的返回代码文档部分。
如果您只需要在自定义函数中直接使用某些代码,它们就会非常有用。
OSStatus错误可以是表示4-char代码的字节,也可以是// declaration: extern CFStringRef CreateTypeStringWithOSType(OSType inType);
OSStatus result = ...;
if (result != noErr) {
NSString *statusString = (NSString *)CreateTypeStringWithOSType(result);
NSLog(@"Error while $VERBing: %@", statusString);
[statusString release]; // because "Create..."
statusString = nil;
}
中定义的任意数量的错误。
如果OSStatus错误是MacErrors.h
或0
,则表示您没有错误。
或者,尝试在noErr
中查找错误号:
MacErrors.h
对于IOS上的安全框架,假设平台上缺少SecCopyErrorMessageString,那就是DYI
在底部添加错误代码
static NSString *stringForOSStatus(OSStatus status)
{
NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.apple.security"];
NSString *key = [NSString stringWithFormat:@"%d", status];
return [bundle localizedStringForKey:key value:key table:@"SecErrorMessages"];
}
到你自己的开关。
例如
https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices
这就是你需要的 let status : OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
switch status {
case errSecSuccess:
return nil
case errSecAuthFailed:
// that's the result of dumping kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly into the query
return "changing app lock type on a device without fingerprint and/or passcode setup is not allowed".localized
default:
return "unhandled case: implement this"
}
。只搜索给定的OSStatus。
我创建了一个您可能觉得有用的OSStatus扩展。它记录了与音频相关的错误的完整错误消息,否则在可能的情况下会记录四个字符的代码,否则您可以在https://www.osstatus.com/中查找OSStatus编号
它进一步增加了有用的信息,如文件,函数和发生错误的行。
这是代码:
https://www.osstatus.com
用法是:
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
三个测试的结果日志:
2018-11-12 19:41:48.427606 + 0100 HexaSynth [5875:102611] AUGraph无效音频单元,OSSatus = -10864在SoftSynthesizer.swift中 - init(soundFontFileName :),第40行
2018-11-12 19:41:48.428403 + 0100 HexaSynth [5875:102611]!Dat,OSStatus = 560226676 in SoftSynthesizer.swift - init(soundFontFileName :),第41行
2018-11-12 19:41:48.428638 + 0100 HexaSynth [5875:102611] SoftSynthesizer.swift中的OSS状态= -125 - init(soundFontFileName :),第42行
对于iOS 11.3+,我在//***** Create audioGraph
NewAUGraph(&audioGraph).debugLog()
//***** Testing .debugLog() OSStatus extension
kAUGraphErr_InvalidAudioUnit.debugLog()
OSStatus(560226676).debugLog()
OSStatus(-125).debugLog()
上使用了扩展...
OSStatus
你可以称之为......
extension OSStatus {
var error: NSError? {
guard self != errSecSuccess else { return nil }
let message = SecCopyErrorMessageString(self, nil) as String? ?? "Unknown error"
return NSError(domain: NSOSStatusErrorDomain, code: Int(self), userInfo: [
NSLocalizedDescriptionKey: message])
}
}
写完之后我注意到这与@ RomanMykitchak之前的答案非常接近(所以请给他一个upvote) - 但我会留在这里,因为扩展可能对某人有用。
OSStatus错误; ... printf(“%s”,(char *)&err);
OSStatus是带符号的整数值。您无法将其转换或“转换”为字符串。您可以将它转换为NSError,如下所示:
-12792
我最近遇到了另一种方法:macerror命令。将OSStatus值打印为带符号整数。然后在终端窗口(在Mac上,而不是你的iDevice!)类型,例如macerror -50。它将以简短的描述作出回应。显然,这只对您在开发过程中有所帮助。
这是我写的代码,希望它能为你节省一些打字...呃,不知道怎么让它显示正确。
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
这适用于macOS和iOS 11.3及以上版本。
我知道这是一个老帖子,但我在与钥匙链相关的部分阅读- (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";
}
}
。他们提到了一种用于将OSStatus错误转换为可读内容的方法。
SecCopyErrorMessageString
返回一个解释安全结果代码含义的字符串。
SecCopyErrorMessageString(OSStatus status,void * reserved);
用途:
the apple docs
我的钥匙串OSStatus错误对我有用。对你起作用吗?您需要将Security.Framework添加到项目中才能使用此方法。
我最近发现这个非常好的网站,它适用于我抛出的每一个状态值。它比用于浏览框架头文件更加用户友好:NSString* ErrMsg = (__bridge_transfer NSString *) SecCopyErrorMessageString(theOSStatusError, NULL);
我结合了几个答案。其实我看起来像是“抛出errorForStatusCode(status)”。但最终实现了:
http://www.osstatus.com/
SecCopyErrorMessageString可从iOS 11.3 guard status == errSecSuccess else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: SecCopyErrorMessageString(status, nil) ?? "Undefined error"])
}
获得
使用OSX计算程序。在演示菜单中选择“程序员”模式。然后在十进制représentation中键入您的代码。然后选择“ascii”按钮,calc会显示4个字符的翻译,例如“!init”,“!cat”等...
大多数时候你可能只需要在.h文件中找到错误代码
我刚刚创建了一个python脚本来查找代码(当你调试/打印osstatus代码时)
https://developer.apple.com/documentation/security/1542001-security_framework_result_codes