Capacitor插件无法在iOS与Vue应用间通信问题求助
我需要实现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

