UFO ET IT

iPhone OSStatus 코드를 유용한 것으로 어떻게 변환합니까?

ufoet 2020. 11. 22. 20:58
반응형

iPhone OSStatus 코드를 유용한 것으로 어떻게 변환합니까?


이 iPhone SDK와 설명서에 조금 이상이 있습니다.

AudioConverterNew를 호출하고 있습니다.

반품 아래의 문서에서 "상태 코드를 반환합니다"라고되어 있습니다 ... 정말 ...

지금까지 매개 변수를 가지고 놀면서 오디오 변환기 참조의 맨 아래에 나열되지 않은 두 가지 다른 오류 만 얻을 수있었습니다.

그들은 'mrep'과 '? tmf'(OSStatus를 char 배열로 캐스팅)이지만 특정 코드가 실제로 중요한 것은 아닙니다.

내가 알 수있는 한, 임의의 오류 코드는 임의의 파일에 정의되어 있으므로 하나의 파일 만 검색 할 수없고 오류 코드를 검색하여 더 많은 정보를 얻을 수있는 도움말 문서를 찾을 수 없습니다. 내가 말할 수있는 것은 OS X에서 GetMacOSStatusErrorString ()을 사용하여 오류를 유용한 것으로 변환 할 수 있지만 iPhone에 해당하는 것은 없습니까?

어떤 도움이라도 대단히 감사하겠습니다.

편집하다:

좋아, 그래서 그들을 캐스팅하면 역으로 제공됩니다 ( 'mrep'을 확인했지만 어느 쪽이든 없었습니다), fmt? Audio Converter api의 목록에 있으며 약간 모호하지만 충분히 공정하지만 여전히 'perm'이 없으면 꽤 자명합니다 (AAC 디코딩을 지원하지 않는 시뮬레이터와 관련이있을 수 있지만) 일반적인 질문은 여전히 ​​남아 있습니다.


아뇨. 완전하지는 않습니다.

일부 OSStatus는 4 자 코드이므로 사용할 수 있습니다 (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] = '\0';
    } else {
        // no, format it as an integer
        sprintf(str, "%d", (int)error);
    }
    return str;
}

( iOS / C : Swift를 포함하여 fourcc를 문자열로 변환하는 몇 가지 더 많은 방법은 "integer"를 4 개의 문자열로 변환을 참조하십시오 )

NSError의 NSOSStatusErrorDomain은 일부 OS 오류를 디코딩 할 수 있습니다. @tomk의 대답을 참조하십시오 .

사용자를 위해 프로그램에서 번호를 디코딩 할 필요가없는 경우 @lros의 답변macerror 에서 언급했듯이 스크립트를 사용하여 수동으로 의미를 찾을 수 있습니다 . 지원되는 OSStatus 목록은의 소스 코드에서 찾을 수 있습니다 ./System/Library/Perl/Extras/5.18/Mac/Errors.pm

모든 공용 프레임 워크에서 오류를 수집 하는 온라인 서비스 http://osstatus.com/ 도 있습니다 . -12792주석 언급 된 매핑 이 누락되었습니다. 아마도 그것은 개인 프레임 워크의 코드 일 것입니다.


OSStatus는 부호있는 정수 값입니다. 문자열로 변환하거나 "캐스트"할 수 없습니다. 다음과 같이 NSError로 변환 할 수 있습니다.

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


최근에 또 다른 접근 방식 인 macerror 명령을 발견했습니다. OSStatus 값을 부호있는 정수로 인쇄합니다. 그런 다음 터미널 창 (iDevice가 아닌 Mac에서)에 예를 들어 macerror -50을 입력합니다 . 간단한 설명으로 응답합니다. 분명히 이것은 개발 중에 만 도움이됩니다.


내가 작성한 코드는 다음과 같습니다. 타이핑을 덜어 주길 바랍니다 ... 어, 올바르게 표시되도록 만드는 방법을 모르겠습니다.

- (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";
    }
}

이는 macOS 및 iOS 용 11.3 이상에서 사용할 수 있습니다.

나는 이것이 오래된 게시물이라는 것을 알고 있지만 키 체인과 관련된 섹션에서 사과 문서읽고있었습니다 . 그들은 OSStatus 오류를 읽을 수있는 것으로 변환하는 데 사용되는 방법을 언급합니다.

SecCopyErrorMessageString

보안 결과 코드의 의미를 설명하는 문자열을 반환합니다.

SecCopyErrorMessageString (OSStatus 상태, void * 예약 됨);

