Post

Replies

Boosts

Views

Activity

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")
0
0
137
1w
PDF Page external links ( hyperlink) are not working after rendering PDF content to UIView in Swift iOS
The pdf that has external weblink on the first page for accessing they youtube. When i open it pdf of reader or other apps it will be asked open the youtube. I want to support that functionality in UIView level. I copied PDF content to UIView successfully and but cannot see any action, once i click the external web link. Here is the my code steps: Storing pdf file in project level (Doc.pdf) Take the first page and convert that page to Data. (During the practical scenario, i need to store that value as Data first, it will be needed reuse later, So cannot use PDFPage object for processing directly.). Binding Data object with CanvasView and override the CanvasView draw method for copying pdf data to UIView. (During practical scenario, I can't use PDFView object, I have to use custom UIView and it will be needed support other customize operation (ex: erasing, cut, copy etc) Finally, even though all contents are copied successfully, i cannot see any action, once i clicked the external web link. Here is the code example: ViewController.Swift import PDFKit class ViewController: UIViewController { var pdfDocument: PDFDocument? override func loadView() { super.loadView() } func getData(pdfPage: PDFPage) -> Data { let cropBox = pdfPage.bounds(for: .cropBox) var adjustedCropBox = cropBox if ((pdfPage.rotation == 90) || (pdfPage.rotation == 270) || (pdfPage.rotation == -90)) { adjustedCropBox.size = CGSize(width: cropBox.height, height: cropBox.width) } let renderer = UIGraphicsPDFRenderer(bounds: adjustedCropBox) return renderer.pdfData { (ctx) in ctx.beginPage() ctx.cgContext.setFillColor(UIColor.white.cgColor) ctx.fill(adjustedCropBox) pdfPage.transform(ctx.cgContext, for: .cropBox) switch pdfPage.rotation { case 0: ctx.cgContext.translateBy(x: 0, y: adjustedCropBox.height) ctx.cgContext.scaleBy(x: 1, y: -1) case 90: ctx.cgContext.scaleBy(x: 1, y: -1) ctx.cgContext.rotate(by: -.pi / 2) case 180, -180: ctx.cgContext.scaleBy(x: 1, y: -1) ctx.cgContext.translateBy(x: adjustedCropBox.width, y: 0) ctx.cgContext.rotate(by: .pi) case 270, -90: ctx.cgContext.translateBy(x: adjustedCropBox.height, y: adjustedCropBox.width) ctx.cgContext.rotate(by: .pi / 2) ctx.cgContext.scaleBy(x: -1, y: 1) default: break } pdfPage.draw(with: .cropBox, to: ctx.cgContext) } } override func viewDidLoad() { super.viewDidLoad() let fileUrl = Bundle.main.url(forResource: "Doc", withExtension: "pdf") guard let fileUrl else { return } pdfDocument = PDFDocument(url: fileUrl) let firstPage: PDFPage? = pdfDocument?.page(at: 0) print("first page annotation count \(firstPage?.annotations.count)") guard let firstPage else { return } let pdfData = getData(pdfPage: firstPage) let canvasView = CanvasView(data: pdfData) self.view.addSubview(canvasView) NSLayoutConstraint.activate([ canvasView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), canvasView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 0), canvasView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor), canvasView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: 0) ]) } } CanvasView.Swift import PDFKit class CanvasView: UIView { var page: PDFPage? init(data: Data) { super.init(frame: .zero) translatesAutoresizingMaskIntoConstraints = false page = loadPDFPage(pdfData: data) } init(pdfPage: PDFPage){ super.init(frame: .zero) translatesAutoresizingMaskIntoConstraints = false page = pdfPage } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func loadPDFPage(pdfData: Data) -> PDFPage? { guard let document = PDFDocument(data: pdfData) else { return nil } return document.page(at: 0) } override func draw(_ layer: CALayer, in ctx: CGContext) { guard let page else { return } print("num of annotations - \(page.annotations.count)") if let cgPDFPage = page.pageRef { let cropBoxBounds = page.bounds(for: .cropBox) print(page.displaysAnnotations) let scaleX = layer.bounds.width / cropBoxBounds.width let scaleY = layer.bounds.height / cropBoxBounds.height ctx.saveGState() ctx.scaleBy(x: scaleX, y: scaleY) ctx.translateBy(x: -cropBoxBounds.origin.x, y: cropBoxBounds.height + cropBoxBounds.origin.y ) ctx.scaleBy(x: 1, y: -1) ctx.setFillColor(UIColor.white.cgColor) ctx.fill(cropBoxBounds) ctx.drawPDFPage(cgPDFPage) ctx.restoreGState() } } override func draw(_ rect: CGRect) {} } Here the project Special Note: Once i loaded PDFPage from url, it has two link annotations. Once i created PDFPage from Data in CavansView, i cannot see any PDF annotations and it is empty. So I assume, during data conversion process, annotations will not be considered. even though i pass original PDFPage object directly instead of Data, link click actions are not worked. So i need to someone help from how we send PDFAnnotation object data to Data object and How we can support web link behaviour as we expected. Please, help me to resolve this case and i really appreciate your feedback and help.
0
1
575
Jun ’23
Do we need to pay for getting Room Plan Feature ?
We are going to integrate Room Plan Feature to our existing application. I didn't find any pricing plan section for Room Plan feature. Is this feature totally free or is it has a pricing plan? If it has pricing plan, can someone share about it ? Room Plan feature is not Beta version right? Can someone advise us? I really appreciate your feedback and help.
1
0
661
Oct ’22