web-dev-qa-db-fra.com

Comment convertir un code iPhone OSStatus en un élément utile?

J'en ai plus qu'un peu marre de ce SDK pour iPhone et de sa documentation ...

J'appelle AudioConverterNew

dans la documentation sous Retours: il est écrit "renvoie un code d'état" ... vraiment ...

jusqu'à présent, en jouant avec les paramètres, je n'ai pu obtenir que deux erreurs différentes dont aucune n'est répertoriée au bas de la référence du convertisseur audio.

ils sont 'mrep' et '? tmf' (transtyper OSStatus dans un tableau de caractères), mais les codes spécifiques ne sont pas vraiment importants.

autant que je sache, les codes d'erreur aléatoires sont définis dans des fichiers aléatoires. Vous ne pouvez donc pas rechercher dans un seul fichier. Je ne trouve pas de document d'aide qui vous permet simplement de rechercher un code d'erreur pour obtenir plus d'informations. Ce que je peux dire, sous OS X, vous pouvez utiliser GetMacOSStatusErrorString () pour convertir une erreur en quelque chose d’utile, mais il n’existe pas d’équivalent iPhone.

toute aide serait grandement appréciée.

MODIFIER:

ok, donc les couler leur donne à l'envers (quelque chose que j'ai vérifié pour 'mrep' mais n'y était pas de toute façon), fmt? est dans la liste pour l’API Audio Converter, et est assez explicite, même s’il est un peu vague, mais «perm» n’est toujours pas là (bien que cela puisse être dû au fait que le simulateur ne prend pas en charge le décodage aac) La question générale est toujours d'actualité.

61
matt

Non, pas complètement.

Certains OSStatus sont des codes à quatre caractères, vous pouvez donc les utiliser (extraits du code exemple "CAXException.h" du SDK iPhone)

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

(Voir iOS/C: convertissez "entier" en chaîne de quatre caractères pour davantage de moyens de convertir des fichiers Fourcc en chaîne, y compris Swift)

NSOSStatusErrorDomain de NSError est capable de décoder certaines erreurs du système d'exploitation. Voir la réponse de @ tomk .

Si vous n'avez pas besoin de décoder le numéro dans le programme pour l'utilisateur, vous pouvez utiliser le script macerror pour rechercher manuellement la signification, comme indiqué dans La réponse de @ lros . La liste des statuts OSS supportés est disponible à partir de son code source dans /System/Library/Perl/Extras/5.18/Mac/Errors.pm

Il existe également un service en ligne http://osstatus.com/ qui collecte les erreurs dans tous les cadres publics. Ils ne sont pas encore vraiment complets, par exemple. le mappage à -12792 mentionné dans le commentaire est manquant. C'est probablement un code provenant d'un framework privé.

30
kennytm

OSStatus est une valeur entière signée. Vous ne pouvez pas convertir ou "convertir" en une chaîne. Vous pouvez le convertir en NSError comme ceci:

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

88
tomk

J'ai récemment rencontré une autre approche: la commande macerror. Imprimez la valeur OSStatus sous forme d’entier signé. Puis, dans une fenêtre de terminal (sur votre Mac, pas sur votre iDevice!), Tapez par exemple macerror -50 . Il répondra avec une brève description. Évidemment, cela ne vous est utile que pendant le développement.

13
lros

Voici le code que j'ai écrit, j'espère que cela vous épargnera quelques saisies ... euh, je ne sais pas comment le faire apparaître correctement.

- (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

Ceci est disponible sur macOS et pour iOS à partir de 11.3 et plus.

Je sais que ceci est un ancien post, mais je lisais les documents Apple dans une section relative aux porte-clés. Ils mentionnent une méthode utilisée pour convertir les erreurs OSStatus en quelque chose de lisible.

SecCopyErrorMessageString

Retourne une chaîne expliquant la signification d'un code de résultat de sécurité.

SecCopyErrorMessageString (statut OSStatus, void * réservé);

Utilisation: 

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

Cela a fonctionné pour moi avec mes erreurs OSStatus de trousseau. Ça marche pour toi? Vous aurez besoin de Security.Framework ajouté à votre projet pour utiliser cette méthode.

J'ai combiné quelques réponses. En fait, je cherchais quelque chose comme "throw errorForStatusCode (status)" .. Mais à la fin, j'ai obtenu:

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

SecCopyErrorMessageString est disponible sur iOS 11.3 https://developer.Apple.com/documentation/security/1542001-security_framework_result_codes

4
Roman Mykitchak

J'ai récemment trouvé ce site vraiment sympa qui a fonctionné pour chaque valeur de statut que j'ai lancée. C'est beaucoup plus convivial que de passer par les fichiers d'en-tête du framework: http://www.osstatus.com/

4
Earlz

Utilisez le programme OSX calc. Sélectionnez le mode "programmeur" dans le menu de présentation . Tapez ensuite votre code en représentation décimale. Puis choisissez le bouton "ascii" et le calculateur vous montrera la traduction de 4 caractères telle que "! Init", "! Cat", etc ...

4
Albrecht

Si vous souhaitez créer un utilitaire de ligne de commande, à utiliser lors du développement et de la prise en charge, vous pouvez toujours utiliser les méthodes Carbon obsolètes, même dans 10.9 (Mavericks). Vous ne pouvez évidemment pas utiliser cela dans une application que vous soumettez à Apple pour inclusion dans les App Stores.

#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]);
            }
        }
    }
}

