Przejdź do treści głównej
Wersja: 0.81

iOS - Korzystanie ze Swifta w modułach natywnych

Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Swift jest oficjalnym i domyślnym językiem do tworzenia natywnych aplikacji na iOS.

W tym przewodniku dowiesz się, jak możesz pisać swoje moduły natywne używając Swifta.

uwaga

Rdzeń React Native jest głównie napisany w C++, a interoperacyjność między Swiftem a C++ nie jest idealna pomimo warstwy interoperacyjności opracowanej przez Apple.

Dlatego moduł, który utworzysz w tym przewodniku, nie będzie czystą implementacją w Swift z powodu niekompatybilności między językami. Będziesz musiał napisać kod pośredniczący w Objective-C++, ale celem przewodnika jest zminimalizowanie jego ilości. Jeśli migrujesz istniejące moduły natywne ze starszej architektury do Nowej Architektury, to podejście pozwoli ci ponownie wykorzystać większość kodu.

Ten przewodnik bazuje na implementacji iOS z przewodnika o modułach natywnych. Upewnij się, że znasz tamten przewodnik przed rozpoczęciem tego, najlepiej implementując podany przykład.

Wzorzec Adaptera

Celem jest zaimplementowanie całej logiki biznesowej przy użyciu modułu w Swift i utworzenie cienkiej warstwy pośredniczącej w Objective-C++, która połączy aplikację z implementacją w Swift.

Można to osiągnąć stosując wzorzec projektowy Adapter do połączenia modułu Swift z warstwą Objective-C++.

Obiekt Objective-C++ jest tworzony przez React Native i przechowuje referencję do modułu Swift, zarządzając jego cyklem życia. Obiekt Objective-C++ przekazuje wszystkie wywołania metod do Swifta.

Tworzenie modułu Swift

Pierwszym krokiem jest przeniesienie implementacji z warstwy Objective-C++ do warstwy Swift.

Aby to osiągnąć, wykonaj następujące kroki:

  1. Utwórz nowy pusty plik w projekcie Xcode i nazwij go NativeLocalStorage.swift

  2. Dodaj implementację w swoim module Swift jak poniżej:

NativeLocalStorage.swift
import Foundation

@objcMembers public class NativeLocalStorage: NSObject {
let userDefaults = UserDefaults(suiteName: "local-storage");

public func getItem(for key: String) -> String? {
return userDefaults?.string(forKey: key)
}

public func setItem(for key: String, value: String) {
userDefaults?.set(value, forKey: key)
}

public func removeItem(for key: String) {
userDefaults?.removeObject(forKey: key)
}

public func clear() {
userDefaults?.dictionaryRepresentation().keys.forEach { removeItem(for: $0) }
}
}

Pamiętaj, że wszystkie metody, które chcesz wywoływać z Objective-C, muszą być zadeklarowane jako public i z adnotacją @objc. Klasa musi także dziedziczyć po NSObject, w przeciwnym razie nie będzie możliwe jej użycie z Objective-C.

Aktualizacja pliku RCTNativeLocalStorage

Następnie musisz zaktualizować implementację RCTNativeLocalStorage, aby móc utworzyć moduł Swift i wywoływać jego metody.

  1. Otwórz plik RCTNativeLocalStorage.mm

  2. Zaktualizuj go jak poniżej:

RCTNativeLocalStorage.mm
//  RCTNativeLocalStorage.m
// TurboModuleExample

#import "RCTNativeLocalStorage.h"
+#import "SampleApp-Swift.h"

- static NSString *const RCTNativeLocalStorageKey = @"local-storage";

-@interface RCTNativeLocalStorage()
-@property (strong, nonatomic) NSUserDefaults *localStorage;
-@end

-@implementation RCTNativeLocalStorage
+@implementation RCTNativeLocalStorage {
+ NativeLocalStorage *storage;
+}

-RCT_EXPORT_MODULE(NativeLocalStorage)

