Xcode memory meter goes to high while converting USDZ file to scn file by programatically

We have requirement adding usdz file to UIView and showing the it’s content and archive the data and save to file. When user open the file, we need to unarchive that usdz content and binding with UIView and showing it to user. Initially, we created SCNScene object passing usdz file url like below.

do {
     usdzScene = try SCNScene(url: usdzUrl)
 } catch let error as NSError {
     print(error)
 }

Since SCNScene support to NSSecureCoding protocol , we directly archive that object and save it file and load back it from file and created SCNScene object using NSKeyedUnarchiver process.

But for some files, we realised high memory consumption while archiving the SCNScene object using below line.

 func encode(with coder: NSCoder) { 
    coder.encode(self.scnScene, forKey: "scnScene")
}

File referene link : toy_drummer_idle.usdz

When we analyse apple documentation (check discussion section) , it said, scn file extension is the fastest format for processing than the usdz.

So we used SCNSecne write to feature for creating scn file from given usdz file.

After that, When we do the archive SCNScene object that was created by sun file url, the archive process is more faster and it will not take high memory as well. It is really faster previous case now.

But unfortunately, SCNScene write method will take lot of time for this conversion and memory meter is also going high and it will be caused to app crash as well.

I check the output file size as well. The given usdz file size is 18MB and generated scn file size is 483 MB. But SCNScene archive process is so fast.

Please, analyse this case and please, provide some guideline how we can optimise this behaviour. I really appreciate your feedback.

Full Code:

import UIKit
import SceneKit

class ViewController: UIViewController {

var scnView: SCNView?
var usdzScene: SCNScene?
var scnScene: SCNScene?

lazy var exportButton: UIButton = {
    let btn = UIButton(type: UIButton.ButtonType.system)
    btn.tag = 1
    btn.backgroundColor = UIColor.blue
    btn.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)
    btn.setTitle("USDZ to SCN", for: .normal)
    btn.setTitleColor(.white, for: .normal)
    btn.layer.borderColor = UIColor.gray.cgColor
    btn.titleLabel?.font = .systemFont(ofSize: 20)
    btn.translatesAutoresizingMaskIntoConstraints = false
    return btn
}()


func deleteTempDirectory(directoryName: String) {
    let tempDirectoryUrl = URL(fileURLWithPath: NSTemporaryDirectory())
    let tempDirectory = tempDirectoryUrl.appendingPathComponent(directoryName, isDirectory: true)
    if FileManager.default.fileExists(atPath:  URL(string: tempDirectory.absoluteString)!.path) {
        do{
            try FileManager.default.removeItem(at: tempDirectory)
        }
        catch let error as NSError {
            print(error)
        }
    }
}

func createTempDirectory(directoryName: String) -> URL? {
    let tempDirectoryUrl = URL(fileURLWithPath: NSTemporaryDirectory())
    let toBeCreatedDirectoryUrl = tempDirectoryUrl.appendingPathComponent(directoryName, isDirectory: true)
    if !FileManager.default.fileExists(atPath:  URL(string: toBeCreatedDirectoryUrl.absoluteString)!.path) {
        do{
            try FileManager.default.createDirectory(at: toBeCreatedDirectoryUrl, withIntermediateDirectories: true, attributes: nil)
        }
        catch let error as NSError {
            print(error)
            return nil
        }
    }
    return toBeCreatedDirectoryUrl
}

@IBAction func buttonPressed(_ sender: UIButton){
    let scnFolderName = "SCN"
    let scnFileName = "3D"
    
    deleteTempDirectory(directoryName: scnFolderName)
    guard let scnDirectoryUrl = createTempDirectory(directoryName: scnFolderName) else {return}
    
    let scnFileUrl =  scnDirectoryUrl.appendingPathComponent(scnFileName).appendingPathExtension("scn")
    guard let usdzScene else {return}
    
    
    let result = usdzScene.write(to: scnFileUrl, options: nil, delegate: nil, progressHandler: nil)
    if (result) {
        print("exporting process is success.")
    } else {
        print("exporting process is failed.")
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    let usdzUrl: URL? = Bundle.main.url(forResource: "toy_drummer_idle", withExtension: "usdz")
    guard let usdzUrl else {return}
    do {
        usdzScene = try SCNScene(url: usdzUrl)
    } catch let error as NSError {
        print(error)
    }
    guard let usdzScene else {return}
    
    scnView = SCNView(frame: .zero)
    guard let scnView else {return}
    scnView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(scnView)
    self.view.addSubview(exportButton)
    NSLayoutConstraint.activate([
        scnView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
        scnView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
        scnView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        scnView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -30),
        
        exportButton.widthAnchor.constraint(equalToConstant: 200),
        exportButton.heightAnchor.constraint(equalToConstant: 40),
        exportButton.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
        exportButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
    ])
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {[weak self] in
        guard let self else {return}
        loadModel(scene: usdzScene)
    }
}


func loadModel(scene: SCNScene){
    guard let scnView else {return}
    scnView.autoenablesDefaultLighting = true
    scnView.scene = scene
    scnView.allowsCameraControl = true
}
}
![]("https://developer.apple.com/forums/content/attachment/5ff0197b-7e0b-4efe-b295-cc205c73dc02" "title=Screenshot 2024-06-20 at 12.23.40.png;width=1712;height=1013")

Xcode memory meter goes to high while converting USDZ file to scn file by programatically
 
 
Q