사용법 :

NSString* ErrMsg = (__bridge_transfer NSString *) SecCopyErrorMessageString(theOSStatusError, NULL);

내 키 체인 OSStatus 오류로 나를 위해 일했습니다. 당신을 위해 작동합니까? 당신이 필요합니다 Security.Framework이 이 방법을 사용하려면 프로젝트에 추가.


나는 최근에 내가 던진 모든 상태 값에 대해 작동하는이 정말 멋진 웹 사이트를 발견했습니다. 프레임 워크 헤더 파일 ( http://www.osstatus.com/)을 살펴 보는 것보다 훨씬 사용자 친화적입니다 .


몇 가지 답변을 결합했습니다. 실제로 나는 "throw errorForStatusCode (status)"와 같은 것을보고 있었다. 그러나 결국 달성 :

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

SecCopyErrorMessageString은 iOS 11.3 https://developer.apple.com/documentation/security/1542001-security_framework_result_codes 에서 사용할 수 있습니다.


OSX 계산 프로그램을 사용합니다. 프리젠 테이션 메뉴에서 "프로그래머"모드를 선택합니다. 그런 다음 십진수 표현으로 코드를 입력하십시오. 그런 다음 "ascii"버튼을 선택하면 "! init", "! cat"등과 같은 4 자 번역이 계산에 표시됩니다.


대부분의 경우 .h 파일에서 오류 코드를 찾아야 할 수도 있습니다.

방금 코드를 찾기 위해 Python 스크립트를 만들었습니다 (osstatus 코드를 디버그 / 인쇄 할 때).

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


개발 및 지원 중에 사용할 명령 줄 유틸리티를 만들려면 10.9 (Mavericks)에서도 더 이상 사용되지 않는 Carbon 메서드를 사용할 수 있습니다. App Store에 포함시키기 위해 Apple에 제출하는 앱에서는 분명히 이것을 사용할 수 없습니다.

#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 -47
   -47: File is busy (delete) (fBsyErr)

설명 문자열이 실패하면 OSStatus 값을 4 자 정의처럼 보이는 문자열로 변환하는 것이 편리합니다. 적어도 상태가 의미하는 바에 대한 주석을 찾기 위해 헤더를 grep 할 수 있습니다.

// 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 확장 프로그램을 만들었습니다. 오디오 관련 오류에 대한 전체 오류 메시지를 기록합니다. 그렇지 않으면 가능한 경우 4 자 코드, 그렇지 않으면 https://www.osstatus.com 에서 조회 할 수있는 OSStatus 번호를 기록합니다.

또한 파일, 함수 및 오류가 발생한 줄과 같은 유용한 정보를 추가합니다.

다음은 코드입니다.

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

그리고 사용법은 다음과 같습니다.

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

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

세 가지 테스트에 대한 결과 로그 :

2018-11-12 19 : 41 : 48.427606 + 0100 HexaSynth [5875 : 102611] SoftSynthesizer.swift의 AUGraph 잘못된 오디오 유닛, OSStatus = -10864-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] OSStatus = -125 in SoftSynthesizer.swift - init(soundFontFileName:), line 42


This is not a direct answer to OP's question, but I think it will be useful to whoever is concerned with these OSStatus return codes:

Search for keyword "Result Codes" in Xcode documentation (Organizer) and we get a more or less categorized return codes documentation sections in the "System Guides" result.

If you just need to use some codes directly in your custom functions, they are very helpful.


OSStatus errors can be bytes representing a 4-char code, or any number of errors defined in MacErrors.h.

If an OSStatus error is 0 or noErr that means you have no error.

Or, try looking up your error number in MacErrors.h:

http://www.opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/MacErrors.h


This might be help.

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"];
}

for Security framework on IOS given that SecCopyErrorMessageString is missing on the platform it's DYI

add error codes at the bottom of

https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices

to your very own switch.

for example

        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"
        }

This is what you need https://www.osstatus.com/. Just search for given OSStatus.


For iOS 11.3+, I'm using an extension on 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])
    }
}

which you can call like…

let status = SecItemAdd(attributes as CFDictionary, nil)

if let error = status.error {
    throw error
}    
// etc

Having written this I noticed this is very close to @RomanMykitchak's earlier answer (so please give him the upvote) - but I'll leave it here as the extension might prove useful to someone.


OSStatus err; ... printf("%s", (char*)&err);

참고URL : https://stackoverflow.com/questions/2196869/how-do-you-convert-an-iphone-osstatus-code-to-something-useful

반응형