- (id) init {
if (self = [super init]) {
- _localStorage = [[NSUserDefaults alloc] initWithSuiteName:RCTNativeLocalStorageKey];
+ storage = [NativeLocalStorage new];
}
return self;
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
return std::make_shared<facebook::react::NativeLocalStorageSpecJSI>(params);
}

- (NSString * _Nullable)getItem:(NSString *)key {
- return [self.localStorage stringForKey:key];
+ return [storage getItemFor:key];
}

- (void)setItem:(NSString *)value key:(NSString *)key {
- [self.localStorage setObject:value forKey:key];
+ [storage setItemFor:key value:value];
}

- (void)removeItem:(NSString *)key {
- [self.localStorage removeObjectForKey:key];
+ [storage removeItemFor:key];
}

- (void)clear {
- NSDictionary *keys = [self.localStorage dictionaryRepresentation];
- for (NSString *key in keys) {
- [self removeItem:key];
- }
+ [storage clear];
}

++ (NSString *)moduleName
+{
+ return @"NativeLocalStorage";
+}

@end

Kod nie zmienia się znacząco. Zamiast bezpośrednio tworzyć referencję do NSUserDefaults, tworzysz nowy NativeLocalStorage używając implementacji w Swift, a każde wywołanie funkcji modułu natywnego jest przekazywane do NativeLocalStorage zaimplementowanego w Swift.

Pamiętaj o zaimportowaniu nagłówka "SampleApp-Swift.h". Jest to nagłówek automatycznie generowany przez Xcode, który zawiera publiczne API twoich plików Swift w formacie zrozumiałym dla Objective-C. Część SampleApp w nazwie nagłówka odpowiada nazwie twojej aplikacji, więc jeśli utworzyłeś aplikację o nazwie innej niż SampleApp, musisz to zmienić.

Zauważ też, że makro RCT_EXPORT_MODULE nie jest już wymagane, ponieważ moduły natywne są rejestrowane za pomocą package.json jak opisano tutaj.

To podejście wprowadza niewielką redundancję w interfejsach, ale pozwala ponownie wykorzystać istniejący kod Swift w twojej bazie kodu przy minimalnym dodatkowym wysiłku.

Implementacja nagłówka pośredniczącego

uwaga

Jeśli jesteś autorem biblioteki tworzącym natywny moduł przeznaczony do dystrybucji jako osobna biblioteka, ten krok nie jest wymagany.

Ostatnim wymaganym krokiem do połączenia kodu Swift z jego odpowiednikiem w Objective-C++ jest nagłówek mostkujący (bridging header).

Nagłówek mostkujący to plik nagłówkowy, w którym możesz zaimportować wszystkie pliki nagłówkowe Objective-C, które muszą być widoczne dla Twojego kodu Swift.

Być może masz już nagłówek mostkujący w swoim projekcie, ale jeśli nie, możesz utworzyć nowy, wykonując następujące kroki:

  1. W Xcode utwórz nowy plik i nazwij go "SampleApp-Bridging-Header.h"

  2. Zaktualizuj zawartość "SampleApp-Bridging-Header.h" w następujący sposób:

SampleApp-Bridging-Header.h
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

+ #import <React-RCTAppDelegate/RCTDefaultReactNativeFactoryDelegate.h>
  1. Podłącz nagłówek mostkujący w swoim projekcie:
    1. W nawigatorze projektu wybierz nazwę swojej aplikacji (SampleApp, po lewej)
    2. Kliknij Build Settings
    3. Wyszukaj "Bridging Header"
    4. Dodaj względną ścieżkę do nagłówka mostkującego, w przykładzie jest to SampleApp-Bridging-Header.h

Nagłówek mostkowania

Budowanie i uruchamianie aplikacji

Teraz możesz przejść do ostatniego kroku przewodnika po modułach natywnych i powinieneś zobaczyć swoją aplikację działającą z modułem natywnym napisanym w Swift.