【问题标题】:Cordova plugin with framework with Appdelegate带有 Appdelegate 框架的 Cordova 插件
【发布时间】:2021-01-29 21:31:56
【问题描述】:

我创建了一个带有本机 sdk 的框架,我工作的公司用于推送通知。我在这个框架中有一个 Appdelegate,因为有一些文件使用它。我已将此框架添加为 Cordova 测试应用程序的插件,但正如我所见,我只能使用现在存在的两个 AppDelegate 之一(一个在框架中,一个在 cordova 应用程序中)。我试图只使用框架的 AppDelegate,但要做到这一点,我必须以某种方式使用 CDVAppDelegate。问题是初始化中的应用程序没有运行正确的didFinishLaunchingWithOptions 函数,我看不到cordova 应用程序的默认首页。我在插件里面有这个文件:

AppDelegateExtension.m

#import "xxxSDK/AppDelegate.h"
#import "xxxSDK/xxx.h"
#import "MainViewController.h"
#import "MyPlugin.h"

@implementation AppDelegate (MyPlugin)
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    #if (DEBUG == 1)
      [xxx launchWithAppUUID:@"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
    #else
      [xxx launchWithAppUUID:@"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
    #endif

    [[xxx sharedService].pushManager registerForRemoteNotifications];
    [[xxx sharedService].pushManager resetBadge];
    MyPlugin.myPlugin.viewController = [[MainViewController alloc] init];
    
    [MyPlugin.myPlugin application:application didFinishLaunchingWithOptions:launchOptions];
    return YES;
}

MyPlugin.h

#import <Cordova/CDVAppDelegate.h>

@interface MyPlugin : CDVAppDelegate
    // Public static method
    + (CDVAppDelegate*) myPlugin;
@end

MyPlugin.m:

#import <Foundation/Foundation.h>
#import "MyPlugin.h"
#import "MainViewController.h"

@implementation MyPlugin

// Private static reference
static CDVAppDelegate* myPlugin;

// Public static method
+ (CDVAppDelegate*) myPlugin {
    return myPlugin;
}
@end

在框架内,AppDelegate.h 是这样的:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@end

我也尝试将 MyPlugin 声明为 CDVPlugin,但问题没有得到解决。有什么想法吗?

【问题讨论】:

    标签: ios cordova cordova-plugins appdelegate ios-frameworks


    【解决方案1】:

    因为AppDelegateExtension.mAppDelegate 类的一个类别,它扩展了原始类而不是实现子类,因此您在类别中实现的任何方法都已存在于主类中(即AppDelegate.m 自动生成由 Cordova) 将被替换。

    所以在这种情况下,AppDelegateExtension.m 中的 didFinishLaunchingWithOptions 将替换 didFinishLaunchingWithOptions in AppDelegate.m

    TL;DR:你需要swizzle the method以避免破坏原来的方法:

    @implementation AppDelegate (MyPlugin)
    + (void)load {
        Method original = class_getInstanceMethod(self, @selector(application:didFinishLaunchingWithOptions:));
        Method swizzled = class_getInstanceMethod(self, @selector(application:swizzledDidFinishLaunchingWithOptions:));
        method_exchangeImplementations(original, swizzled);
    }
    
    - (BOOL)application:(UIApplication*)application swizzledDidFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    {
        #if (DEBUG == 1)
          [xxx launchWithAppUUID:@"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
        #else
          [xxx launchWithAppUUID:@"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
        #endif
    
        [[xxx sharedService].pushManager registerForRemoteNotifications];
        [[xxx sharedService].pushManager resetBadge];
        MyPlugin.myPlugin.viewController = [[MainViewController alloc] init];
        
        [MyPlugin.myPlugin application:application didFinishLaunchingWithOptions:launchOptions];
        return YES;
    }
    

    您可以在cordova-plugin-firebasex 中查看此示例。

    【讨论】:

    • 您好,谢谢您的回复!实际上我正在尝试在 [MyPlugin.myPlugin application:application didFinishLaunchingWithOptions:launchOptions]; 行访问 CDVAppdelegate 的函数
    【解决方案2】:

    好的,我这样做了:

    @implementation AppDelegate (MyPlugin)
    + (void)load {
        Method original = class_getInstanceMethod(self, @selector(application:didFinishLaunchingWithOptions:));
        Method swizzled = class_getInstanceMethod(self, @selector(application:swizzledDidFinishLaunchingWithOptions:));
        method_exchangeImplementations(original, swizzled);
    }
    
    - (BOOL)application:(UIApplication*)application swizzledDidFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    {
        #if (DEBUG == 1)
          [Warply launchWithAppUUID:@"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
        #else
          [Warply launchWithAppUUID:@"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
        #endif
    
        [[Warply sharedService].pushManager registerForRemoteNotifications];
        [[Warply sharedService].pushManager resetBadge];
        CDVAppDelegate *appDelegate = [[CDVAppDelegate alloc]init];
        [appDelegate application:application didFinishLaunchingWithOptions:launchOptions];
        return YES;
    }
    

    CDVAppdelegate 的 didFinishLaunchingWithOptions 正在运行,但在我的设备 index.html 视图中看不到。我的 sdk 运行正常,但 cordova 应用程序根本没有运行。 我认为问题是 AppDelegate : UIResponder 无法支持我想做的事情,我开始相信我想要的事情无法实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 2018-12-17
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多