Skip to main content

Mobile integration on iOS devices

The document editor can be embedded in an iOS application using the WKWebView component. A complete demo project is available on GitHub.

Integration based on the ONLYOFFICE test sample

This example shows how to integrate ONLYOFFICE mobile web editors with the ONLYOFFICE test or DMS sample.

iOS integration via test sample

Opening ONLYOFFICE editors

  1. Download and install ONLYOFFICE Docs Enterprise or Developer.

  2. Download the mobile demo sample for iOS from GitHub.

  3. Open the EditorWebViewDemo.xcodeproj project with Xcode to modify code fragments of this example for your DMS to work correctly.

  4. To display the main page of your DMS, specify the address of the ONLYOFFICE Docs example page in the DOCUMENT_SERVER_EXAMPLE_URL property in the EditorWebViewDemo.xcconfig configuration file:

    DOCUMENT_SERVER_EXAMPLE_URL = documentserver

    Where documentserver is the name of the server where ONLYOFFICE Docs is installed.

    tip

    Don't have a document server yet? Register for a free ONLYOFFICE Docs Cloud and use the public IP address or public DNS name of your instance as documentserver. You can find them in the Instances section of the cloud console.

    If DOCUMENT_SERVER_EXAMPLE_URL is specified, the DMS main page is loaded. Otherwise, an error occurs:

    private func load() {
    if Env.documentServerExampleUrl.replacingOccurrences(of: "https://", with: "").isEmpty {
    showAlert(title: "Error", message: "You must specify the document server example page address for \"DOCUMENT_SERVER_EXAMPLE_URL\" value in configuration file.")
    return
    }

    guard let url = URL(string: Env.documentServerExampleUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "") else {
    return
    }

    webView.load(URLRequest(url: url))
    }
    iOS error iOS managing
  5. Use the DocumentServerViewController controller to open the editors correctly on iOS devices. In this controller, define a function to open a document via WKWebView component. First, request an absolute URL and check if it contains the "/editor?" string. If so, add an additional query parameter (the mobile platform type) to the link:

    private var openDocumentMarker = "/editor?"
    private var additionalQueryParameters = ["type": "mobile"]

    func webView(_ webView: WKWebView,
    decidePolicyFor navigationAction:
    WKNavigationAction,
    decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
    {
    guard let urlString = navigationAction.request.url?.absoluteString else {
    decisionHandler(.cancel)
    return
    }

    if urlString.contains(openDocumentMarker),
    let redirectUrl = navigationAction.request.url?.appendingQueryParameters(additionalQueryParameters)
    {
    decisionHandler(.cancel)
    navigator.navigate(to: .documentServerEditor(url: redirectUrl))
    } else {
    reloadItem.isEnabled = true
    backItem.isEnabled = webView.canGoBack
    forwardItem.isEnabled = webView.canGoForward

    title = navigationAction.request.url?.host ?? ""

    decisionHandler(.allow)
    }

    }
  6. In the DocumentServerViewController controller, create the navigation actions available on the DMS main page. For example, in our test sample, they are specified with the interface elements such as the Reload, Back, and Forward buttons.

  7. For easy interaction with the editor, define the Activity Indicator and Progress View UI components.

    The full code for DocumentServerViewController can be found here.

    Activity indicator Progress view Buttons
  8. To start working with documents, display the ONLYOFFICE editor on your mobile device via the WKWebView component. To do this, set up WKWebView and layout in the DocumentServerEditorViewController controller as follows:

    private lazy var webViewConfiguration: WKWebViewConfiguration = {
    let preferences = WKPreferences()
    let dropSharedWorkersScript = WKUserScript(
    source: "delete window.SharedWorker;",
    injectionTime: WKUserScriptInjectionTime.atDocumentStart,
    forMainFrameOnly: false
    )
    preferences.javaScriptEnabled = true
    $0.userContentController.addUserScript(dropSharedWorkersScript)
    $0.preferences = preferences
    return $0
    }(WKWebViewConfiguration())

    private func configureView() {
    webView = WKWebView(frame: .zero, configuration: webViewConfiguration)

    view.addSubview(webView)
    webView.translatesAutoresizingMaskIntoConstraints = false

    webView.navigationDelegate = self
    webView.uiDelegate = self

    if let webViewSuperview = webView.superview {
    webView.topAnchor.constraint(equalTo: webViewSuperview.topAnchor).isActive = true
    webView.leadingAnchor.constraint(equalTo: webViewSuperview.leadingAnchor).isActive = true
    webView.bottomAnchor.constraint(equalTo: webViewSuperview.bottomAnchor).isActive = true
    webView.trailingAnchor.constraint(equalTo: webViewSuperview.trailingAnchor).isActive = true
    }
    }
  9. In the Xcode toolbar, select a build scheme and a device where the app will be run. After that, choose Product -> Run, or click the Run button in the project toolbar to build and run your code.

  10. On the main screen of the application, select the Using DocumentServer option to demonstrate an example of integrating ONLYOFFICE mobile web editors with the ONLYOFFICE test or DMS sample.

Closing ONLYOFFICE editors

Use the DocumentServerEditorViewController controller to exit from the editor. When the user navigates back to the DMS main page URL, the controller intercepts the navigation and pops back to the previous screen:

func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
{
guard let urlString = navigationAction.request.url?.absoluteString else {
decisionHandler(.cancel)
return
}

if urlString == Env.documentServerExampleUrl {
decisionHandler(.cancel)
navigationController?.popViewController(animated: true)
} else {
decisionHandler(.allow)
}
}
Go back

The full code for DocumentServerEditorViewController can be found here.

Integration based on the ONLYOFFICE Docs API

This example shows how to open the ONLYOFFICE editors via WKWebView using the editor configuration described in the API documentation and the configuration examples.

iOS integration via api

Opening ONLYOFFICE editors

  1. Download and install ONLYOFFICE Docs Enterprise or Developer.

  2. Download the mobile demo sample for iOS from GitHub.

  3. Open the EditorWebViewDemo.xcodeproj project with Xcode to modify code fragments of this example for your DMS to work correctly.

  4. Create an empty .html file. The demo project editor.html resource is used as a template.

  5. Add the <div> element as shown below:

    <div id="placeholder"></div>
  6. Specify your ONLYOFFICE Docs link with the JavaScript API that will be used for your website:

    <script type="text/javascript" src="https://documentserver/web-apps/apps/api/documents/api.js"></script>

    Where documentserver is the name of the server where ONLYOFFICE Docs is installed.

    tip

    Don't have a document server yet? Register for a free ONLYOFFICE Docs Cloud and use the public IP address or public DNS name of your instance as documentserver. You can find them in the Instances section of the cloud console.

  7. Add the script initializing the Document Editor for the <div> element with the configuration for the document you want to open. Define event handler functions that forward events to native code via window.webkit.messageHandlers, and pass them to the editor config:

    <script type="text/javascript">

    var handler = window.webkit.messageHandlers;

    var onAppReady = function() {
    handler.onAppReady.postMessage({});
    };

    var onDownloadAs = function(event) {
    handler.onDownloadAs.postMessage({fileType: event.data.fileType, url: event.data.url});
    };

    // ... other event handlers ...

    window.docEditor = new DocsAPI.DocEditor("placeholder",
    {
    {external_config},
    "type": "mobile",
    "events": {
    "onAppReady": onAppReady,
    "onDocumentReady": onDocumentReady,
    "onDownloadAs": onDownloadAs,
    "onError": onError,
    "onInfo": onInfo,
    "onRequestClose": onRequestClose,
    "onRequestInsertImage": onRequestInsertImage,
    "onRequestUsers": onRequestUsers,
    "onWarning": onWarning,
    }
    });

    </script>
  8. To start working with documents, display the ONLYOFFICE editor on your mobile device via the WKWebView component. To do this, specify the EditorViewController controller. Request the URL to the editor.html file, get its contents, replace the placeholder values with the actual configuration from samples.plist (where all sample configurations are categorized according to the API documentation Try page), sign the config with a JWT token, and inject the document server URL:

    private func load() {
    guard let url = Bundle.main.url(forResource: "editor", withExtension: "html") else {
    return
    }

    var html = ""

    do {
    html = try String(contentsOf: url)
    } catch {
    print(error)
    }

    var config = config?
    .replacingOccurrences(of: "{KEY}", with: UUID().uuidString)
    .replacingOccurrences(of: "{DOC_URL_PATH}", with: Env.documentServerFilesUrl)
    .replacingOccurrences(of: "{CALLBACK_URL}", with: Env.editorCallbackUrl)
    .toDictionary() ?? [:]

    config["token"] = JWT.encode(claims: config, algorithm: .hs256(Env.documentServerJwtSecret.data(using: .utf8)!))

    let jsonString = (config.jsonString(prettify: true) ?? "")
    .dropLast()
    .dropFirst()

    html = html
    .replacingOccurrences(of: "{document_server_url}", with: Env.documentServerUrl)
    .replacingOccurrences(of: "{external_config}", with: jsonString)

    webView.loadHTMLString(html, baseURL: nil)
    }
    Editor samples

    The full code for EditorViewController can be found here.

  9. In the Xcode toolbar, select a build scheme and a device where the app will be run. After that, choose Product -> Run, or click the Run button in the project toolbar to build and run your code.

  10. On the main screen of the application, select the Using API Configuration option to demonstrate how to open the ONLYOFFICE mobile web editors using the editor configuration described in the API documentation and the configuration examples.

  11. On the next page, choose one of the configuration samples to open the resulting HTML in the WKWebView component.

Working with documents

To work with documents (open, download, insert images, mention other users, etc.), use the API documentation with its events and methods:

  1. To track events and call appropriate methods, handle the events of ONLYOFFICE editors in native code by the EditorEventsHandler controller and then delegate them to EditorViewController:

    var delegate: EditorEventsDelegate?

    convenience init(configuration: WKWebViewConfiguration) {
    self.init()

    configuration.userContentController.add(self, name: EditorEvent.onDownloadAs.rawValue)
    }

    extension EditorEventsHandler: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController,
    didReceive message: WKScriptMessage)
    {
    let event = EditorEvent(rawValue: message.name)

    switch event {
    case .onDownloadAs:
    guard
    let json = message.body as? [String: Any],
    let fileType = json["fileType"] as? String,
    let url = json["url"] as? String
    else { return }

    delegate?.onDownloadAs(fileType: fileType, url: url)
    }
    }
    }

    The onDownloadAs event is used here as an example. Register an object as a handler for a particular message by calling configuration.userContentController.add(self, name: messageName) during the WKWebView configuration. Get the event parameters (file type and URL) and delegate the event handling to EditorViewController:

    func onDownloadAs(fileType: String, url: String) {
    print("⚡ ONLYOFFICE Document Editor create file: \(url)")
    }
  2. Define the callMethod function to call API methods from native code. It can take string, boolean or object values as arguments. This function adds the method name and its arguments to the string with the JavaScript code and then evaluates JavaScript in the WKWebView component with the evaluateJavaScript method:

    private func callMethod(function: String, arg: Bool) {
    let javascript = "window.docEditor.\(function)(\(arg))"
    webView.evaluateJavaScript(javascript, completionHandler: nil)
    }

    private func callMethod(function: String, arg: String) {
    let javascript = "window.docEditor.\(function)(\"\(arg)\")"
    webView.evaluateJavaScript(javascript, completionHandler: nil)
    }

    private func callMethod(function: String, arg: [String: Any]) {
    guard
    let json = try? JSONSerialization.data(withJSONObject: arg, options: []),
    let jsonString = String(data: json, encoding: .utf8)
    else {
    return
    }

    let javascript = "window.docEditor.\(function)(\(jsonString))"
    webView.evaluateJavaScript(javascript, completionHandler: nil)
    }

    The full code for EditorEventsHandler can be found here.

  3. To display the result of downloading and printing a document, use the PreviewController controller. This controller is based on QLPreviewController. Download a document by its URL and set the dataSource and delegate properties to QLPreviewController:

    func present(url: URL, in parent: UIViewController, complation: @escaping (() -> Void)) {
    download(url: url) { fileUrl in
    DispatchQueue.main.async {
    guard let fileUrl = fileUrl else {
    complation()
    return
    }

    self.fileUrl = fileUrl

    let quickLookController = QLPreviewController()
    quickLookController.dataSource = self
    quickLookController.delegate = self

    if QLPreviewController.canPreview(fileUrl as QLPreviewItem) {
    quickLookController.currentPreviewItemIndex = 0
    parent.present(quickLookController, animated: true, completion: nil)
    }
    complation()
    }
    }
    }

    The full code for PreviewController can be found here.