ios – How to make update View when use UIViewRepresentable in swift project


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.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img