Je construis une application iOS en utilisant React Native et j'essaie de la tester sur des téléphones.
Si je connecte mon téléphone à l'ordinateur et que je «construis» directement sur celui-ci, l'application est correctement construite et s'ouvre/fonctionne correctement, pas de problème.
Mais si j'essaie de l'archiver et de l'envoyer aux téléphones à l'aide de TestFlight ou Fabric with Crashlytics d'iTunes Connect, l'application se bloque immédiatement après son ouverture. Il montre brièvement l'écran de lancement, mais pas plus.
De plus, il n'y a pas de rapport d'incident - dans TestFlight, Crashlytics ou XCode, une fois le téléphone rebranché. Je fonctionne donc dans le noir ici, sans aucune information sur ce qui se casse. N'ayant pas été en mesure de trouver un problème similaire en ligne, j'ai donc décidé de poser la question. Des idées sur ce qui pourrait mal tourner?
S'il vous plaît laissez-moi savoir s'il y a un code ou d'autres données que vous pourriez avoir besoin de voir. Certaines sont confidentielles, mais je vais essayer de publier une version approximative.
Comme Chris Geirman l'a suggéré, le problème était une erreur JavaScript. Je ne suis pas sûr que les personnes ayant des problèmes similaires trouveront ce fil, mais dans le cas contraire, voici l'erreur étrange qui se produisait.
J'avais créé un système ORM simple, avec un modèle de base et un ensemble de modèles qui en ont hérité. Le constructeur BaseModel ressemblait à ceci:
constructor(props = {}, relations = {}) {
Object.keys(props).forEach((k) => {
// Save props to object
this[k] = props[k];
});
this.relations = relations;
this.className = this.constructor.name;
}
Cette dernière ligne était le problème. Sur mon simulateur local et si je construis l'application sur mon téléphone en la branchant, cela fonctionne bien. Comme dans, si un modèle Message hérite de BaseModel, l'appel de var msg = new Message(data, relations); msg.className
renvoie Message
.
Mais quelque chose à propos de regroupement/archivage/envoi de l'application via TestFlight ou Fabric.io réduit et uglifie le code JavaScript, de sorte que les noms de classe soient modifiés. Donc, au lieu de cela, si je fais ceci - var msg = new Message(data, relations); msg.className
- je récupèrerai un nom de variable aléatoire, quelque chose comme 't'.
C'était un problème dans mon application, car ma page d'accueil contenait une instruction switch qui fonctionnait avec le className:
iconContent() {
return {
Message: {
icon: <Image style={styles.feedItemIconImage} source={ require('../assets/img/icon_message.png') } />,
color: c.grass
}, ...
}[this.props.className] // from the model item
}
Mais 'Message'
n'était pas, comme prévu, la valeur de this.props.className
- 't'
était. Ainsi, si j'essayais d'entrer dans la valeur color
, par exemple, je commettrais une erreur, car j'essayais d'accéder à la propriété color
de null
.
Pourquoi cela n'a-t-il pas été signalé? Je ne le sais pas (j'ai suivi les suggestions de Chris et installé Sentry, mais cela ne semblait toujours pas signaler l'erreur).
Mais c'est ce qui se passait. Une minification/uglification s'est produite seulement lorsque j'ai installé l'application sur un téléphone via TestFlight/Fabric, c'est pourquoi l'application ne s'est écrasée que dans ces conditions.
J'espère que cela évitera à quiconque se heurtera à un virus similaire de se déchirer les cheveux.
Je ne sais pas si vous avez toujours ce problème - mais si tel est le cas, je vous recommanderais de vérifier Bugsnag pour réagir aux rapports d'erreur natifs - qui signalent les plantages dans la couche JavaScript ainsi que dans les couches natives (Java/cocoa) .
L'un des problèmes les plus difficiles à résoudre dans la génération de rapports d'incidents natifs (comme Sasha l'a mentionné) est la restauration des traces de pile d'origine lors de l'utilisation de la minification et/ou de l'obscurcissement - ceci est traité dans Bugsnag en fournissant un support complet pour les cartes source JS, ainsi que la symbolisation iOS. et le support Android Proguard au niveau des couches natives.
Faites-moi savoir si cela aide - je suis un fondateur @ Bugsnag
J'aimerais partager ma propre expérience du crash de la phase de production, alors que tout fonctionnait bien lors de la phase de développement.
J'ai eu le problème similaire qui a causé par le Reactotron logger. Comme je ne l’associe pas au stade de la production, une seule ligne de console.tron.log a bloqué mon application de manière totalement invisible. (C'est un peu ma faute, vu que je me foutais complètement de mon linter avec le réglage 'sans console')
Voici l'extrait de code que je présente dans mon fichier de niveau racine, root.js.
if (__DEV__) {
...
console.tron = Reactotron;
...
}
J'espère que quelqu'un le trouvera avant de perdre du temps à comprendre ce qui ne va pas.