适用于 Adob​​e Air 的推送通知 iOS 原生扩展 [英] push notification iOS native extension for Adobe Air

查看:27
本文介绍了适用于 Adob​​e Air 的推送通知 iOS 原生扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发适用于 Adob​​e AIR 的 iOS 本机扩展,该扩展将获取推送通知的设备令牌.不幸的是,我不是那种笨手笨脚的 Objective-C 程序员,我不确定我使用的代码是否有问题.它编译没有问题,我可以将扩展与 AIR 一起使用,但看起来注册通知既不会产生正面影响也不会产生负面影响.所以我想要做的是在从 AIR 调用 RegisterDevice 函数时注册通知,如果它注册将设备令牌存储在 deviceTokenString 中,如果它没有注册并返回错误,我将错误存储在这个字符串中.当调用 GetToken 函数时,我将 deviceTokenString 返回给 AIR,因此它是令牌或错误.在 AIR 应用程序中,我通过单击按钮启动第一个 RegisterDevice 函数,然后启动 GetToken 函数.不幸的是,我既没有收到令牌也没有收到错误(也没有出现请求许可的弹出窗口).我也试图将注册部分放在 didFinishLaunchingWithOptions 中,但看起来 didFinishLaunchingWithOptions 从未启动过.如果你们可以看看代码是否正常,我将非常感激.或者,也许您有任何想法,还有什么可能是错误的?我在配置门户中启用了推送 SSL 证书.这是我正在使用的代码

I'm working on iOS native extension for Adobe AIR that will get device token for push notifications. Unfortunately I'm not that munch objective-C programmer and I'm not sure if there's something wrong in the code I'm using. It compiles with no problem, I can use the extension with AIR but looks like registering for notifications doesn't return neither positive nor negative effect. So what I'm trying to do is register for notifications when RegisterDevice function is called from AIR and if it does register store the device token in deviceTokenString and if it doesn't register and comes back with the error I store the error in this string. When GetToken function is called I return deviceTokenString to AIR so it's either token or error. In AIR application I launch first RegisterDevice function and later GetToken function by clicking buttons. Unfortunately I don't get neither token nor error (also popup asking for permission doesn't show up). I was also trying to put registering part in didFinishLaunchingWithOptions but it looks like didFinishLaunchingWithOptions is never launched. If you guys can have a look if the code is OK I would be really grateful. Or maybe you have any ideas what else can be wrong? I have push SSL certificate enabled in provisioning portal. Here's the code I'm using

NativePush.m":

"NativePush.m":

#import "UIKit/UIKit.h"
#import "include/FlashRuntimeExtensions.h"

@implementation NativePush

@synthesize tokenString = _tokenString;

NSString *deviceTokenString = @"";

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {       
    return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
{ 
    NSString *str = 
    [NSString stringWithFormat:@"%@",deviceToken];
    deviceTokenString = str;
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err 
{ 
    NSString *str = [NSString stringWithFormat: @"Error: %@", err];   
    deviceTokenString = str;
}

void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx,
                        uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet) {
    *numFunctionsToTest = 2;
    FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*2);
    func[0].name = (const uint8_t*)"RegisterDevice";
    func[0].functionData = NULL;
    func[0].function = &RegisterDevice;

    func[1].name = (const uint8_t*)"GetToken";
    func[1].functionData = NULL;
    func[1].function = &GetToken;

    *functionsToSet = func;
}

void ContextFinalizer(FREContext ctx) {
    return;
}

void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet,
                    FREContextFinalizer* ctxFinalizerToSet) {
    *extDataToSet = NULL;
    *ctxInitializerToSet = &ContextInitializer;
    *ctxFinalizerToSet = &ContextFinalizer;
}

void ExtFinalizer(void* extData) {
    return;
}

FREObject RegisterDevice(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {

    [[UIApplication sharedApplication] 
     registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeAlert | 
      UIRemoteNotificationTypeBadge | 
      UIRemoteNotificationTypeSound)];

    return NULL;
}

