IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【Unity】Unity项目接入微信SDK分享功能总结(IOS端) -> 正文阅读

[移动开发]【Unity】Unity项目接入微信SDK分享功能总结(IOS端)


前言

第一次在 IOS 上接入 Unity 项目的SDK

在此记录系统性的总结一下自己接入过程,避免以后踩同样的坑


开发环境

  • Xcode 12.5
  • Unity 2018.4.10f

开发语言

  • C#
  • OC (因为 C# 与 OC 交互起来比较方便)

一、IOS 与 Unity 的交互

1. 接入前须知

在 Unity 项目中的 Plugins->IOS 中编写的代码
在这里插入图片描述
会在打包的时候一同带入 Xcode 项目中的 Libraries->Plugins->IOS 文件夹下

在这里插入图片描述
下文所有要编写的代码都要编写在其中

2. Unity 调用 IOS 中的方法

C# 无法直接调用 OC 或者 Swift 当中的方法

但是可以利用C#的特性来访问C语言所定义的接口

然后再通过C接口再调用ObjC的代码(对于Swift代码则还需要使用OC桥接)

a. 在 Plugins->IOS 编写 Test.mm 文件

该方法的作用是将传入的 message 在 Xcode 的调试中输出

extern "C"{
    void IOSLog(const char *message);
}
// 调试log
void IOSLog(const char *message){
    NSString* str = [[NSString alloc]initWithUTF8String:message];
    NSLog(@"%@", str);
}

b. 在 Unity 的脚本中引入声明

#if UNITY_IOS
    [DllImport("__Internal")]
    static extern void IOSLog(string message);
#endif

声明为静态变量方便调用

注:如果找不到该方法,可能导致编译失败

c. 在 Unity 中调用

IOSLog("Hello world!");

3. IOS 调用 Unity 中的方法

IOS 调用 Unity 的方法和 Android 一致

使用 UnitySendMessage 方法

UnitySendMessage(String var0, String var1, String var2)

具体可以查看 Android 调用 Unity 方法


二、UnityAppController

Unity 打出来的包中会包含一个 UnityAppController.mm 文件

这个文件与 Android 中的 UnityPlayerActivity.java 类似

是程序的入口,许多重要的生命周期函数都在这里实现

由于每次打包的时候都会重新生成该文件

所以我们需要自己写一个 MyUnityAppController.mm 并继承它

#import "UnityAppController.h"
#import "AgentLogic.h"

@interface MyUnityAppController : UnityAppController
@end

IMPL_APP_CONTROLLER_SUBCLASS (MyUnityAppController)

@implementation MyUnityAppController
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    [super application:application didFinishLaunchingWithOptions:launchOptions];
    NSLog(@"MyUnityAppController"); /* 可以实现自己的方法 */
    return YES;
}
@end

注:MyUnityAppController.mm 可以放在上文提到的 IOS 文件夹下


三、微信 SDK 接入

最重要的还是要按照 微信开放平台 上的文档进行操作

1. 配置 Universal Links (通用链接)

什么是 Universal Links ?

Universal Link 是 Apple 在 iOS 9 推出的一种能够方便的通过传统 HTTPS 链接来启动 APP的功能。如果你的应用支持 Universal Link,当用户点击一个链接时可以跳转到你的网站并获得无缝重定向到对应的 APP,且不需要通过Safari 浏览器。如果你的应用不支持的话,则会在 Safari 中打开该链接。

如何支持 Universal Links

一个支持 HTTPS 的域名,并且拥有该域名下上传到根目录的权限(为了上传Apple指定文件)

a. 在苹果开发者中心配置 Associated Domains

在这里插入图片描述
b. 根据微信文档创建配置文件 apple-app-site-association

创建一个内容为json格式的文件

当用户安装你的应用的时候,同时会下载该文件

这个文件名必须为apple-app-site-association,切记没有后缀名

文件在通过 QQ 等文件传输之后可能会自己加上后缀名,要留意

{
    "applinks": {
        "apps": [],
        "details": [
            {
				"appID": "8P7343TG54.com.tencent.xin.SDKSample",    
				"paths": ["/sdksample/*"]
            }
        ]
    }
}

c. 上传文件

配置好文件后,就可以将文件上传到域名所对应的 根目录 或者 .well-known 目录下

并试着是否能访问到该文件

d. 在微信开放平台里配置 Universal Links

根据你在 apple-app-site-association 中的配置

在微信上应该注册为 https://xxx.xxx.xxx/sdksample/

e. 在项目中配置域名

在项目的 Signing & Capabilities 的 Associated Domains 中添加你的域名

如果没有该选项可以添加

在这里插入图片描述

2. 搭建开发环境

这里还是要提一下,一定要严格按照官方文档来!

a. 将 SDK 中包含的文件加入到项目当中

推荐一同放入 IOS 文件夹中

分别是 WXApi.h、WXApiObject.h、libWeChatSDK.a

在这里插入图片描述

b. 添加相应的库

Security.framework, CoreGraphics.framework, WebKit.framework

c. 配置 Build Setting

在工程文件中选择 Build Setting

在"Other Linker Flags"中加入"-ObjC -all_load"

在 Search Paths 中添加 libWeChatSDK.a ,WXApi.h,WXApiObject.h

在这里插入图片描述

d. 添加 URL scheme

选择工程设置项,选中 TARGETS 一栏

在 info 标签栏的 URL type 添加 URL scheme 为你所注册的应用程序 id

在这里插入图片描述

e. 添加 LSApplicationQueriesSchemes

选择工程设置项,选中 TARGETS 一栏

