Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use application in iOS app: openURL:options: This AppSelegate method. This method is called when another application opens your application through a URL. #3640

Open
ydkgame opened this issue Jan 11, 2025 · 8 comments
Labels

Comments

@ydkgame
Copy link

ydkgame commented Jan 11, 2025

`// 处理 URL 的方法

  • (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    // 调用你的 URL 处理类 TDSHandleUrl
    return [TDSHandleUrl handleOpenURL:url];
    }

  • (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    // 调用你的 URL 处理类 TDSHandleUrl
    return [TDSHandleUrl handleOpenURL:url];
    }
    `
    ===========================================================
    The above method example must be used in this AppSelegate class, which is called when another application opens your application through a URL. How can I write these two methods so that they can be called, as there is currently no AppSelegate class in ANE? cry for help. Thank you.
    ===========================================================
    Here is the source code
    ===========================================================
    #import "AirNativeShare.h"
    #import "Constants.h"
    #import "CustomText.h"

// AntiAddictionUI
#import <AntiAddictionUI/AntiAddictionUI.h>

#import <TapBootstrapSDK/TapBootstrapSDK.h>
#import <TapMomentSDK/TapMomentSDK.h>

@interface AirNativeShare ()
@Property (nonatomic, readonly) FREContext context;

@EnD

@implementation AirNativeShare

@synthesize globalString;
@synthesize appID;
@synthesize videoID;

// 处理 URL 的方法

  • (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    // 调用你的 URL 处理类 TDSHandleUrl
    return [TDSHandleUrl handleOpenURL:url];
    }

  • (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    // 调用你的 URL 处理类 TDSHandleUrl
    return [TDSHandleUrl handleOpenURL:url];
    }

  • (instancetype)initWithContext:(FREContext)extensionContext {

    if ((self = [super init])) {

      _context = extensionContext;
    

    }

    return self;
    }

  • (void) sendLog:(NSString*)log {
    [self sendEvent:@"log" level:log];
    }

  • (void) sendEvent:(NSString*)code {
    [self sendEvent:code level:@""];
    }

  • (void) sendEvent:(NSString*)code level:(NSString*)level {
    FREDispatchStatusEventAsync(_context, (const uint8_t*)[code UTF8String], (const uint8_t*)[level UTF8String]);
    }

-(void)addAlertView{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
@"Title" message:@"This is a test alert 1" delegate:self
cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
[alertView show];
}

  • (void) addWin1:(NSString*)msg {
    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
    @"Title" message:msg delegate:self
    cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
    [alertView show];
    }

#pragma mark - 初始化

  • (void)initTapSDK {

    //初始化SDK
    TapConfig *config = TapConfig.new;
    config.clientId = @"t4nw2glhabdqvae";
    config.clientToken=@"E7SURWLgkQabcqOcWze1nhAZrfKOB02eIqt";
    config.region = TapSDKRegionTypeCN;
    config.serverURL = @"Server URL";
    [TapBootstrap initWithConfig:config];

    TapDBConfig * dbConfig = [[TapDBConfig alloc]init];

    dbConfig.enable = true;
    dbConfig.channel=@"";
    dbConfig.gameVersion=@"";
    dbConfig.advertiserIDCollectionEnabled=true;
    config.dbConfig = dbConfig;

    config.region = TapSDKRegionTypeCN;
    [TapBootstrap initWithConfig:config];

    //开启动态
    //[TapMoment setDelegate:self];

}

  • (void)addLogin {
    [TDSUser loginByTapTapWithPermissions:@[@"public_profile"] callback:^(TDSUser * _Nullable user, NSError * _Nullable error) {
    if (user) {
    // 开发者可以调用 user 的方法获取更多属性。
    NSString *userId = user.objectId; // 用户唯一标识
    NSString *username = user[@"nickname"]; // 昵称
    NSString *avatar = user[@"avatar"]; // 头像
    NSLog(@"userId: %@, username: %@, avatar: %@", userId, username, avatar);

          [self addWin1:username];
          
      } else {
          NSLog(@"%@", error);
      }
    

    }];
    }

  • (void)addInit {

    //[self addUIApplication1];

    [self addLogin];

    NSLog(@"1.addLogin =============");
    }

  • (void)addUser3 {

    TapConfig *config = [TapConfig new];
    config.clientId = @"t4nw2glhabdqvae"; // 必须,开发者中心对应 Client ID
    config.clientToken = @"E7SURWLgkQabcqOcWze1nhAZrfKOB02eIqtt"; // 必须,开发者中心对应 Client Token
    config.serverURL = @"https://your_server_url";
    config.tapAntiAddictionConfig = [[TapAntiAddictionConfig alloc] init];
    config.tapAntiAddictionConfig.showSwitchAccount = true;
    config.tapAntiAddictionConfig.useAgeRange = true;
    [TapBootstrap initWithConfig:config];
    //设置回调, callback 为开发者实现的自定义防沉迷回调对象
    [AntiAddiction setDelegate:self];

    NSString *baseUserIdentifier = @"玩家的唯一标识";
    // 生成一个随机数
    uint32_t randomNumber = arc4random() % 1000000; // 生成一个0到999999之间的随机数
    // 将随机数转换为字符串
    NSString *randomNumberString = [NSString stringWithFormat:@"%u", randomNumber];
    // 将随机数字符串附加到原始的用户标识上
    NSString *userIdentifierWithRandom = [NSString stringWithFormat:@"%@_%@", baseUserIdentifier, randomNumberString];
    // 使用更新后的用户标识启动防沉迷系统
    [AntiAddiction startupWithTapTap:userIdentifierWithRandom];
    NSLog(@"2.addUser=============");
    }

  • (void)addUser6 {

    AntiAddictionConfig *config = [[AntiAddictionConfig alloc] init];
    config.clientID = @"t4nw2glhabdqvae"; // TapTap 开发者中心对应 Client ID
    config.showSwitchAccount = YES;
    config.useAgeRange = YES; //是否使用年龄段信息
    //设置配置与回调, delegate 为开发者实现的自定义防沉迷回调对象
    [AntiAddiction initWithConfig:config];
    [AntiAddiction setDelegate:self];

    NSString *baseUserIdentifier = @"玩家的唯一标识";
    // 生成一个随机数
    uint32_t randomNumber = arc4random() % 1000000; // 生成一个0到999999之间的随机数
    // 将随机数转换为字符串
    NSString *randomNumberString = [NSString stringWithFormat:@"%u", randomNumber];
    // 将随机数字符串附加到原始的用户标识上
    NSString *userIdentifierWithRandom = [NSString stringWithFormat:@"%@_%@", baseUserIdentifier, randomNumberString];
    // 使用更新后的用户标识启动防沉迷系统
    [AntiAddiction startupWithTapTap:userIdentifierWithRandom];

    NSLog(@"2.addUser=============");
    }