Compiler avec:

$ clang -fobjc-arc -o osstatus osstatus.m -framework Foundation -framework CoreServices

copiez-le quelque part dans votre $PATH:

$ cp osstatus ~/bin

et alimentez-le avec les codes d'erreur de vos fichiers journaux ou de vos rapports d'erreur:

$ osstatus -47
   -47: File is busy (delete) (fBsyErr)
2
trojanfoe

La plupart du temps, vous aurez peut-être simplement besoin de trouver le code d'erreur dans les fichiers .h

Je viens de créer un script python pour trouver le code (lorsque vous déboguez/imprimez un code osstatus)

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

2
sprhawk

À défaut d'une chaîne de description, il est pratique de convertir les valeurs OSStatus en chaînes qui ressemblent à leurs définitions à quatre caractères. Au moins, vous pouvez alors créer des en-têtes dans l'espoir de trouver un commentaire sur la signification du statut.

// 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

Cela pourrait être une aide.

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

Ce n'est pas une réponse directe à la question de OP, mais je pense que cela sera utile à quiconque est concerné par ces codes de retour OSStatus:

Recherchez le mot clé "Codes de résultat" dans la documentation Xcode (Organiseur) et vous obtiendrez des sections de documentation de codes de retour plus ou moins catégorisées dans le résultat "Guides système". 

Si vous avez juste besoin d'utiliser des codes directement dans vos fonctions personnalisées, ils sont très utiles.

1
kakyo

Les erreurs OSStatus peuvent être des octets représentant un code à 4 caractères ou un nombre quelconque d’erreurs défini dans MacErrors.h.

Si une erreur OSStatus est 0 ou noErr, cela signifie que vous n'avez aucune erreur. 

Ou essayez de rechercher votre numéro d'erreur dans MacErrors.h:

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

1
inorganik

pour la structure de sécurité sur IOS étant donné que SecCopyErrorMessageString est manquant sur la plateforme, il s'agit de DYI

ajouter des codes d'erreur au bas de

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

à votre propre commutateur.

par exemple

        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

J'ai créé une extension OSStatus que vous pouvez trouver utile. Il enregistre un message d'erreur complet pour les erreurs liées au son, sinon, lorsque cela est possible, le code à quatre caractères, sinon le numéro OSStatus que vous pourriez rechercher dans https://www.osstatus.com

Il ajoute ensuite des informations utiles telles que le fichier, la fonction et la ligne où l'erreur s'est produite.

Voici le code:

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

Et l'utilisation serait:

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

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

Les journaux résultants pour les trois tests:

2018-11-12 19: 41: 48.427606 + 0100 HexaSynth [5875: 102611] Unité audio AUGraph non valide, OSStatus = -10864 dans SoftSynthesizer.Swift - init (soundFontFileName :), ligne 40

2018-11-12 19: 41: 48.428403 + 0100 HexaSynth [5875: 102611]! Dat, OSStatus = 560226676 dans SoftSynthesizer.Swift - init (soundFontFileName :), ligne 41

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

0
KerCodex

Pour iOS 11.3+, j'utilise une extension sur 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])
    }
}

que vous pouvez appeler comme…

let status = SecItemAdd(attributes as CFDictionary, nil)

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

Après avoir écrit ceci, j'ai remarqué que ceci est très proche de la réponse précédente de @ RomanMykitchak (donc donnez-lui le vote positif) - mais je le laisse ici car l'extension pourrait s'avérer utile pour quelqu'un.

0
Ashley Mills

C’est ce dont vous avez besoin https://www.osstatus.com/ . Il vous suffit de rechercher un statut OSS donné.

0
Boris Nikolić