En Objective-C, j'appelle la méthode NSSetUncaughtExceptionHandler(&exceptionHandler)
pour consigner les exceptions. Comment ça s'appelle à Swift?
Avec Swift 2, vous pouvez transmettre des fonctions et des fermetures Swift en tant que pointeur de fonction C. Voir la réponse de Martin R ci-dessous .
Vous ne pouvez pas, à partir de Xcode 6 beta 6.
Swift prend en charge le transfert des pointeurs de fonction, mais ils sont traités à peu près comme des pointeurs opaques. Vous ne pouvez pas non plus définir un pointeur de fonction C sur une fonction Swift, ni appeler un pointeur de fonction C dans Swift.
Cela signifie que vous appelez NSSetUncaughtExceptionHandler()
depuis Swift, mais que le gestionnaire doit être implémenté dans Objective-C. Vous avez besoin d'un fichier d'en-tête comme ceci:
volatile void exceptionHandler(NSException *exception);
extern NSUncaughtExceptionHandler *exceptionHandlerPtr;
et dans la mise en œuvre, vous avez besoin de quelque chose comme ceci:
volatile void exceptionHandler(NSException *exception) {
// Do stuff
}
NSUncaughtExceptionHandler *exceptionHandlerPtr = &exceptionHandler;
Après avoir importé le fichier d'en-tête dans l'en-tête de pontage Swift, vous pouvez configurer le gestionnaire d'exceptions comme d'habitude:
NSSetUncaughtExceptionHandler(exceptionHandlerPtr)
À partir de Swift 2 (Xcode 7), vous pouvez passer les fonctions/fermetures Swift Aux paramètres prenant un pointeur de fonction C. À partir des notes de publication de Xcode 7:
Prise en charge native des pointeurs de fonction C: les fonctions C prenant des arguments de pointeur de fonction Peuvent être appelées à l'aide de fermetures ou de fonctions globales, , avec la restriction que la fermeture ne doit capturer aucun de ses . contexte local.
Donc, cela compile et fonctionne:
func exceptionHandler(exception : NSException) {
print(exception)
print(exception.callStackSymbols)
}
NSSetUncaughtExceptionHandler(exceptionHandler)
Ou avec une fermeture "en ligne":
NSSetUncaughtExceptionHandler { exception in
print(exception)
print(exception.callStackSymbols)
}
Cela fait exactement la même chose que le code Objective-C correspondant: Il capture par ailleurs NSException
s non capturé. Ce sera donc capturé:
let array = NSArray()
let elem = array.objectAtIndex(99)
NOTE: - Il ne pas intercepte les erreurs Swift 2 (de throw
) ou les erreurs d'exécution Swift, elles ne sont donc pas interceptées:
let arr = [1, 2, 3]
let elem = arr[4]
L'erreur que vous pouvez voir lors de la réouverture d'une application ultérieure de cette manière.
Ce code pour Swift 4. Ajouter dans didFinishLaunchingWithOptions()
:
NSSetUncaughtExceptionHandler { exception in
print("Error Handling: ", exception)
print("Error Handling callStackSymbols: ", exception.callStackSymbols)
UserDefaults.standard.set(exception.callStackSymbols, forKey: "ExceptionHandler")
UserDefaults.standard.synchronize()
}
Et le code ajouté dans fistViewController viewLoad()
// ERROR ExceptionHandler
if let exception = UserDefaults.standard.object(forKey: "ExceptionHandler") as? [String] {
print("Error was occured on previous session! \n", exception, "\n\n-------------------------")
var exceptions = ""
for e in exception {
exceptions = exceptions + e + "\n"
}
AlertFunctions.messageType.showYesNoAlert("Error was occured on previous session!", bodyMessage: exceptions, {
}, no: {
UserDefaults.standard.removeObject(forKey: "ExceptionHandler")
UserDefaults.standard.synchronize()
})
}
EDIT: Le code fonctionne. Mais vous devez rouvrir votre application après une erreur.