it-swarm.com.ru

Как конвертировать код iPhone OSStatus во что-то полезное?

Я больше чем тошнит от этого iPhone SDK и его документации ...

Я звоню AudioConverterNew

в документации в разделе «Возвраты» указано «возвращает код состояния» ... действительно ...

до сих пор, играя с параметрами, я смог получить только две разные ошибки, ни одна из которых не указана в нижней части справочника Audio Converter.

это 'mrep' и '? tmf' (приведение OSStatus к массиву символов), но конкретные коды на самом деле не имеют значения.

насколько я могу судить, случайные коды ошибок определены в случайных файлах, поэтому вы не можете просто искать один файл, я не могу найти справочный документ, который просто позволяет вам искать код ошибки, чтобы получить больше информации, и от Что я могу сказать, в OS X вы можете использовать GetMacOSStatusErrorString (), чтобы преобразовать ошибку во что-то полезное, но нет эквивалента iPhone?

любая помощь будет принята с благодарностью.

Правка:

хорошо, поэтому приведение их дает их в обратном порядке (что-то, что я проверил на «mrep», но не было в любом случае), fmt? находится в списке для Audio Converter api, и довольно понятен, если немного расплывчатый, но достаточно справедливый, все же «perm» не существует (хотя это может быть что-то, что связано с симулятором, не поддерживающим декодирование aac) и мой общий вопрос все еще стоит.

61
matt

Нет, не полностью.

Некоторые 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] = '\0';
    } else {
        // no, format it as an integer
        sprintf(str, "%d", (int)error);
    }
    return str;
}

(См. iOS/C: преобразование «целого числа» в строку из четырех символов для некоторых других способов преобразования fourcc в строку, включая Swift)

NSOSStatusErrorDomain NSError способен декодировать некоторые ошибки ОС. Смотрите @ Томк ответ .

Если вам не нужно декодировать номер в программе для пользователя, вы можете использовать скрипт macerror, чтобы вручную выяснить значение, как указано в @ lros's answer . Список поддерживаемых OSStatus можно найти в его исходном коде в /System/Library/Perl/Extras/5.18/Mac/Errors.pm

Существует также онлайн-сервис http://osstatus.com/ сбор ошибок из всех общедоступных платформ. Они еще не совсем завершены, например Упомянутое в комментарии сопоставление с -12792 отсутствует. Возможно, это код из частного фреймворка.

30
kennytm

OSStatus является целочисленным значением со знаком. Вы не можете преобразовать или «привести» его к строке. Вы можете преобразовать его в NSError следующим образом:

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

88
tomk

Недавно я столкнулся с другим подходом: командой macerror. Выведите значение OSStatus в виде целого числа со знаком. Затем в окне терминала (на вашем Mac, а не на iDevice!) Введите, например, macerror -50 . Он ответит с кратким описанием. Очевидно, что это полезно только для вас, во время разработки.

13
lros

Вот код, который я написал, надеюсь, это сэкономит вам время на ввод текста ... э-э, не знаю, как заставить его правильно отображаться.

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

Это доступно на macOS и для iOS от 11.3 и выше.

Я знаю, что это старый пост, но я читал документы Apple в разделе, связанном с цепочками для ключей. Они упоминают метод, который используется для преобразования ошибок OSStatus в нечто читаемое.

SecCopyErrorMessageString

Возвращает строку, объясняющую смысл кода результата безопасности.

SecCopyErrorMessageString (статус OSStatus, пусто * зарезервировано);

Useage: 

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

Это работало для меня с моими ошибками OSStatus цепочки для ключей. Работает ли это для вас? Вам нужно будет добавить Security.Framework в ваш проект, чтобы использовать этот метод.

10

Я объединил несколько ответов. На самом деле я искал что-то вроде «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

4
Roman Mykitchak

Я недавно нашел этот действительно хороший веб-сайт, который работает для каждого значения статуса, которое я выбрасывал. Это намного удобнее для пользователя, чем просмотр файлов заголовков фреймворка: http://www.osstatus.com/

4
Earlz

Используйте программу OSX calc. Выберите режим «программист» в меню презентации .... Затем введите свой код в десятичном представлении. Затем нажмите кнопку «ascii», и calc покажет вам перевод на 4 символа, такой как «! Init», «! Cat» и т.д.

4
Albrecht

Если вы хотите создать утилиту командной строки для использования во время разработки и поддержки, вы все равно можете использовать устаревшие методы Carbon, даже в 10.9 (Mavericks). Очевидно, вы не можете использовать это в приложении, которое вы отправляете в Apple для включения в App Store.

#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)
2
trojanfoe

В большинстве случаев, возможно, вам просто нужно найти код ошибки в файлах .h

Я только что сделал скрипт Python, чтобы найти код (когда вы отлаживаете/печатаете код osstatus)

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

2
sprhawk

При отсутствии строки описания удобно конвертировать значения OSStatus в строки, которые выглядят как их четырехсимвольные определения. По крайней мере, тогда вы можете получить заголовки в надежде найти комментарий о том, что означает статус.

// 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;
}
2
Shon

Это может помочь.

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

Это не прямой ответ на вопрос OP, но я думаю, что это будет полезно для тех, кто имеет отношение к этим кодам возврата OSStatus:

Выполните поиск по ключевому слову «Коды результата» в документации XCode (Организатор), и мы получим более или менее категоризированные разделы документации кодов возврата в результате «Системные руководства». 

Если вам просто нужно использовать некоторые коды непосредственно в ваших пользовательских функциях, они очень полезны.

1
kakyo

Ошибки OSStatus могут быть байтами, представляющими 4-символьный код, или любым количеством ошибок, определенных в MacErrors.h.

Если ошибка OSStatus - 0 или noErr, это означает, что у вас нет ошибок. 

Или попробуйте найти свой номер ошибки в MacErrors.h:

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

1
inorganik

для платформы безопасности в IOS, учитывая, что SecCopyErrorMessageString отсутствует на платформе, это DYI

добавить коды ошибок внизу

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"
        }
1
Anton Tropashko

Я создал расширение OSStatus, которое может оказаться полезным. Он регистрирует полное сообщение об ошибках, связанных со звуком, в противном случае, когда это возможно, четырехзначный код, в противном случае номер 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

И использование будет:

//***** 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] Недопустимый аудиоблок AUGraph, OSStatus = -10864 в SoftSynthesizer.Swift - init (soundFontFileName :), строка 40

2018-11-12 19: 41: 48.428403 + 0100 HexaSynth [5875: 102611]! Dat, OSStatus = 560226676 в SoftSynthesizer.Swift - init (soundFontFileName :), строка 41

2018-11-12 19: 41: 48.428638 + 0100 HexaSynth [5875: 102611] OSStatus = -125 в SoftSynthesizer.Swift - init (soundFontFileName :), строка 42

0
KerCodex

Для iOS 11.3+ я использую расширение на 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])
    }
}

который вы можете назвать как ...

let status = SecItemAdd(attributes as CFDictionary, nil)

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

Написав это, я заметил, что это очень близко к более раннему ответу @ RomanMykitchak (поэтому, пожалуйста, дайте ему ответ), но я оставлю это здесь, так как расширение может оказаться полезным для кого-то.

0
Ashley Mills

Это то, что вам нужно https://www.osstatus.com/ . Просто найдите данный OSStatus.

0
Boris Nikolić