Add framework to project

Drag the files FloorplannerViewer.framework and FloorplannerViewer.bundle into your applications folder.

Modify the application’s target Build Settings and add the option -ObjC to Other Linker Flags.

Use Viewer control

Load project

Using [loadProjectWithId:] and [loadProjectFromUrl:] you can load a new project using either a project id or an url to a fml project.

// import the headers to your source file
@import FloorplannerViewer;

// Load project using project id:
[viewerControl loadProjectWithId:33549795];

// Load project from a url:
NSURL* url = [NSURL URLWithString:@"https://portals.floorplanner.com/projects/33549795.fml"];
[viewerControl loadProjectFromUrl:url];
// import the headers to your source file
import FloorplannerViewer

// Load project using project id:
viewerControl.loadProjectWithId(33549795)

// Load project from a url:
let url = NSURL(string: "https://portals.floorplanner.com/projects/33549795.fml")!
viewerControl.loadProjectFromUrl(url)

Change view mode

Using viewMode you can change the active viewmode for the viewer.

// Change view mode
if (viewerControl.viewMode == FPViewerViewMode3D) {
  viewerControl.viewMode = FPViewerViewMode2D;
} else {
  viewerControl.viewMode = FPViewerViewMode3D;
}
// Change view mode
if viewerControl.viewMode == .Mode3D {
  viewerControl.viewMode = .Mode2D
} else {
  viewerControl.viewMode = .Mode3D
}

Get designs in project

The following example lists the available designs in an UIActionSheet using [getFloors:], shows them and selects the new design using [loadDesign:].

[viewerControl getFloors:^(NSArray<FPFloor*>* floors, NSError* error) {
  dispatch_async(dispatch_get_main_queue(), ^{
    UIActionSheet* actionSheet = [[UIActionSheet alloc] init];
    designs = [[NSMutableArray alloc] init];

    for (FPFloor* floor in floors) {
      for (FPDesign* design in floor.designs {
        [actionSheet addButtonWithTitle:design.name];
        [designs addObject:design];
      }
    }

    actionSheet.delegate = self;
    [actionSheet showInView:self.view];
  });
}];

[viewerControl loadDesign:designs[designIndex]];
viewerControl.getFloors {floors, error in
  dispatch_async(dispatch_get_main_queue()) {
    let actionSheet = UIActionSheet()
    self.designs = [FPDesign]();

    for floor in floors {
      for design in floor.designs {
        actionSheet.addButtonWithTitle(design.name)
        self.designs.append(design)
      }
    }

    actionSheet.delegate = self
    actionSheet.showInView(self.view)
  }
}

viewerControl.loadDesign(designs[designIndex])

Use in SwiftUI

Apple is moving to a new UI system called SwiftUI. The Floorplanner Viewer control also works in SwiftUI but it has to be wrapped inside a UIViewRepresentable control. Below you can find an example on how this can be done.

import SwiftUI
import FloorplannerViewer

struct FloorplanViewer: UIViewRepresentable {
    
  class Coordinator : NSObject, FPViewerDelegate {
    func viewerDidFinishLoadProject(_ viewer: FPViewer) {
      viewer.getFloors {floors, error in
        for floor in floors! {
          for design in floor.designs {
            DispatchQueue.global(qos: .background).async {
              DispatchQueue.main.async {
                viewer.load(design)
              }
            }
            return
          }
        }
      }
    }
  }

  func makeUIView(context: Context) -> FPViewer {
    let control = FPViewer()
    control.delegate = context.coordinator
    control.viewMode = .mode3D

    // Load demo project
    control.loadProject(from: URL(string: "https://floorplanner.com/api/v2/projects/61301631/fml")!)

    return control
  }
    
  func makeCoordinator() -> Coordinator {
    return Coordinator()
  }

  func updateUIView(_ uiView: FPViewer, context: Context) {
  }
}

struct ContentView: View {
  var body: some View {
    FloorplanViewer()
      .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}