Question Qu'est-ce que cela signifie de "faiblir" un cadre?


Dans Xcode, je peux définir un framework sur "Facultatif" au lieu de "Obligatoire", ce qui signifie que le framework est faiblement lié.

Est-ce que cela signifie que le framework n'est inclus dans le bundle que lorsqu'il est importé quelque part?

Je souhaite assouplir quelques frameworks de débogage utilisant API privée, et je ne veux pas qu'ils apparaissent dans la version App Store.


20
2018-06-04 15:41


origine


Réponses:


Note importante: Cette réponse a été écrite avant l’annonce d’iOS 8. Bien que les détails techniques s'appliquent toujours aux frameworks système, il est désormais possible de créer vos propres frameworks à liens dynamiques livrés dans votre bundle d'applications. Il existe des restrictions, par exemple, seule une application et ses extensions peuvent être liées à la même instance d'un framework incorporé, mais il n'en reste pas moins que ce framework personnalisé et lié dynamiquement sont possible depuis iOS 8. Si vous voulez en savoir plus, reportez-vous à ce guide (Utilisation d'un cadre incorporé pour partager le code) et WWDC 2014 session 416, Construire des cadres modernes.

Réponse originale: Aucun des frameworks (de plate-forme) n'est vraiment "inclus dans le bundle"Au lieu de cela, votre application a une référence ("lien") à un framework une fois que vous l'ajoutez à la phase de génération" Link Binary with Library ". Les frameworks sont préinstallés sur les périphériques. Lorsque vous exécutez une application, toutes les références du framework de l'application sont résolues par l'éditeur de liens dynamique (sur le périphérique), ce qui signifie que le code d’infrastructure est chargé pour que votre application puisse l’utiliser.

Certains frameworks peuvent ne pas être disponibles sur tous les périphériques que vous envisagez de prendre en charge, par exemple, PassKit a été introduit dans iOS 6. Si vous exécutez une application liée à PassKit sur un périphérique iOS 5, elle se bloque immédiatement après le lancement. trouver le cadre sur l'appareil. Cependant, si vous associez PassKit, l'éditeur de liens dynamique définira tous les symboles du framework comme suit: nil, si le cadre n'a pas pu être trouvé. Cela empêche l'application de tomber en panne et vous pouvez vérifier la disponibilité des symboles à l'exécution, par exemple:

if ([PKPass class]) {
  // Class is available - use it
  PKPass *pass = [[PKPass alloc] init];
}

[PKPass class] est sûr d'utiliser sur tous les appareils / systèmes depuis le PKPass symbole de classe sera nil sur les anciens systèmes et la messagerie nil n'est pas un problème en Objective-C.

Plus sur le lien faible: Documentation Apple

Pour vraiment répondre à votre question:

Est-ce que cela signifie que le framework n'est inclus dans le bundle que lorsqu'il est importé quelque part?

Non. Le framework sera toujours lié depuis l'application. Ce n'est que lorsque le framework est introuvable sur le périphérique sur lequel votre application s'exécute que le framework ne sera pas chargé.

Une solution consisterait à avoir des cibles distinctes pour les versions Debug et App Store. Une autre solution consiste à ne pas utiliser la phase de génération intégrée "Link Binary with Library" de Xcode, mais à lier les infrastructures Debug via les options de l'éditeur de liens. Celles-ci peuvent être spécifiées pour chaque configuration (Debug / Release / ...) séparément, comme ceci:

Adding framework via linker flags

Si vous voulez le lier, utilisez -weak_framework PassKit (PassKit, bien sûr, étant juste un exemple ici ... insérez le nom de votre framework) à la place. Si votre infrastructure de débogage ne se trouve pas dans l'un des répertoires d'infrastructure par défaut, vous devrez peut-être fournir un chemin complet ou modifier le chemin de recherche de Frameworks. De plus, vous devriez probablement utiliser des macros pour vous assurer qu'aucun code utilisant le (s) framework (s) de débogage ne soit intégré à la version App Store.

modifier: Une autre option à utiliser depuis Xcode 5 @import <FrameworkName>;. De cette façon, vous pouvez laisser votre phase "Link Binary ..." vide et déclencher la liaison des frameworks dans le code. Vous pouvez ensuite utiliser des macros telles que DEBUG pour vous assurer que certains frameworks ne sont pas utilisés pour les builds App Store. Il y a un excellente réponse En ce qui concerne @import.


16
2018-06-05 09:39



J'ai rencontré des liens faibles lorsque j'utilisais des iAds. Le problème était que si je lierais le framework iAds et exécuter l'application sur un périphérique avec SDK qui ne supportait pas les iAds, il se bloquerait tout simplement. Liens faibles permettant d'éviter les accidents. Je crois toujours que même avec des liaisons faibles, vous devez toujours enregistrer le code si le framework est disponible ou non.


3
2018-06-04 15:52



Est-ce que cela signifie que le framework n'est inclus dans le bundle que lorsqu'il est importé quelque part?

Cela dépend de la façon dont vous avez configuré vos schémas ou vos cibles.

Vous pouvez utiliser un seul schéma uniquement pour le débogage et inclure uniquement votre framework optionnel. Utilisez un autre schéma sans le cadre facultatif pour la publication.

Scheme Example

METTRE À JOUR

Pour ce faire, basez votre nouveau schéma sur une configuration de projet et définissez OTHER_LDFLAGS comme décrit dans réponse de hagi.

Project Configurations and Schemes


2
2018-06-04 16:19