//设置需要实现以下协议方法来接收回调的delegate 对象
// //[AntiAddiction exit];
// [self sendEvent:ad_init_finish level:ad_init_finish];

  • (void)antiAddictionCallbackWithCode:(AntiAddictionResultHandlerCode)code extra:(NSString * _Nullable)extra {

    if (code == 500) {
    [self addWin1:@" 1.Finish"];
    } else {

      NSString *firstName = @"John";
      NSString *lastName = @"Doe";
      
      // 注意:这里使用%ld是因为假设AntiAddictionResultHandlerCode是NSInteger或兼容类型。
      // 在实际应用中,更好的做法是使用一个字符串数组或字典来映射枚举值到可读的字符串。
      NSString *codeString = [NSString stringWithFormat:@"%ld", (long)code];
      
      // 但是,直接拼接codeString可能不是您想要的,因为这将输出一个数字。
      // 假设您有一个方法getResultStringFromCode:可以将code转换为可读字符串:
      // NSString *resultString = [self getResultStringFromCode:code];
      
      // 为了演示目的,我们暂时使用codeString,但请注意这不是一个好的做法。
      NSString *fullNameWithCode = [NSString stringWithFormat:@"%@ %@ - Code: %@", firstName, lastName, codeString];
      
      NSLog(@"%@", fullNameWithCode); // 输出类似于: John Doe - Code: 123(其中123是code的值)
      
      // 假设addWin1:方法应该接收一个包含用户全名和结果的字符串:
      [self addWin1:fullNameWithCode];
    

    }
    }

@EnD

AirNativeShare* GetAirNativeShareContextNativeData(FREContext context) {

CFTypeRef controller;
FREGetContextNativeData(context, (void**)&controller);
return (__bridge AirNativeShare*)controller;

}

DEFINE_ANE_FUNCTION(addVideoAD) {
AirNativeShare* controller = GetAirNativeShareContextNativeData(context);
if (!controller)
return AirNativeShare_FPANE_CreateError(@"context's AirNativeShare is null", 0);
@Try {

    [controller addGDTAdViewController];
    NSURL* url = nil;
    
}
@catch (NSException *exception) {
    [controller sendLog:[@"Exception occured while trying to share : " stringByAppendingString:exception.reason]];
}



return nil;

}

DEFINE_ANE_FUNCTION(init) {
AirNativeShare* controller = GetAirNativeShareContextNativeData(context);
if (!controller)
return AirNativeShare_FPANE_CreateError(@"context's AirNativeShare is null", 0);
@Try {

    // 设置全局变量的值
    controller.appID =               AirNativeShare_FPANE_FREObjectToNSString(argv[0]);
    controller.videoID =             AirNativeShare_FPANE_FREObjectToNSString(argv[1]);

    [controller onInit];
   // [controller addGDTAdViewController];
    
    //[controller sendEvent:ad_init_finish level:ad_init_finish];
    
    
    NSURL* url = nil;
    
}
@catch (NSException *exception) {
    [controller sendLog:[@"Exception occured while trying to share : " stringByAppendingString:exception.reason]];
}



return nil;

}