FREObject GetToken(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {

    NSString* tokenS =  deviceTokenString;

    char* tokenChar = [tokenS UTF8String];
    FREObject tokenObject = NULL;

    FRENewObjectFromUTF8( strlen(tokenChar)+1 , (const uint8_t*)tokenChar, &tokenObject);

    return tokenObject;

}

@end

和头文件NativePush.h":

and header file "NativePush.h":

import "Foundation/Foundation.h"
import "include/FlashRuntimeExtensions.h"

@interface NativePush : NSObject
@property (nonatomic, retain) NSString* tokenString;

FREObject RegisterDevice(
                        FREContext ctx,
                        void* funcData,
                        uint32_t argc,
                        FREObject arg[]
                        );
FREObject GetToken(
                        FREContext ctx,
                        void* funcData,
                        uint32_t argc,
                        FREObject arg[]
                        );
void ContextInitializer(
                        void* extData,
                        const uint8_t* ctxType,
                        FREContext ctx,
                        uint32_t* numFunctionsToTest,
                        const FRENamedFunction** functionsToSet
                        );
void ContextFinalizer(FREContext ctx);
void ExtInitializer(
                    void** extDataToSet,
                    FREContextInitializer* ctxInitializerToSet,
                    FREContextFinalizer* ctxFinalizerToSet
                    );
void ExtFinalizer(void* extData);
@end

推荐答案

好的,

在把我的头发撕了 3 天后,我想通了.我不设置委托,因为这会破坏 Adob​​e 的所有内容.我创建现有委托的自定义子类并覆盖与 APNS 相关的委托函数.我的代码如下.

After tearing my hair out for 3 days I figured it out. I dont set the delegate, because that will break all Adobe's stuff. I create a custom subclass of the existing delegate and override the delegate functions that have to do with APNS. My code is below.

//empty delegate functions, stubbed signature is so we can find this method in the delegate
//and override it with our custom implementation
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{}

    - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error{}


   //custom implementations of empty signatures above
void didRegisterForRemoteNotificationsWithDeviceToken(id self, SEL _cmd, UIApplication* application, NSData* deviceToken)
{
NSLog(@"My token is: %@", deviceToken);
}


 void didFailToRegisterForRemoteNotificationsWithError(id self, SEL _cmd, UIApplication* application, NSError* error)
{
NSLog(@"Failed to get token, error: %@", error);
}





// ContextInitializer()
//
// The context initializer is called when the runtime creates the extension context instance.
void PushContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, 
                    uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet) 
{

//injects our modified delegate functions into the sharedApplication delegate

id delegate = [[UIApplication sharedApplication] delegate];

Class objectClass = object_getClass(delegate);

NSString *newClassName = [NSString stringWithFormat:@"Custom_%@", NSStringFromClass(objectClass)];
Class modDelegate = NSClassFromString(newClassName);
if (modDelegate == nil) {
    // this class doesn't exist; create it
    // allocate a new class
    modDelegate = objc_allocateClassPair(objectClass, [newClassName UTF8String], 0);

    SEL selectorToOverride1 = @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:);

    SEL selectorToOverride2 = @selector(application:didFailToRegisterForRemoteNotificationsWithError:);

    // get the info on the method we're going to override
    Method m1 = class_getInstanceMethod([jreporterNativePush class], selectorToOverride1);
    Method m2 = class_getInstanceMethod([jreporterNativePush class], selectorToOverride2);

    // add the method to the new class
    class_addMethod(modDelegate, selectorToOverride1, (IMP)didRegisterForRemoteNotificationsWithDeviceToken, method_getTypeEncoding(m1));

    class_addMethod(modDelegate, selectorToOverride2, (IMP)didFailToRegisterForRemoteNotificationsWithError, method_getTypeEncoding(m2));

    // register the new class with the runtime
    objc_registerClassPair(modDelegate);
}
// change the class of the object
object_setClass(delegate, modDelegate);


NSLog(@"completed crazy swap w/o bombing  w00t");

///////// end of delegate injection / modification code



*numFunctionsToTest = 1;

FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * 1);

func[0].name = (const uint8_t*) "registerPush";
func[0].functionData = NULL;
func[0].function = &registerPush;

*functionsToSet = func;

}

这篇关于适用于 Adob​​e Air 的推送通知 iOS 原生扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