推送通知的iOS原生扩展Adobe AIR的 [英] push notification iOS native extension for Adobe Air

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

问题描述

我工作的iOS原生扩展Adobe AIR的,将获得设备令牌推送通知。遗憾的是我没那么蒙克目标C程序员,我不知道是否有什么不对我用code。它编译没有问题,我可以使用与AIR扩展,但看起来像通知不返回既不正面也不负面影响登记。所以,我想要做的是注册时RegisterDevice函数被称为AIR通知和如果它不注册存储在deviceTokenString设备令牌,如果它不注册和错误回来我存储错误此字符串。当为gettoken函数被调用我回到deviceTokenString到空气,它要么令牌或错误。在AIR应用程序中我通过点击按钮启动第一RegisterDevice功能,后来为gettoken功能。不幸的是我没有得到既不令牌也没有错误(也弹出请求许可没有显示出来)。我也试图把注册参加didFinishLaunchingWithOptions但它看起来像didFinishLaunchingWithOptions永远不会启动。如果你们可以看看,如果code是好的,我会很感激。或者,也许你有任何想法,还有什么可以是错误的?我在配置门​​户网站启用推送SSL证书。这里的code我用

NativePush.m

#进口的UIKit / UIKit.h
#进口包括/ FlashRuntimeExtensions.h@implementation NativePush@synthesize tokenString = _tokenString;* NSString的deviceTokenString = @; - (ID)的init
{
    自= [超级初始化]
    如果(个体经营){
        //初始化code在这里。
    }    返回自我;
} - (BOOL)应用:(*的UIApplication)的应用didFinishLaunchingWithOptions:(NSDictionary的*)launchOptions {
    返回YES;
} - (无效)应用:(*的UIApplication)应用didRegisterForRemoteNotificationsWithDeviceToken:(NSData的*)deviceToken
{
    * NSString的海峡=
    [的NSString stringWithFormat:@%@,deviceToken]
    deviceTokenString =海峡;
} - (无效)应用:(*的UIApplication)应用didFailToRegisterForRemoteNotificationsWithError:(NSError *)错误
{
    * NSString的海峡= [的NSString stringWithFormat:@错误:%@,犯错]
    deviceTokenString =海峡;
}无效ContextInitializer(void *的扩展数据,常量uint8_t有* ctxType,FRE​​Context CTX,
                        uint32_t的* numFunctionsToTest,常量FRENamedFunction ** functionsToSet){
    * numFunctionsToTest = 2;
    FRENamedFunction * FUNC =(FRENamedFunction *)malloc的(的sizeof(FRENamedFunction)* 2);
    FUNC [0] =。名称(常量uint8_t有*)RegisterDevice
    FUNC [0] .functionData = NULL;
    FUNC [0]。功能=安培; RegisterDevice;    FUNC [1]。名称=(常量uint8_t有*)为gettoken
    FUNC [1] .functionData = NULL;
    FUNC [1]。功能=安培;为gettoken;    * functionsToSet = FUNC;
}无效ContextFinalizer(FREContext CTX){
    返回;
}无效ExtInitializer(无效** extDataToSet,FREContextInitializer * ctxInitializerToSet,
                    FREContextFinalizer * ctxFinalizerToSet){
    * extDataToSet = NULL;
    * ctxInitializerToSet =安培; ContextInitializer;
    * ctxFinalizerToSet =安培; ContextFinalizer;
}无效ExtFinalizer(void *的扩展数据){
    返回;
}FREObject RegisterDevice(FREContext CTX,无效* funcData,uint32_t的ARGC,ARGV FREObject []){    [UIApplication的sharedApplication]
     registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeAlert |
      UIRemoteNotificationTypeBadge |
      UIRemoteNotificationTypeSound)];    返回NULL;
}FREObject为gettoken(FREContext CTX,无效* funcData,uint32_t的ARGC,ARGV FREObject []){    * NSString的代币= deviceTokenString;    字符* tokenChar = UTF8字符串令牌];
    FREObject tokenObject = NULL;    FRENewObjectFromUTF8(strlen的(tokenChar)+1,(常量uint8_t有*)tokenChar,&安培; tokenObject);    返回tokenObject;}@结束

和头文件NativePush.h