DEFINE_ANE_FUNCTION(data_manage) {
AirNativeShare* controller = GetAirNativeShareContextNativeData(context);
if (!controller)
return AirNativeShare_FPANE_CreateError(@"context's AirNativeShare is null", 0);
@Try {

    // 设置全局变量的值
    //controller.appID =               AirNativeShare_FPANE_FREObjectToNSString(argv[0]);
   // controller.videoID =             AirNativeShare_FPANE_FREObjectToNSString(argv[1]);
    NSInteger * id =AirNativeShare_FPANE_FREObjectToInt(argv[0]);
   
    if ( id== 3 ){
        //[controller addGDTAdViewController];
        [controller addUser3];
    }else if ( id== 4 ){
        [controller addAlertView];
    }else if ( id== 5 ){
        [controller addLogin];
    }else if ( id== 6 ){
        [controller addUser6];
    }
    
    NSURL* url = nil;
    
}
@catch (NSException *exception) {
    [controller sendLog:[@"Exception occured while trying to share : " stringByAppendingString:exception.reason]];
}



return nil;

}

#pragma mark - ANE setup

void AirNativeShareContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx,
uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet) {

AirNativeShare* controller = [[AirNativeShare alloc] initWithContext:ctx];
FRESetContextNativeData(ctx, (void*)CFBridgingRetain(controller));

static FRENamedFunction functions[] = {
    //MAP_FUNCTION(showShareDialog, NULL),
    //MAP_FUNCTION(showShareWithCustomTexts, NULL),
    MAP_FUNCTION(addVideoAD, NULL),
    MAP_FUNCTION(init, NULL),
    MAP_FUNCTION(data_manage, NULL),
};

*numFunctionsToTest = sizeof(functions) / sizeof(FRENamedFunction);
*functionsToSet = functions;

}

void AirNativeShareContextFinalizer(FREContext ctx) {
CFTypeRef controller;
FREGetContextNativeData(ctx, (void **)&controller);
CFBridgingRelease(controller);
}

void AirNativeShareInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet ) {
*extDataToSet = NULL;
*ctxInitializerToSet = &AirNativeShareContextInitializer;
*ctxFinalizerToSet = &AirNativeShareContextFinalizer;
}

void AirNativeShareFinalizer(void *extData) {}

`

@marchbold
Copy link
Collaborator

Have you looked into the InvokeEvent for this? It should get called when your application is launched from a url. Or do you have a particular need to implement this natively?

@ydkgame
Copy link
Author

ydkgame commented Jan 12, 2025

Have you looked into the InvokeEvent for this? It should get called when your application is launched from a url. Or do you have a particular need to implement this natively?

**myApp://open?param1=123
I can use this link to redirect to, and I hope to receive messages in ane.
I am not very familiar with Object C, and I don't know how I received the data transmitted in ane
**

<key>CFBundleURLSchemes</key> <array> <string>myApp</string> </array>

@marchbold
Copy link
Collaborator

If you only need the url information you should be able to get this through the AS3 InvokeEvent. You shouldn't need to write any objC for this.

import flash.desktop.NativeApplication;
import flash.desktop.InvokeEvent;

// Add an event listener for the INVOKE event
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);

function onInvoke(event:InvokeEvent):void {
    // Access the arguments array
    var args:Array = event.arguments;

    // Check if there are any arguments
    if (args.length > 0) {
        trace("Launch arguments:");
        for (var i:int = 0; i < args.length; i++) {
            trace("Argument " + i + ": " + args[i]);
        }
    } else {
        trace("No launch arguments were passed.");
    }
}

@ydkgame
Copy link
Author

ydkgame commented Jan 14, 2025

Thank you very much,
What I want to know is the functionality that can replace the following code in the native code ane
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { //Call your URL processing class TDSHHandleURL return [TDSHandleUrl handleOpenURL:url]; }

@marchbold
Copy link
Collaborator

The openURL method opens a url (which you can do with a normal url navigation in AIR).

If you are just looking for how to call this natively in objc then:

#import <UIKit/UIKit.h>

- (void)openURLExample {
    NSURL *url = [NSURL URLWithString:@"https://www.example.com"];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
    }
}

If you are looking for the iOS equivalent to receive this information you likely want to look into the willFinishLaunchingWithOptions on your application delegate. This one is quite tricky to implement in AIR so not something I'd suggest for a beginner.

@ydkgame
Copy link
Author

ydkgame commented Jan 14, 2025

Thank you, thank you. I didn't mean to open the URL because ANE doesn't have the AppSelegate. m class
At present, this method can only be executed when placed in the AppSelegate. m class. I hope to implement this feature in ANE's code. When the link jumps over, an event can be triggered

(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
//Call your URL processing class TDSHHandleURL
return [TDSHandleUrl handleOpenURL:url];
}

@marchbold
Copy link
Collaborator

Right, well if you are looking to override the app delegate I suggest you take a look at our Core integration:

https://github.com/distriqt/ANE-Core/tree/master/integration

This allows you to handle the app delegate methods without breaking any other extensions or the AIR SDK integrations.

@ydkgame
Copy link
Author

ydkgame commented Jan 14, 2025

Thank you, I'm taking another look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants