Capacitor iOS Plugin Guide
Building Capacitor plugins for iOS involves writing Swift (or Objective-C) to interface with Apple's iOS SDKs.
Getting Started
To get started, first generate a plugin as shown in the Getting Started section of the Plugin guide.
Next, open Package.swift
in Xcode. You then want to navigate to the .swift files for your plugin.
For example, for a plugin with the Plugin Class Name EchoPlugin
, you should open ios/Sources/EchoPlugin/EchoPlugin.swift
and ios/Sources/EchoPlugin/Echo.swift
.
Plugin Basics
A Capacitor plugin for iOS has two simple Swift classes, one is implementation class that extends NSObject
, where you should put the plugin logic and another that extends CAPPlugin
and CAPBridgedPlugin
and has some exported methods that will be callable from JavaScript and wraps the implementation methods.
Simple Example
In the generated example, there is a simple echo plugin with an echo
function that simply returns a value that it was given.
This example demonstrates a few core components of Capacitor plugins: receiving data from a Plugin Call, and returning data back to the caller:
Echo.swift
import Foundation
@objc public class Echo: NSObject {
@objc public func echo(_ value: String) -> String {
print(value)
return value
}
}
EchoPlugin.swift
import Foundation
import Capacitor
@objc(EchoPlugin)
public class EchoPlugin: CAPPlugin, CAPBridgedPlugin {
public let identifier = "EchoPlugin"
public let jsName = "Echo"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "echo", returnType: CAPPluginReturnPromise)
]
private let implementation = Echo()
@objc func echo(_ call: CAPPluginCall) {
let value = call.getString("value") ?? ""
call.resolve([
"value": implementation.echo(value)
])
}
}
Accessing Call Data
Each plugin method receives an instance of CAPPluginCall
containing all the information of the plugin method invocation from the client.
A client can send any data that can be JSON serialized, such as numbers, text, booleans, objects, and arrays. This data
is accessible on the options
field of the call instance, or by using convenience methods such as getString
or getObject
. Passing and accessing some of these values has some peculiarities to be aware of, as discussed separately.
For example, here is how you'd get data passed to your method:
@objc func storeContact(_ call: CAPPluginCall) {
let name = call.getString("yourName") ?? "default name"
let address = call.getObject("address") ?? [:]
let isAwesome = call.getBool("isAwesome") ?? false
guard let id = call.options["id"] as? String else {
call.reject("Must provide an id")
return
}
// ...
call.resolve()
}
Notice the various ways data can be accessed on the CAPPluginCall
instance, including how to require
options using guard
.
Returning Data Back
A plugin call can either succeed or fail. Plugin calls borrow method names from JavaScript promises: call resolve()
to indicate success (optionally returning data) and use reject()
to indicate failure with an error message.
The resolve()
method of CAPPluginCall
takes a dictionary and supports JSON-serializable data types. Here's an example of returning data back to the client:
call.resolve([
"added": true,
"info": [
"id": id
]
])
To fail, or reject a call, call reject()
, passing an error string and optionally an error code and Error
instance:
call.reject(error.localizedDescription, nil, error)
Running Code on Plugin Load
Occasionally, plugins may need to run some code when the plugin is first loaded. For example, this would be a good place to set up any Notification Center event handlers.
To do this, provide an implementation for the load()
method:
override public func load() {
}