You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Capacitor插件无法在iOS与Vue应用间通信问题求助

iOS主应用与Vue/JS通过Capacitor自定义插件通信时出现UNIMPLEMENTED错误的解决方法

我需要实现iOS主应用与Vue/JS代码的通信,将VoIP Token从iOS端传递到Vue端。参考Capacitor官方文档创建了自定义插件,插件包含get/set方法用于跨端数据交互,但每次调用插件获取存储的Token时,Xcode调试都会报错:Error getting VoIP token: {"code":"UNIMPLEMENTED"}。

调试日志显示Swift代码获取到Token后才会打印VoIP插件初始化信息,排除了异步时序问题。尝试过添加延迟定时器,也确认插件已包含在Podfile并参与编译,但问题仍未解决。


相关代码

iOS端单例类代码(QuillCapacitorPlugin.swift)

import Foundation

@objc public class QuillCapacitorPlugin: NSObject {
    // Singleton instance
    @objc public static let shared = QuillCapacitorPlugin()
    
    // Stored variable
    var storedValue: String?
    
    // Method to set the stored value
    @objc public func setStoredValue(_ value: String) {
        self.storedValue = value
    }
    
    // Method to get the stored value
    @objc public func getStoredValue() -> String? {
        return self.storedValue
    }
    
    // Existing echo method
    @objc public func echo(_ value: String) -> String {
        print(value)
        return value
    }
}

iOS端插件实现类代码(QuillCapacitorPluginPlugin.swift)

import Foundation
import Capacitor

@objc(QuillCapacitorPluginPlugin)
public class QuillCapacitorPluginPlugin: CAPPlugin {
    // Use the shared instance
    private let implementation = QuillCapacitorPlugin.shared
    
    // MARK: - Plugin Methods
    
    @objc func echo(_ call: CAPPluginCall) {
        let value = call.getString("value") ?? ""
        call.resolve([
            "value": implementation.echo(value)
        ])
    }
    
    @objc func setStoredValue(_ call: CAPPluginCall) {
        let value = call.getString("value") ?? ""
        implementation.setStoredValue(value)
        call.resolve()
    }
    
    @objc func getStoredValue(_ call: CAPPluginCall) {
        if let value = implementation.getStoredValue() {
            call.resolve([
                "value": value
            ])
        } else {
            call.reject("No value stored")
        }
    }
}

JS端插件注册代码(index.ts)

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

import type { QuillCapacitorPluginPlugin } from './definitions';

const QuillCapacitorPlugin = registerPlugin<QuillCapacitorPluginPlugin>('QuillCapacitorPlugin', {
  web: () => import('./web').then((m) => new m.QuillCapacitorPluginWeb()),
});

export * from './definitions';
export { QuillCapacitorPlugin };

JS端接口定义(definition.ts)

export interface QuillCapacitorPluginPlugin {
  echo(options: { value: string }): Promise<{ value: string }>;
  setStoredValue(options: { value: string }): Promise<void>;
  getStoredValue(): Promise<{ value: string }>;
}

iOS端AppDelegate代码

func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
    let voipToken = pushCredentials.token.map { String(format: "%02x", $0) }.joined()
    print("PushKit Token: \(voipToken)")
    
    // Store the token
    QuillCapacitorPlugin.shared.setStoredValue(voipToken)
}

Vue/JS端调用代码

// voipPlugin.js
import { QuillCapacitorPlugin } from 'quill-capacitor-plugin';

export const getStoredVoIPToken = async () => {
  try {
    const result = await QuillCapacitorPlugin.getStoredValue();
    console.log('token is', result);
    return result.token;
  } catch (error) {
    console.error('Error getting VoIP token:', error);
    return null;
  }
};

// Vue Plugin
export const VoIPPlugin = {
  install() {
    console.log('Setting up VoIP Plugin');
    
    // Add method to get token to globalProperties
    getStoredVoIPToken().then((token) => {
        console.log('token is 2', token)
    });
  }
};

问题排查与解决步骤

UNIMPLEMENTED错误在Capacitor中通常表示JS端调用的方法未在原生插件中正确注册,或插件配置存在问题,以下是针对性解决方案:

1. 配置Capacitor插件注册

在项目根目录的capacitor.config.ts中添加插件注册配置:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // 其他原有配置
  plugins: {
    QuillCapacitorPlugin: {}
  }
};

export default config;

2. 确认iOS端插件Info.plist注册

打开iOS项目的Info.plist,添加Capacitor插件条目:

<key>CapacitorPlugins</key>
<array>
  <string>QuillCapacitorPluginPlugin</string>
</array>

确保@objc(QuillCapacitorPluginPlugin)中的类名与Info.plist里的字符串完全一致。

3. 修正JS端返回值取值错误

原生getStoredValue方法返回的是{"value": token},JS端错误取了result.token,应改为result.value:

export const getStoredVoIPToken = async () => {
  try {
    const result = await QuillCapacitorPlugin.getStoredValue();
    console.log('token is', result);
    return result.value; // 修正此处取值
  } catch (error) {
    console.error('Error getting VoIP token:', error);
    return null;
  }
};

4. 重新同步并编译项目

执行以下命令同步Capacitor配置,然后重新编译:

npx cap sync ios
npx cap open ios

在Xcode中执行Cmd+Shift+K清理构建文件夹,再重新运行项目。

5. 验证插件基础功能

先调用echo方法测试插件是否正常工作,确认基础通信没问题:

const testEcho = async () => {
  const res = await QuillCapacitorPlugin.echo({ value: 'test' });
  console.log(res.value); // 应打印"test"
};
testEcho();

同时在原生getStoredValue方法中添加日志,确认是否被调用:

@objc func getStoredValue(_ call: CAPPluginCall) {
  print("getStoredValue called") // 添加日志
  if let value = implementation.getStoredValue() {
      call.resolve([
          "value": value
      ])
  } else {
      call.reject("No value stored")
  }
}

内容的提问来源于stack exchange,提问作者CruicalWind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:41:13