在 info 标签栏的 LSApplicationQueriesSchemes 添加 “weixin” 和 “weixinULAPI”

在这里插入图片描述

3. 在代码中使用

以微信为例子,后续接入多个 SDK 的时候都可以按照这个方法来

根据官方文档,在 UnityAppController 的各个生命周期里调用相应的函数

这里要注意重写 AppDelegate 或 SceneDelegate 的 continueUserActivity 方法

注意:适配了SceneDelegate的App,系统将会回调SceneDelegate的continueUserActivity方法,所以需要重写SceneDelegate的该方法。

这里建议将微信需要调用的方法都封装到一起

4. 封装微信 api

编写 AgentLoic.h 继承 WXApiDelegate 接口

可以将要实现的方法都写在里面

#import "WXApi.h"

@interface AgentLogicInterface : NSObject<WXApiDelegate>
@end

class AgentLogic
{
public:
    AgentLogic();
    virtual ~AgentLogic();
    
    static AgentLogic* getInstance();
    
    void didFinishLaunchingWithOptions(UIApplication *app, NSDictionary *launchOptions);
    
    bool continueUserActivity(UIApplication *app, NSUserActivity *userActivity);
    bool handleOpenURL(UIApplication* app, NSURL* url);
    bool openURL(UIApplication* app, NSURL* url, NSString* sourceApplication, id annotation);
public:
    void onWXReq(BaseReq* req);
    void onWXResp(BaseResp* resp);
    void WXShareImage(char *bytes, int type, int length);
private:
    AgentLogicInterface* m_pInterface;
};

并在 AgentLogic.mm 实现对应方法

#import "AgentLogic.h"

extern "C"{
    void WeChatShareImage(char *bytes, int type, int length);
    void IOSLog(const char *message);
}

#pragma mark SDK
AgentLogic* g_pAgentLogic = NULL;

AgentLogic* AgentLogic::getInstance(){
    if (g_pAgentLogic == NULL){
        g_pAgentLogic = new AgentLogic();
    }
    return g_pAgentLogic;
}

AgentLogic::AgentLogic()
{
    m_pInterface = [AgentLogicInterface new];
}

AgentLogic::~AgentLogic()
{
    
}

void AgentLogic::didFinishLaunchingWithOptions(UIApplication *app, NSDictionary *launchOptions){
    //向微信注册
    [WXApi registerApp:@"123456789"    universalLink:@"https://xxx.xxx.xxx/sdksample/"];
}

bool AgentLogic::continueUserActivity(UIApplication *app, NSUserActivity *userActivity){
    return [WXApi handleOpenUniversalLink:userActivity delegate:m_pInterface];
}

bool AgentLogic::handleOpenURL(UIApplication* app, NSURL* url)
{
    return [WXApi handleOpenURL:url delegate:m_pInterface];
}

bool AgentLogic::openURL(UIApplication* app, NSURL* url, NSString* sourceApplication, id annotation)
{
    return [WXApi handleOpenURL:url delegate:m_pInterface];
}

#pragma mark 微信
void AgentLogic::onWXResp(BaseResp *resp)
{
    if([resp isKindOfClass:[SendMessageToWXResp class]])
    {
        SendMessageToWXResp *sendResp = (SendMessageToWXResp *)resp;
        std::string strParam = "";
        if(sendResp.errCode == 0)
        {
            NSLog(@"#####分享成功");
        }
        else
        {
            NSLog(@"#####分享失败");
        }
    }
}

void AgentLogic::onWXReq(BaseReq *req)
{
    NSLog(@"#####onWXReq");
}

// 微信分享图片
void WeChatShareImage(char *bytes, int type, int length){
    // 创建发送对象实例
    SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
    req.bText = NO; // 不使用文本信息
    req.scene = type; // 0 = 好友回话 1 = 朋友圈

    // 处理二进制数据
    NSData *imageData = [NSData dataWithBytes:bytes length:length];
    UIImage *image = [UIImage imageWithData:imageData];
    
    // 压缩图片分辨率(因为data压缩到一定程度后,如果图片分辨率不缩小的话还是不行)
    CGSize newSize = CGSizeMake(128, 128);
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* thumbImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // 创建分享内容图片
    WXImageObject *imageObject = [WXImageObject object];
    imageObject.imageData = imageData;
    
    // 创建消息
    WXMediaMessage *message = [WXMediaMessage message];
    message.thumbData = UIImageJPEGRepresentation(thumbImage, 0.5);
    message.mediaObject = imageObject;
    req.message = message;
    
    [WXApi sendReq:req completion:nil];
}

// 调试log
void IOSLog(const char *message){
	......
}

实现 WXApiDelegate 接口,调用相应的方法

@implementation AgentLogicInterface
#pragma mark 微信接口
-(void)onResp:(BaseResp *)resp
{
    AgentLogic::getInstance()->onWXResp(resp);
}

-(void)onReq:(BaseReq *)req
{
    AgentLogic::getInstance()->onWXReq(req);
}
@end

最后在 MyUnityAppController.mm 中调用

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    [super application:application didFinishLaunchingWithOptions:launchOptions];
    AgentLogic::getInstance()->didFinishLaunchingWithOptions(application, launchOptions);
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    [super application:application handleOpenURL:url];
    return AgentLogic::getInstance()->handleOpenURL(application, url);
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    [super application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
    return AgentLogic::getInstance()->openURL(application, url, sourceApplication, annotation);
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler {
    return AgentLogic::getInstance()->continueUserActivity(application, userActivity);
}

注:在 continueUserActivity 方法中,不需要调用父类的方法,否则会导致运行报错。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 11:02:31  更:2021-07-14 11:02:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/23 14:27:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码