导入基金会/ Foundation.h
进口包括/ FlashRuntimeExtensions.h@interface NativePush:NSObject的
@属性(非原子,保留)的NSString * tokenString;FREObject RegisterDevice(
                        FREContext CTX,
                        无效* funcData,
                        uint32_t的ARGC,
                        FREObject ARG []
                        );
FREObject为gettoken(
                        FREContext CTX,
                        无效* funcData,
                        uint32_t的ARGC,
                        FREObject ARG []
                        );
无效ContextInitializer(
                        void *的扩展数据,
                        常量uint8_t有* ctxType,
                        FREContext CTX,
                        uint32_t的* numFunctionsToTest,
                        常量FRENamedFunction ** functionsToSet
                        );
无效ContextFinalizer(FREContext CTX);
无效ExtInitializer(
                    无效** extDataToSet,
                    FREContextInitializer * ctxInitializerToSet,
                    FREContextFinalizer * ctxFinalizerToSet
                    );
无效ExtFinalizer(void *的扩展数据);
@结束


解决方案

好吧,

撕裂我的头发了3天之后,我想通了。我不设置委托,因为这将打破所有Adobe的东西。我创建现有委托的一个自定义子类,并覆盖有APNS做委托功能。我的code如下。

  //空的委托功能,存根签名是这样,我们可以找到在委托该方法
//并与我们的自定义实现覆盖它
- (无效)应用:(*的UIApplication)的应用didRegisterForRemoteNotificationsWithDeviceToken:(NSData的*)deviceToken {}     - (无效)应用:(*的UIApplication)的应用didFailToRegisterForRemoteNotificationsWithError:(NSError *)错误{}
   //上述空签名定制实现
无效didRegisterForRemoteNotificationsWithDeviceToken(ID自我,SEL _cmd,UIApplication的*应用的NSData * deviceToken)
{
的NSLog(@我的令牌:%@,deviceToken);
}
 无效didFailToRegisterForRemoteNotificationsWithError(ID自我,SEL _cmd,UIApplication的*应用程序,NSError *误差)
{
的NSLog(@未能获得令牌,错误:%@,错误);
}// ContextInitializer()
//
//当运行时创建扩展上下文实例的上下文的初始化被调用。
无效PushContextInitializer(void *的扩展数据,常量uint8_t有* ctxType,FRE​​Context CTX,
                    uint32_t的* numFunctionsToTest,常量FRENamedFunction ** functionsToSet)
{//我们注入修饰委托功能到sharedApplication委托ID代表= [[UIApplication的sharedApplication]代表];类对象类= object_getClass(代表);* NSString的newClassName = [的NSString stringWithFormat:@自定义_%@,NSStringFromClass(对象类)];
类modDelegate = NSClassFromString(newClassName);
如果(modDelegate ==无){
    //这个类不存在;创建
    //分配一个新的类
    modDelegate = objc_allocateClassPair(objectClass的,[newClassName UTF8字符串],0);    SEL selectorToOverride1 = @selector(应用程序:didRegisterForRemoteNotificationsWithDeviceToken :);    SEL selectorToOverride2 = @selector(应用程序:didFailToRegisterForRemoteNotificationsWithError :);    //获得我们要覆盖的方法的信息
    方法M1 = class_getInstanceMethod([jreporterNativePush类],selectorToOverride1);
    方法M2 = class_getInstanceMethod([jreporterNativePush类],selectorToOverride2);    //方法添加到新类
    class_addMethod(modDelegate,selectorToOverride1,(IMP)didRegisterForRemoteNotificationsWithDeviceToken,method_getTypeEncoding(M1));    class_addMethod(modDelegate,selectorToOverride2,(IMP)didFailToRegisterForRemoteNotificationsWithError,method_getTypeEncoding(M2));    //与运行时注册新的类
    objc_registerClassPair(modDelegate);
}
//改变对象的类别
object_setClass(委托modDelegate);
的NSLog(@疯狂完成交换W / O轰炸w00t);/////////委托注射结束/修改code* numFunctionsToTest = 1;FRENamedFunction * FUNC =(FRENamedFunction *)malloc的(的sizeof(FRENamedFunction)* 1);FUNC [0] =。名称(常量uint8_t有*)registerPush
FUNC [0] .functionData = NULL;
FUNC [0]。功能=安培; registerPush;* functionsToSet = FUNC;

}

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":

#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

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

解决方案

Ok,

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;

}

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

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