Getting {"code":"UNIMPLEMENTED"} on local plugin

Capacitor Version

Latest Dependencies:

@capacitor/cli: 7.4.3
@capacitor/core: 7.4.3
@capacitor/android: 7.4.3
@capacitor/ios: 7.4.3

Installed Dependencies:

@capacitor/cli: 7.4.2
@capacitor/android: 7.4.1
@capacitor/core: 7.4.1
@capacitor/ios: 7.4.2

Platforms Affected

  • iOS
  • Android
  • Web

Current Behavior

Plugin is not working and I am having the following error on xcode build

:high_voltage: {“code”:“UNIMPLEMENTED”}

Project Reproduction

  • cant provide it’s corporate

Additional Information

I am trying to create a custom local plugin, for ios. I am following these instructions: Building a Capacitor Plugin | Capacitor Documentation

Below is my code:

ios/App/App/plugins/SafeArea/SafeArea.swift

import Foundation
import UIKit
import Capacitor

@objc public class SafeArea: NSObject {
    @objc public func getInsets(for viewController: UIViewController) -> [String: CGFloat] {
        
        print("Hello SafeArea called")
        // Force layout to ensure safe area insets are accurate
        viewController.view.setNeedsLayout()
        viewController.view.layoutIfNeeded()
        
        let insets = viewController.view.safeAreaInsets
        return [
            "top": insets.top,
            "bottom": insets.bottom,
            "left": insets.left,
            "right": insets.right
        ]
    }
}

ios/App/App/plugins/SafeArea/SafeAreaPlugin.swift

import Foundation
import Capacitor
import UIKit

@objc(SafeAreaPlugin)
public class SafeAreaPlugin: CAPPlugin, CAPBridgedPlugin {

    public let identifier = "SafeAreaPlugin"
    public let jsName = "SafeArea"
    public let pluginMethods: [CAPPluginMethod] = [
        CAPPluginMethod(name: "getInsets", returnType: CAPPluginReturnPromise)
    ]
    
    private let implementation = SafeArea()
    
    @objc public func getInsets(_ call: CAPPluginCall) {
        guard let vc = self.bridge?.viewController else {
            call.reject("Cannot find view controller")
            return
        }
        let insets = implementation.getInsets(for: vc)
        call.resolve(insets)
    }
}

ios/App/App/MyViewController.swift

import UIKit
import Capacitor

class MyViewController: CAPBridgeViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print("Hello from MyViewController!")
    }
    
    override func capacitorDidLoad() {
        bridge?.registerPluginInstance(SafeAreaPlugin())
    }
    
}

ios/App/App/Base.lproj/Main.storyboard

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
    </dependencies>
    <scenes>
        <!--My View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="MyViewController" customModule="App" customModuleProvider="target" sceneMemberID="viewController"/>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="126" y="-30"/>
        </scene>
    </scenes>
</document>

app/plugins/setSafeAreaVars.ts

import { registerPlugin } from '@capacitor/core';

interface Insets {
    top: number;
    bottom: number;
    left: number;
    right: number;
}

interface SafeAreaPlugin {
    getInsets(): Promise<Insets>;
}

const SafeArea = registerPlugin<SafeAreaPlugin>('SafeArea');

export default defineNuxtPlugin(() => {
    const setCssVariables = async() => {
        try {
            const insets = await SafeArea.getInsets();

            if (insets) {
                document.documentElement.style.setProperty('--safe-area-top', `${insets.top}px`);

                document.documentElement.style.setProperty('--safe-area-bottom', `${insets.bottom}px`);

                document.documentElement.style.setProperty('--safe-area-left', `${insets.left}px`);

                document.documentElement.style.setProperty('--safe-area-right', `${insets.right}px`);
            }
        } catch(e) {
            console.error('Failed to get safe area insets from plugin:', e);
        }
    };

    setCssVariables();
});

Note: plugin works as expected on Android.

What am I doing wrong and I get this error code?

1 Like