View in English

  • Global Nav Open Menu Global Nav Close Menu
  • Apple Developer
Search
Cancel
  • Apple Developer
  • News
  • Discover
  • Design
  • Develop
  • Distribute
  • Support
  • Account
Only search within “”

Quick Links

5 Quick Links

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Sujets
  • Toutes les vidéos
  • À propos

Retour à WWDC25

  • À propos
  • Résumé
  • Transcription
  • Code
  • Découvrir l’interopérabilité entre Swift et Java

    Découvrez comment combiner Swift et Java dans une seule base de code. Nous allons présenter le projet d'interopérabilité swift-java, qui vous permet d'utiliser Swift dans les programmes Java ou vice versa. Nous allons vous montrer comment utiliser les outils et les bibliothèques offerts par swift-java pour écrire du code sûr et performant qui interagit entre ces deux environnements d'exécution.

    Chapitres

    • 0:00 - Introduction et ordre du jour
    • 2:41 - Différences d’exécution
    • 3:31 - Méthodes Java natives
    • 6:29 - SwiftJava
    • 10:13 - Appel de Java depuis Swift
    • 14:01 - Appel de Swift depuis Java
    • 20:47 - Conclusion

    Ressources

    • SwiftJava
    • The Swift Programming Language
    • The Swift website
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    WWDC25

    • Améliorer l’utilisation de la mémoire et les performances avec Swift
    • Mixez en toute sécurité C, C++ et Swift
    • Nouveautés dans Swift

    WWDC23

    • Mix Swift and C++
  • Rechercher dans cette vidéo…

    Bonjour, je m’appelle Konrad. Je suis ingénieur au sein de l’équipe du langage Swift. Aujourd’hui, je vais vous parler d’une nouvelle initiative d’interopérabilité que nous avons lancée plus tôt cette année : l’interopérabilité entre Swift et Java. Cette interopérabilité est importante, car elle ouvre de nouvelles possibilités d’utilisation de Swift dans divers domaines. Grâce à sa compatibilité avec d’autres langages, Swift peut être intégré petit à petit dans des projets existants. Plus besoin d’effectuer des réécritures importantes et risquées. Nous pouvons simplement ajouter une nouvelle fonctionnalité ou remplacer une fonctionnalité existante par du code Swift, sans affecter le reste du code source. Nous pouvons aussi réutiliser des bibliothèques déjà intégrées dans d’autres langages, ou leur fournir des bibliothèques écrites en Swift. Notre approche de l’interopérabilité ne se limite pas au langage. Nous utilisons les meilleurs outils de compilation pour chaque environnement. que ce soit CMake pour C/C++ ou Gradle pour Java. L’interopérabilité avec les langages C est l’un des points forts de Swift depuis sa création. Elle a permis à Swift de s’intégrer parfaitement dans l’environnement de développement Apple existant, pour finalement devenir le langage principal sur ces plates-formes. Il y a deux ans, nous avons démarré notre projet d’interopérabilité C++ pour permettre l’intégration des bibliothèques C++ et Swift dans un seul code source. Cette avancée a ouvert de nombreuses possibilités pour utiliser Swift dans encore plus de domaines. Pour plus d’informations, je vous invite à regarder la séance « Mix Swift and C++ » de la WWDC 2023 ou celle de cette année intitulée « Safely Mix C, C++ and Swift ». Quand on aborde la question de l’interopérabilité, deux axes principaux se dégagent. Tout d’abord, nous pouvons écrire une application principalement en Swift et appeler du code écrit en Java. Nous pouvons aussi nous concentrer sur la simplification et l’optimisation des appels depuis Java vers Swift. L’interopérabilité entre Java et Swift prend en charge ces deux aspects. Les outils et techniques que nous utilisons varient selon les domaines, mais il n’est pas rare de les combiner dans un même projet. Avant de passer à des exemples concrets, rappelons les différences entre les runtimes Java et Swift. Nous verrons ensuite trois exemples concrets d’utilisation de l’interopérabilité Java. Tout d’abord, la fonctionnalité des méthodes natives de Java. Ensuite, nous verrons comment rendre une bibliothèque Java accessible dans Swift. Et enfin, nous verrons l’approche inverse en intégrant une bibliothèque Swift pour la rendre accessible dans un projet Java. Commençons par comparer les deux runtimes. Après tout, le runtime Java est très différent des autres langages natifs avec lequel Swift est déjà compatible. Mais, avec un peu de recul, on peut dire que Swift est sans doute le langage de programmation qui se rapproche le plus de Java. Ces deux langages proposent des classes avec un modèle d’héritage similaire. Ils offrent tous deux une gestion automatique de la mémoire, largement transparent pour le développeur. Ils offrent aussi un système générique très similaire, même si son fonctionnement diffère lors de l’exécution. Enfin, Swift peut générer des erreurs de la même manière que les exceptions Java, bien que la quantité d’informations qu’elles contiennent lors de l’exécution soit légèrement différente. Ce qui compte vraiment, c’est qu’en sélectionnant judicieusement notre façon d’utiliser ces fonctionnalités, nous pouvons transposer la majorité des API d’un langage à l’autre. Après avoir passé en revue les points communs et les différences entre ces langages, entrons dans le vif du sujet pour découvrir comment enrichir une application Java existante. Nous allons commencer par la création d’une fonction simple dans Swift. À cette fin, nous allons utiliser la fonctionnalité des méthodes natives Java. Les méthodes natives Java font partie de l’API Java Native Interface, également appelée JNI. JNI est intégrée à Java depuis 1997, bien avant l’apparition de l’iPod, et a été développée pour permettre à Java de communiquer avec du code natif. On l’utilise souvent pour optimiser les performances en déchargeant certaines tâches de la mémoire Java, ou pour exploiter des bibliothèques natives qui n’ont pas d’équivalent Java. JNI reste l’une des principales solutions d’interopérabilité entre Java et le code natif, avec des API pratiquement inchangées depuis sa création. C’est donc naturellement par JNI que nous allons commencer notre exploration. Pour faire nos premiers pas avec JNI, voyons ensemble la marche à suivre pour l’utiliser sans recourir à des bibliothèques externes ou des outils supplémentaires. Du côté de l’application Java, vous définissez une fonction native, qui sera implémentée à l’aide du code natif. Pour illustrer la gestion du transfert d’objets vers le code natif par JNI, nous utilisons le type Integer en majuscule comme arguments et type de retour de cette fonction. Contrairement aux valeurs Int primitives, ce sont des objets Java que nous devons correctement utiliser. Ensuite, vous devez utiliser le compilateur Java avec un flag « -h » sur tous les fichiers contenant des méthodes natives. Vous obtenez un fichier d’en-tête C contenant des déclarations de fonction C que la JVM tente d’appeler lorsque la méthode native Java correspondante est appelée. La déclaration possède un nom assez long, Java_com_example_JNIExample_compute, qui correspond au nom du package, de la classe et de la méthode native. Elle prend en charge l’environnement JNI et utilise le paramètre jobject pour faire référence à l’objet Java sur lequel la méthode est appelée, tout en conservant les paramètres définis dans la déclaration de fonction Java initiale. Enfin, vous devez coder cette fonction en Swift, le langage que nous avons choisi pour ce projet.

    Il y a beaucoup de code, n’est-ce pas ? Bien que le code standardisé prenne le pas sur l’implémentation logique réelle, qui se trouve ici, ce n’est pas du superflu pour autant. Il y a ici de nombreuses occasions de faire des erreurs pouvant entraîner des problèmes graves. En bref, JNI est une solution pratique pour exécuter du code natif à partir de la JVM, mais son utilisation reste délicate. Pour optimiser les performances des méthodes, nous devons parfois recourir à la mise en cache et à d’autres techniques, ce qui rend le code plus complexe. Il faut tenir compte de plusieurs étapes de compilation et d’en-têtes C supplémentaires. Faire correspondre manuellement toutes les signatures de méthode et les chaînes magiques est risqué. Nous devons également gérer soigneusement la durée de vie de tout objet Java créé ou reçu. Il est donc possible d’utiliser JNI de manière autonome, mais ce n’est pas la solution la plus pratique. Ce qui nous amène à SwiftJava, la nouvelle fonction dédiée à l’interopérabilité entre Swift et Java. Nous avons créé SwiftJava afin de permettre aux développeurs Swift et Java de faire communiquer leurs applications de manière simple, sécurisée et efficace.

    SwiftJava comporte plusieurs éléments que vous pouvez utiliser séparément ou ensemble. Tout d’abord, un package Swift fournit la bibliothèque et les macros JavaKit, ce qui rend le traitement du code JNI, comme illustré dans l’exemple précédent, beaucoup plus sûr. Ensuite, nous avons SwiftKit, une bibliothèque Java. Elle permet aux applications Java de traiter efficacement les objets Swift. Et enfin, l’outil de ligne de commande Swift-Java et d’autres intégrations de systèmes de compilation, comme le plug-in SwiftPM, ou même les projets en cours pour intégrer des outils de compilation Java populaires, tels que Gradle. Reprenons le dernier exemple, mais cette fois-ci, avec les outils SwiftJava. Nous allons utiliser l’outil de ligne de commande Swift-Java pour créer la liaison nécessaire, au lieu d’un compilateur Java. Nous devons lui indiquer un nom de module pour l’écriture des sources générées ainsi qu’une configuration supplémentaire. Dans les projets plus complexes, cette opération est déclenchée par un plug-in de compilation dans SwiftPM ou par un autre système que vous utilisez. Le processus aboutit à un fichier Swift qui inclut des annotations décrivant la classe Java importée. Si le type Java a des méthodes membres, elles apparaîtront également dans le type Swift correspondant, ce qui nous permettra de rappeler ces fonctions Java à partir de Swift. Et enfin, le protocole JNIExampleNativeMethods généré contient toutes les méthodes natives que nous pouvons implémenter pour ce type. Il remplace l’en-tête C que nous avons utilisé auparavant. Pour implémenter votre fonction de calcul native, il vous suffit d’écrire une extension de la classe JNIExample générée et de la faire correspondre au protocole JNIExampleNativeMethods. Nous devons également l’annoter à l’aide de la macro JavaImplementation fournie par JavaKit. Ensuite, le compilateur nous aidera à implémenter la signature de fonction requise. Il suffit de se rappeler que nous devons ajouter une annotation avec la macro @JavaMethod, qui s’occupe de certains détails JNI supplémentaires pour nous. Grâce à SwiftJava, notre méthode est beaucoup plus facile à implémenter, ce qui nous permet de nous concentrer sur notre logique métier. Nous pouvons désormais utiliser toutes les bibliothèques Swift que nous voulons, ce qui est encore mieux. Je peux, par exemple, vouloir utiliser une implémentation native d’un algorithme cryptographique. Justement, l’écosystème Swift offre une excellente bibliothèque pour cela. Je peux ainsi importer le module crypto et calculer, par exemple, le hachage SHA256 des données transmises. Vous vous souvenez peut-être des problèmes rencontrés lors de notre précédente implémentation de la JNI. La plupart d’entre eux ne portaient pas vraiment sur JNI, mais plutôt sur la difficulté de l’utiliser correctement. Grâce à l’approche de SwiftJava concernant JNI, nous pouvons éviter une grande partie du code standard, ce qui rend le code final beaucoup plus facile à gérer et à maintenir. Nous n’avons plus besoin d’interagir avec les en-têtes C, car nous pouvons utiliser des signatures de fonctions générées et bien typées. Nous évitons ainsi les erreurs, qui peuvent prendre beaucoup de temps à déboguer. Enfin, la gestion de la durée de vie des objets est considérablement améliorée par rapport à l’écriture manuelle des liens entre les langages. Ceci est essentiel pour écrire du code sécurisé pour la mémoire, quel que soit le langage utilisé. Il est donc bien plus agréable et sûr d’effectuer des interactions JNI avec SwiftJava plutôt que de les coder manuellement. Mais, ce n’est qu’un début, et SwiftJava a encore beaucoup à offrir. Imaginons maintenant une situation où nous voudrions utiliser une bibliothèque Java à partir de Swift. Nous allons à nouveau utiliser l’outil Swift-Java, mais cette fois-ci, concentrons-nous sur la manière d’importer une bibliothèque Java entière, et pas uniquement un seul type. Imaginons que je veuille utiliser la bibliothèque Apache Commons CSV, qui est très populaire, dans Swift. Non seulement je dois trouver la bibliothèque, mais aussi toutes ses dépendances en aval. La gestion des dépendances devient vite complexe, car les bibliothèques Java ont souvent de nombreuses dépendances indirectes, qui elles-mêmes en ont d’autres, et ainsi de suite. Heureusement, SwiftJava peut s’en occuper pour nous. Il nous suffit de préparer les coordonnées de l’artefact de la bibliothèque que nous voulons utiliser. Vous pouvez les trouver en effectuant une recherche en ligne. Si vous n’êtes pas sûr, vous pouvez demander à un développeur Java de votre équipe. La dépendance comportera trois informations : un ID d’artefact pour désigner l’artefact spécifique, un ID de groupe pour indiquer l’organisation qui publie la bibliothèque, et un numéro de version. Ensuite, nous utiliserons l’intégration Gradle de SwiftJava, un outil populaire de compilation et un gestionnaire de dépendances dans l’écosystème Java. Pour utiliser cette dépendance avec Gradle, il suffit d’ajouter des colonnes entre ces trois valeurs. Nous venons ainsi de créer un descripteur de dépendance dans un format compris par Gradle. Maintenant que nous avons les coordonnées de la dépendance, nous avons deux options pour les télécharger et les intégrer dans notre cible JavaApacheCommonsCSV. La première méthode consiste à utiliser le plug-in SwiftJava de l’outil de compilation. Dans le fichier swift-java.config de notre cible, ajoutons une section pour lister toutes les dépendances racines à résoudre. Et voilà. Désormais, le plug-in appellera automatiquement Gradle pour résoudre les dépendances Java à chaque compilation de notre projet SwiftPM. SwiftPM applique aussi un sandbox de sécurité qui garantit que les plug-ins compilés ne peuvent pas accéder à des fichiers arbitraires ni au réseau. Si vous souhaitez utiliser cette approche, vous pouvez désactiver le sandbox de sécurité lors de la compilation du projet. Il se peut que cela ne soit pas faisable dans tous les contextes. Voici donc une autre méthode que vous pouvez essayer. Nous pouvons utiliser la commande Resolve de l’outil de ligne de commande Swift-Java. En spécifiant le nom du module pour le fichier de configuration, l’outil résoudra les dépendances et enregistrera le chemin d’accès à la classe résultante dans un fichier. Pour cette opération, qui se fait en dehors de la compilation SwiftPM, il n’est pas nécessaire de désactiver le sandbox. Cependant, cela implique que vous devrez lancer manuellement la résolution des dépendances avant de compiler votre projet. C’est un compromis, et vous pouvez choisir le modèle qui convient le mieux à votre façon de travailler.

    Quoi qu’il en soit, nous pouvons désormais utiliser la bibliothèque Java de Swift. Il nous suffit d’importer les modules JavaKit et JavaApacheCommonsCSV. Ensuite, nous lançons la JVM dans notre processus Swift afin d’exécuter le code Java. Nous sommes maintenant prêts à utiliser Java dans notre application Swift. Comme ici, nous utilisons le FileReader du JDK et le transmettons à la bibliothèque CSV que nous venons d’importer. De plus, nous pouvons même utiliser les boucles for-each de Swift directement sur les collections Java renvoyées.

    Nous avons vu comment SwiftJava utilise à la fois Gradle et SwiftPM pour offrir une excellente expérience utilisateur. Nous pouvons importer des bibliothèques Java entières sans avoir besoin de modifier les sources Java. Le code Swift généré à la source utilise les types wrapper JDK fournis par JavaKit et gère automatiquement les types définis par l’utilisateur. JavaKit facilite aussi la gestion de la durée de vie des objets Java en transformant les références en références globales si nécessaire. La dernière technique abordée aujourd’hui consiste à rendre une bibliothèque Swift entière accessible à une application Java. C’est une fonctionnalité essentielle qui nous permet de développer une logique métier de base dans Swift et de la déployer dans nos applications et services, que Swift soit déjà adopté ou non.

    Nous avons mentionné plus tôt que l’interopérabilité doit aller dans les deux sens. Il est crucial de comprendre que faciliter la transition de Java vers Swift permet à plus de projets d’adopter Swift et d’en apprécier l’expérience, ce qui joue un rôle important dans l’intégration d’un nouveau langage dans un code source. Si nous voulions exposer toute une bibliothèque Swift en utilisant les techniques précédentes, il nous faudrait écrire de nombreuses fonctions wrapper du côté Java. Pour certaines fonctions, ça va, mais si c’est une bibliothèque entière, il faut adopter une autre approche. De la même manière que nous avons exposé une bibliothèque Java pour Swift, faisons maintenant en sorte que l’appel de Swift soit aussi simple que possible pour Java. Nous allons encapsuler tous les types de notre bibliothèque Swift dans des classes Java et les distribuer ensemble sous forme de bibliothèque Java. Cette fois, nous n’utiliserons pas JNI. Nous allons plutôt utiliser les nouvelles API Foreign Function et Memory, qui a été stabilisée en mars dernier et est désormais disponible à partir de Java 22. Cette API offre un meilleur contrôle de la mémoire native et de la formation des appels natifs. Elle peut parfois remplacer JNI. Grâce à ces nouvelles API, nous pouvons établir une intégration très avancée entre Java et le runtime de Swift, ainsi que la gestion de la mémoire, ce qui n’aurait pas été possible autrement. Cela se traduit par une sécurité renforcée et de meilleures performances lors des appels natifs à partir de Java. Pour cet exemple, nous allons utiliser une structure Swift qui représente un objet métier que je veux exposer à Java. Ce type de valeur n’a pas d’identité d’objet stable, ce qui n’est pas exprimable par les objets Java. Il faudra donc être prudent lorsque nous manipulerons cet objet dans Java. Il a aussi une propriété publique, un initialiseur et plusieurs méthodes pour l’utiliser. Pour exposer ce type à Java, nous allons à nouveau utiliser l’outil de ligne de commande Swift-Java. Cette fois, nous allons l’utiliser d’une manière un peu différente. Nous lui fournirons un chemin d’entrée pour Swift ainsi que des répertoires de sortie pour les sources générées en Swift et en Java. L’outil va utiliser toutes les sources du chemin d’entrée pour créer des classes Java, qui serviront d’interfaces pour accéder aux types et fonctions Swift. Nous allons aussi créer le code d’assistance Swift nécessaire. Tout, y compris le code Swift transformé en bibliothèque dynamique, sera finalement compilé et intégré dans une bibliothèque Java. La classe Java générée va ressembler à ceci. Elle implémente l’interface de valeur Swift, car c’est une struct. La classe contient un segment de mémoire dédié, qui est en réalité un pointeur vers l’instance dans la mémoire native. Elle représente l’ensemble des initialiseurs, propriétés et fonctions publics avec leurs signatures équivalentes en Java. Nous avons un code très efficace, créé à partir du code source, qui permet d’effectuer des appels natifs en utilisant les API Foreign Function. Nous pouvons maintenant nous appuyer sur les sources Java générées dans notre application. Pour créer et gérer des valeurs Swift natives, nous aurons besoin d’une SwiftArena, qui s’occupe de l’allocation de mémoire et de la gestion de la durée de vie des objets Swift. Une fois l’arène prête, nous pouvons simplement appeler le constructeur de valeurs Swift, comme si c’était une classe Java normale. Profitons-en pour discuter un peu plus de la gestion des ressources de mémoire native et Java dans ce contexte. Tout d’abord, un nouvel objet wrapper Java est alloué sur le heap Java, qui est géré par le Garbage Collector de la JVM. Son constructeur généré à partir du code source utilise ensuite SwiftArena qui lui est transmis pour allouer et initialiser une instance du type de valeur Swift dans le heap natif. Normalement, les types de valeurs, tels que notre struct SwiftyBusiness sont alloués dans la pile, mais comme nous avons besoin d’une adresse mémoire stable, nous les allouons plutôt dans le heap. Nous pouvons ainsi pointer en toute sécurité vers cette adresse mémoire à partir de l’objet wrapper Java. Finalement, le wrapper Java n’est plus utilisé et le Garbage Collector décidera de le collecter et de le détruire. Cela déclenchera également une destruction de l’instance native du côté Swift. En ce qui concerne la gestion de la mémoire, tout est sûr. Cependant, contrairement à Swift, compter sur la finalisation des objets de cette façon impose une charge importante au GC, qui doit effectuer un suivi supplémentaire de ces objets. Un autre effet est que le moment de la désinitialisation de la valeur Swift native devient imprévisible. Bien que ce modèle soit facile à mettre en place, laissez-moi vous montrer une autre méthode pour gérer la mémoire native. Au lieu d’utiliser une Auto Arena, nous pouvons utiliser une syntaxe Java try-with-resources associée à un type Confined Arena. L’allocation des objets se fera de la même façon ici, mais l’utilisation de try-with-resources change la façon dont ils sont détruits. Plus précisément, l’Arena sera fermée à la fin de cette opération. Cela déclenche la destruction de l’objet wrapper Java, qui à son tour, déclenche la destruction de la valeur Swift sur le heap natif. Cette approche est plus efficace. Nous ne forçons pas le GC à finaliser les objets, ce qui peut poser problème lorsqu’il y en a beaucoup. Nous avons aussi retrouvé la propriété de désinitialisation d’objet bien définie et ordonnée, qui est essentielle pour de nombreux programmes Swift. Essayez autant que possible d’utiliser des Scoped Arenas plutôt que de vous reposer sur le GC pour optimiser le comportement et les performances de l’application. Pour résumer, nous avons réussi à encapsuler une bibliothèque Swift complète à l’aide d’une seule invocation de l’outil de ligne de commande Swift-Java. Nous pouvons créer des Swift encapsulés en bibliothèques Java et les publier, ce qui facilite leur utilisation dans les projets Java et simplifie l’adoption de Swift par vos équipes. En utilisant les API modernes Foreign Function et Memory, nous pouvons contrôler précisément les allocations et la durée de vie des objets, y compris pour les types de valeur Swift. Aujourd’hui, nous avons vu plusieurs techniques pour travailler avec Swift et Java, que vous pouvez utiliser séparément ou conjointement selon les besoins spécifiques de votre projet. Bien que nous n’en soyons qu’au début et qu’il y ait encore beaucoup à améliorer et à perfectionner, SwiftJava constitue déjà une excellente solution pour l’interopérabilité entre ces langages. Grâce aux bibliothèques d’assistance SwiftKit et JavaKit, vous pouvez écrire un code sécurisé et efficace qui utilise ces deux langages. Et les macros JavaKit, ainsi que l’outil de ligne de commande Swift-Java génèrent automatiquement le code standard qui serait autrement difficile à gérer.

    Je vous encourage à vous joindre à nous pour développer ce projet. Il est entièrement open source et disponible sur Github dans l’organisation Swiftlang. Il reste encore beaucoup de défis passionnants à relever et d’idées à explorer. Pour en apprendre davantage sur Swift et Java ou pour partager vos idées et commentaires, même si vous n’êtes pas encore prêt à contribuer, le mieux est de nous rejoindre sur les forums Swift. Merci beaucoup de votre attention. Quant à moi, je vais aller me préparer une tasse de café.

    • 9:05 - Implement JNI native methods in Swift

      import JavaKit
      import JavaRuntime
      
      import Crypto
      
      @JavaImplementation("com.example.JNIExample")
      extension JNIExample: JNIExampleNativeMethods {
       
        @JavaMethod
        func compute(_ a: JavaInteger?, _ b: JavaInteger?) -> [UInt8] {
          guard let a else { fatalError("Expected non-null parameter 'a'") }
          guard let a else { fatalError("Expected non-null parameter 'b'") }
          
          let digest = SHA256Digest([a.intValue(), b.intValue()]) // convenience init defined elsewhere
          return digest.toArray()
        }
      }
    • 12:30 - Resolve Java dependencies with swift-java

      swift-java resolve --module-name JavaApacheCommonsCSV
    • 13:05 - Use a Java library from Swift

      import JavaKit
      import JavaKitIO
      import JavaApacheCommonsCSV
      
      let jvm = try JavaVirtualMachine.shared()
      
      let reader = FileReader("sample.csv") // java.io.StringReader
      
      for record in try JavaClass<CSVFormat>().RFC4180.parse(reader)!.getRecords()! {
        for field in record.toList()! {      // Field: hello
          print("Field: \(field)")           // Field: example
        }                                    // Field: csv
      }
      
      print("Done.")
    • 16:22 - Wrap Swift types for Java

      swift-java --input-swift Sources/SwiftyBusiness \ 
                 --java-package com.example.business \
                 --output-swift .build/.../outputs/SwiftyBusiness \
                 --output-java .build/.../outputs/Java ...
    • 18:55 - Create Swift objects from Java

      try (var arena = SwiftArena.ofConfined()) {
        var business = new SwiftyBusiness(..., arena);
      }
    • 0:00 - Introduction et ordre du jour
    • Découvrez une bibliothèque expérimentale du langage Swift, appelée « swift-java », qui rend Swift compatible avec Java et vient s’ajouter aux fonctionnalités d’interopérabilité existantes dans Objective-C, C et C++. Cette interopérabilité vous permet d’intégrer progressivement Swift dans du code Java existant, de réutiliser des bibliothèques entre différents langages et d’intégrer des bibliothèques Swift à des projets Java. L’interopérabilité offerte par « swift-java » permet d’appeler du code Java à partir de Swift et inversement. Notre équipe travaille actuellement sur des outils et des techniques visant à gérer les différences entre les environnements d’exécution Java et Swift, ainsi qu’à améliorer la sécurité mémoire du code Java converti en types Swift.

    • 2:41 - Différences d’exécution
    • Swift et Java partagent des fonctionnalités telles que les classes, l’héritage, la gestion automatique de la mémoire, les génériques et la gestion des erreurs, bien qu’il existe des différences au niveau de l’exécution. Bien que ces deux langages présentent des différences, leurs points communs permettent généralement de transposer les API de l’un vers celles de l’autre.

    • 3:31 - Méthodes Java natives
    • L’API Java Native Interface (JNI) a été lancée au début de l’année 1997 et permet au code Java qui s’exécute dans une machine virtuelle Java (JVM) d’interagir avec du code natif, tel que Swift. Elle est souvent utilisée pour améliorer les performances ou pour utiliser des bibliothèques natives sans équivalent Java. Pour utiliser JNI, une fonction « native » est définie en Java, et un fichier d’en-tête C correspondant est généré. Ce fichier d’en-tête contient une déclaration de fonction C qui doit être implémentée dans le langage natif, tel que Swift. Le processus nécessite de gérer le cycle de vie des objets, d’assurer la compatibilité des signatures de méthodes et de traiter un code souvent trop verbeux. Ces tâches complexes peuvent non seulement être chronophages, mais aussi générer des erreurs critiques pouvant mener à des plantages système.

    • 6:29 - SwiftJava
    • SwiftJava améliore la compatibilité entre les langages Swift et Java. Il fournit une suite d’outils, notamment des bibliothèques Swift et Java, un outil en ligne de commande et des intégrations de systèmes de compilation, afin de simplifier et de sécuriser l’interaction entre ces deux langages. L’outil en ligne de commande « swift-java » automatise la génération de code de pontage. Il élimine ainsi toute interaction manuelle avec les en-têtes C. Vous bénéficiez ainsi d’un code plus propre et plus facile à maintenir, avec une gestion améliorée de la durée de vie des objets et une sécurité des types renforcée. Vous pouvez désormais vous concentrer sur la logique métier en tirant pleinement parti des écosystèmes Swift et Java et en évitant les pièges et les erreurs courants associés à l’implémentation manuelle de JNI.

    • 10:13 - Appel de Java depuis Swift
    • SwiftJava permet l’intégration de bibliothèques Java dans des projets Swift. Pour importer une bibliothèque Java, telle qu’Apache Commons CSV, préparez les coordonnées suivantes : « groupId », « artifactId » et « version ». SwiftJava utilise ensuite Gradle, un système de compilation open source, pour résoudre les dépendances Java. Il existe deux méthodes pour télécharger et encapsuler les dépendances Java : L’utilisation du plug-in de l’outil de compilation SwiftJava, qui nécessite la désactivation du sandbox de sécurité SwiftPM, ou la commande « resolve » de l’outil en ligne de commande « swift-java », qui effectue la résolution en dehors du processus de compilation. Une fois les dépendances Java résolues, vous pouvez importer la bibliothèque Java dans Swift, démarrer la JVM dans le processus Swift et utiliser de manière transparente le code Java et les collections avec les fonctionnalités Swift, JavaKit gérant la gestion de la durée de vie des objets.

    • 14:01 - Appel de Swift depuis Java
    • SwiftJava permet l’intégration des bibliothèques Swift dans des projets Java. Pour ce faire, cette séance WWDC25 présente une nouvelle approche qui évite d’avoir recours à des fonctions d’encapsulation complexes côté Java. À la place, l’intégralité de la bibliothèque Swift est encapsulée dans des classes Java à l’aide de la nouvelle API Foreign Function and Memory (FFI) lancée dans Java 22. FFI offre un meilleur contrôle de la mémoire native et permet une intégration approfondie entre les environnements d’exécution Java et Swift et les systèmes de gestion de la mémoire. Grâce à FFI, l’appel de code Swift à partir de Java est plus efficace et plus sûr. L’outil en ligne de commande « swift-java » est utilisé pour générer les classes Java et le code d’aide Swift nécessaires. Cet outil automatise la génération de code standard, ce qui simplifie le processus. Les classes Java générées servent d’accesseurs pour les types et les fonctions Swift. Elles exposent ainsi efficacement les fonctionnalités de la bibliothèque Swift à Java. Une gestion adéquate de la mémoire est essentielle si vous utilisez des objets Swift natifs dans Java. Cette discussion met en avant deux approches : l’utilisation d’une « AutoArena » qui s’appuie sur le Garbage Collector (GC) Java, et une méthode préférée utilisant « try-with-resources » et une « ConfinedArena ». Cette dernière approche garantit une désinitialisation bien définie et ordonnée des objets. Elle permet ainsi d’éviter les problèmes de performances et la surcharge du GC. Cette technique vous permet de créer et de publier des bibliothèques Java encapsulées dans Swift, ce qui les rend facilement utilisables dans des projets Java. Elle simplifie l’adoption de Swift dans les équipes qui utilisent déjà beaucoup Java pour créer un environnement de développement plus flexible et plus efficace. Le développement continu de SwiftJava vise à perfectionner et à affiner ces techniques afin de fournir une solution robuste pour la compatibilité entre les deux langages.

    • 20:47 - Conclusion
    • Le langage de programmation Swift est open source et hébergé sur GitHub. Il est également disponible dans des bibliothèques telles que SwiftJava. La communauté est active sur les forums Swift, où vous pouvez apprendre, partager des idées et donner votre avis.

Developer Footer

  • Vidéos
  • WWDC25
  • Découvrir l’interopérabilité entre Swift et Java
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • App Store
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Fonts
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Open Source
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Sample Code
    • Tutorials
    • Downloads
    • Forums
    • Videos
    Open Menu Close Menu
    • Support Articles
    • Contact Us
    • Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Get the Apple Developer app.
    Copyright © 2025 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines