Create a 3D View of Your Room Using iOS RoomPlan API

Create a 3D View of Your Room Using iOS RoomPlan API

Implement RoomPlan API in your iOS Application.

Powered by ARKit, RoomPlan is a new Swift API that utilizes the camera and LiDAR Scanner on iPhone and iPad to create a 3D floor plan of a room, including key characteristics such as dimensions and types of furniture. ~ Apple

Overview - Dive In

In today's digital age, bringing the physical world into the digital realm has never been easier. RoomPlan, an API powered by ARKit, is designed to revolutionize how we interact with spaces using our iPhones and iPads.

RoomPlan offers a seamless experience, leveraging the power of your device's camera and LiDAR Scanner to create stunning 3D floor plans of rooms in real time. The RoomPlan will work on devices supporting LiDAR with iOS and iPadOS 16.0+.

LiDAR is available on the Pro and Pro Max models of iPhone 12, 13, 14, and 15. Third-generation 11-inch and fifth-generation 12.9-inch iPad Pro models from 2020 and later also have LiDAR.

Thanks to LiDAR technology, RoomPlan offers lightning-fast, real-time scanning capabilities. Users can scan their surroundings effortlessly, with built-in coaching UI guiding optimal scans. Visual feedback ensures users know exactly how their scan is progressing.

RoomPlan doesn't just stop at creating 3D floor plans—it goes further by providing detailed USD or USDZ file formats. These files include dimensions for each component recognized in the room, such as walls and furniture types. Plus, users can fine-tune the dimensions and placement of each component using compatible tools like AutoCAD.

Implementation - Let's Get Started

