73 votes

Erreur d'accès au code dans Swift 3

Nouveau dans Xcode 8 beta 4, NSError est relié au Swift Error type de protocole. Cela affecte StoreKit lorsqu'il traite les échecs SKPaymentTransaction s. Vous devez vérifier que l'erreur ne s'est pas produite parce que la transaction a été annulée pour savoir s'il faut ou non afficher un message d'erreur à l'utilisateur. Pour ce faire, vous examinez le message d'erreur code . Mais avec Error au lieu de NSError il n'y a pas de code défini. Je n'ai pas réussi à comprendre comment obtenir correctement le code d'erreur à partir de Error .

Cela fonctionnait dans la version précédente de Swift 3 :

func failedTransaction(_ transaction: SKPaymentTransaction) {
    if let transactionError = transaction.error {
        if transactionError.code != SKErrorCode.paymentCancelled.rawValue {
            //show error to user
        }
     }
     ...
}

Maintenant que error est un Error no NSError , code n'est pas un membre.

1 votes

Essayez if (transaction.error as NSError).code != SKErrorCode.PaymentCancelled {

1 votes

Cela fonctionne, il suffit de le couler comme un NSError Merci @LeoDabus

141voto

Leo Dabus Points 122890

Une autre option pour accéder aux propriétés du code et du domaine dans les types d'erreur de Swift 3 consiste à les étendre comme suit :

extension Error {
    var code: Int { return (self as NSError).code }
    var domain: String { return (self as NSError).domain }
}

4 votes

Consultez la réponse de @murray-sagal, il est préférable d'utiliser le SKError nouvellement fourni, plutôt que de revenir aux objets Objective-C.

56voto

Andrey M. Points 1080

Maintenant, dans Xcode 8 et swift 3, le cast conditionnel est toujours réussi, donc vous devez faire ce qui suit :

let code = (error as NSError).code

et vérifiez le code pour vos besoins. J'espère que cela vous aidera

42voto

Murray Sagal Points 1053

Casting à SKError semble fonctionner pour moi dans xCode 8 et Swift 3...

    guard let error = transaction.error as? SKError else {return}
    switch error.code {  // https://developer.apple.com/reference/storekit/skerror.code
    case .unknown: break
    case .paymentCancelled: break
    case .clientInvalid: break
    case .paymentInvalid: break
    case .paymentNotAllowed: break
    case .cloudServiceNetworkConnectionFailed: break
    case .cloudServicePermissionDenied: break
    case .storeProductNotAvailable: break
    }

Pas besoin de rawValue .

0 votes

Mise à jour de la réponse correcte à celle-ci car elle est la plus correcte. Il est préférable de procéder de cette manière plutôt que d'utiliser la méthode NSError . Confirmé qu'il fonctionne.

0 votes

C'est pas génial ? J'ai exactement le même problème mais dans ALAssets. Mais il ne semble pas y avoir d'équivalent SKError à cet endroit.

0 votes

@Joey Apple avait supprimé SKError de l'API publique d'iOS 11 sur Xcode 9 betas 1 et 2. C'était un bug qui a été corrigé sur Xcode 9 beta 3. Il faudra maintenant utiliser "SwiftyStoreKit" !

12voto

Rob Points 1464

C'est correct (les propres tests d'Apple utilisent cette approche) :

if error._code == SKError.code.paymentCancelled.rawValue { ... }

D'un autre côté, le moulage vers NSError sera probablement bientôt déprécié :

let code = (error as NSError).code // CODE SMELL!!
if code == SKError.code.paymentCancelled.rawValue { ... }

0 votes

Existe-t-il un lien vers l'approche utilisée par les propres tests d'Apple ?

0 votes

Eh bien, @AndrewPaulSimmons, il n'y avait pas de lien clair et net, mais si vous consultez le repo Git d'Apple pour Swift et que vous recherchez "_code", vous pouvez voir tous leurs propres tests où ils traitent l'objet Error de cette manière. Allez voir : github.com/apple/swift/search?utf8=%E2%9C%93&q=_code

8 votes

Vous considérez que le casting vers la bonne classe est une odeur de code, mais que l'accès externe aux membres soulignés est correct ? Accordé que vous devriez accéder à .code dans un if let ou un guard let et pas seulement en supposant aveuglément que le casting a fonctionné.

1voto

Gurjit Singh Points 595

Utilisez

error._code == NSURLErrorCancelled

pour correspondre au code d'erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X