I am working on showing the React-native-View in the swift project. I download the bunlde file through asynchronous operation, save the bundle file in the app directory, and use it to create the RCTROOTVIEW. My current problem is that when I try to show the view, I see a blank screen because the process of downloading and saving the file is asynchronous. How can I solve this problem?
my source
import UIKit
import React
import SwiftUI
import Foundation
struct ReactNativeView: UIViewRepresentable {
let mockData: NSDictionary = ["scores": [["name": "Alex", "value": "42"], ["name": "Joel", "value": "10"]]]
let jsCodeLocation = URL(string: "https://CDN.com/main.jsbundle")!
func getDocumentsDirectory() -> URL {
return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
}
func downloadBundle(url: URL, completion: @escaping (URL?, Error?) -> Void) {
let documentsUrl = getDocumentsDirectory()
let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)
URLSession.shared.downloadTask(with: url) { (tempLocalUrl, response, error) in
guard let tempLocalUrl = tempLocalUrl, error == nil else {
print("Error downloading bundle: \(String(describing: error))")
completion(nil, error)
return
}
do {
try FileManager.default.moveItem(at: tempLocalUrl, to: destinationUrl)
print("File moved to destination [\(destinationUrl.path)]")
completion(destinationUrl, nil)
} catch {
print("Error moving file to destination: \(error)")
completion(nil, error)
}
}.resume()
}
func makeUIView(context: Context) -> UIView {
var rootView : RCTRootView?
downloadBundle(url: jsCodeLocation) { _url, error in
guard let localURL = _url, error == nil else {
print("error saving file")
return
}
rootView = RCTRootView(
bundleURL: localURL,
moduleName: "RNHighScores",
initialProperties: mockData as [NSObject: AnyObject],
launchOptions: nil
)
}
return rootView ?? UIView()
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
use code
@objc private func showReactNativeView() {
let reactNativeViewController = UIHostingController(rootView: ReactNativeView())
present(reactNativeViewController, animated: true, completion: nil)
}
...
containerButton.rx.tap
.asDriverOnErrorJustComplete()
.drive(onNext: { [weak self] in
self?.showReactNativeView()
})
.disposed(by: disposeBag)
Finally, if you already have a downloaded file, I want to erase or overwrite it.