Let's look at the following steps to implement room plan API in your project.

  1. Setting Up Your Project

    Begin by creating a new project in Xcode and give it a name that resonates with your app's purpose. Once the project is set up, create a new file named RoomCaptureViewController.swift, where all the magic will happen. Also, don't forget to add a button in your main ViewController.swift that will lead users to the RoomCaptureViewController by navigation.

  2. Adding Camera Usage Description

    It's crucial to inform users how the camera will be used. Open the Info.plist file and add NSCameraUsageDescription. This simple step ensures transparency and builds trust with your users.

  3. Creating the RoomCaptureView

    In RoomCaptureViewController.swift, import RoomPlan and initialize the RoomCaptureView. This component will handle the scanning process and provide real-time feedback to users.

     import UIKit
     import RoomPlan
    
     class RoomCaptureViewController: UIViewController, RoomCaptureViewDelegate {
    
         private var roomCaptureView: RoomCaptureView!
         private var roomCaptureSessionConfig: RoomCaptureSession.Configuration = RoomCaptureSession.Configuration()
    
         override func viewDidLoad() {
             super.viewDidLoad()
    
             // call this method to setup room capture view
             setupRoomCaptureView()
         }
    
         private func setupRoomCaptureView() {
             roomCaptureView = RoomCaptureView(frame: view.bounds)
             roomCaptureView.delegate = self
    
             view.insertSubview(roomCaptureView, at: 0)
         }
    
  4. Implementing Delegate Methods

    Make your RoomCaptureViewController conform to the RoomCaptureViewDelegate protocol. This allows you to receive updates during the scanning process and capture the final results once scanning is complete.

    
     // variable to store captured room data
     private var finalResults: CapturedRoom?
    
     ...
    
     func captureView(shouldPresent roomDataForProcessing: CapturedRoomData, error: Error?) -> Bool {
         return true
     }
    
     func captureView(didPresent processedResult: CapturedRoom, error: Error?) {
         finalResults = processedResult
         self.exportButton?.isEnabled = true
         self.activityIndicator?.stopAnimating()
     }
    
     ...
    
  5. Starting and Stopping the Capture Session

    Add methods to start and stop the capture session. These functions ensure smooth operation of the scanning process and manage the session's lifecycle effectively.

     // variable to check if scan is in progress    
     private var isScanning: Bool = false
    
     ...    
    
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
         startSession()
     }
    
     override func viewWillDisappear(_ flag: Bool) {
         super.viewWillDisappear(flag)
         stopSession()
     }
    
     private func startSession() {
         isScanning = true
         roomCaptureView?.captureSession.run(configuration: roomCaptureSessionConfig)
     }
    
     private func stopSession() {
         isScanning = false
         roomCaptureView?.captureSession.stop()
     }
    
  6. Adding Control Buttons

    Enhance user experience by adding control buttons such as Cancel, Done, and Share. These buttons allow users to interact with the scanning session effortlessly. Add in Storyboard and create actions and outlets in RoomCaptureViewController.swift.

     ...
    
     @IBOutlet var exportButton: UIButton?
     @IBOutlet var doneButton: UIButton?
     @IBOutlet var cancelButton: UIButton?
    
     ...
    
     @IBAction func doneScanning(_ sender: UIBarButtonItem) {
         if isScanning { stopSession() } else { cancelScanning(sender) }
         self.exportButton?.isEnabled = false
         self.activityIndicator?.startAnimating()
     }
    
     @IBAction func cancelScanning(_ sender: UIBarButtonItem) {
         navigationController?.dismiss(animated: true)
     }
    
     @IBAction func exportResults(_ sender: UIButton) {
         let destinationFolderURL = FileManager.default.temporaryDirectory.appending(path: "Export")
         let destinationURL = destinationFolderURL.appending(path: "Room.usdz")
         let capturedRoomURL = destinationFolderURL.appending(path: "Room.json")
         do {
             try FileManager.default.createDirectory(at: destinationFolderURL, withIntermediateDirectories: true)
             let jsonEncoder = JSONEncoder()
             let jsonData = try jsonEncoder.encode(finalResults)
             try jsonData.write(to: capturedRoomURL)
             try finalResults?.export(to: destinationURL, exportOptions: .parametric)
    
             let activityVC = UIActivityViewController(activityItems: [destinationFolderURL], applicationActivities: nil)
             activityVC.modalPresentationStyle = .popover
    
             present(activityVC, animated: true, completion: nil)
             if let popOver = activityVC.popoverPresentationController {
                 popOver.sourceView = self.exportButton
             }
         } catch {
             print("Error = \(error)")
         }
     }
    
     ...
    
  7. Managing Button Visibility

    Dynamically manage the visibility of buttons based on the scanning state. For example, hide the export button while scanning is in progress and show it once the scan is complete.

     ...
    
     private func startSession() {
         isScanning = true
         roomCaptureView?.captureSession.run(configuration: roomCaptureSessionConfig)
    
         setActiveNavBar()
     }
    
     private func stopSession() {
         isScanning = false
         roomCaptureView?.captureSession.stop()
    
         setCompleteNavBar()
     }
    
     ...
    
     private func setActiveNavBar() {
         UIView.animate(withDuration: 1.0, animations: {
             self.cancelButton?.tintColor = .white
             self.doneButton?.tintColor = .white
             self.exportButton?.alpha = 0.0
         }, completion: { complete in
             self.exportButton?.isHidden = true
         })
     }
    
     private func setCompleteNavBar() {
         self.exportButton?.isHidden = false
         UIView.animate(withDuration: 1.0) {
             self.cancelButton?.tintColor = .systemBlue
             self.doneButton?.tintColor = .systemBlue
             self.exportButton?.alpha = 1.0
         }
     }
    

And, the End. You're successfully implemented RoomPlan in your project.

But wait don't forget to read the closing paragraph and Find the link to complete code below.

Conslusion - Final Step

Now that you've successfully implemented RoomPlan API in your project. Try improving the code and add new features for saving and interacting with the 3D scanned model. Be creative, Happy Coding 👋

Click here to check the complete sample code at Apple Developer Website 🍎


Feel free to ask any of your queries in the comments!!!


Also, check out my last blog "Learn To Use Git & Github: Add Projects To Your Github Repository" by visiting the link below:

https://himanshugoyal.hashnode.dev/learn-to-use-git-github-add-projects-to-your-github-repository


Image in blog cover by Alexandra Gorn on Unsplash