欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

「Unity3D」极简调用IOS Obj-C代码实现原生分享

程序员文章站 2022-03-31 07:58:54
如题,本文将会给出完整可运行的代码,以及注意事项。第一步,编写IOS端的分享代码。只有一个实现文件:SocialShare.mmextern "C"{ // 提供给Unity调用 void IOSSocialShare(const char* cText, const char* cUrl, const char* cTexData) { // 文字 NSString* textStr = [NSString stringWithUTF8...

如题,本文将会给出完整可运行的代码,以及注意事项。

第一步,编写IOS端的分享代码。

只有一个实现文件:SocialShare.mm

extern "C"
{
    // 提供给Unity调用
    void IOSSocialShare(const char* cText, const char* cUrl, const char* cTexData)
    {
        // 文字
        NSString* textStr    = [NSString stringWithUTF8String:cText];
        // 链接
        NSString* urlStr     = [NSString stringWithUTF8String:cUrl];
        // 图片数据
        NSString* texDataStr = [NSString stringWithUTF8String:cTexData];

        NSURL*    url        = [NSURL URLWithString:urlStr];
        NSData*   imageData  = [[NSData  alloc] initWithBase64EncodedString:texDataStr options:0];
        UIImage*  image      = [[UIImage alloc] initWithData:imageData];
        NSArray*  items;
        
        if (urlStr.length == 0)
        {
            // 没有链接,只有文字和图片
            items = @[textStr, image];
        }
        else
        {
            items = @[textStr, image, url];
        }
        
        // 获得分享视图
        UIActivityViewController* controller = [[UIActivityViewController alloc]
                                                 initWithActivityItems:items applicationActivities:nil];

        // 排除不需要的分享类型
        controller.excludedActivityTypes     =@
        [
            UIActivityTypeMail,
            UIActivityTypeMessage,
            UIActivityTypePrint,
            UIActivityTypeAssignToContact,
            UIActivityTypeAddToReadingList,
            UIActivityTypeAirDrop,
            UIActivityTypeOpenInIBooks,
            @"com.apple.reminders.RemindersEditorExtension",
            @"com.apple.mobilenotes.SharingExtension",
        ];

        // 获得Unity的视图
        UIViewController* unityController = UnityGetGLViewController();
        NSString*         version         = [UIDevice currentDevice].systemVersion;
        int               versionCode     = [[[version componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
        
        // 根据不同的系统版本,设置分享视图展现
        if (versionCode >= 8)
        {
            UIPopoverPresentationController* presentationController = [controller popoverPresentationController];
            presentationController.permittedArrowDirections         = UIPopoverArrowDirectionAny;
            presentationController.sourceView                       = unityController.view;
            presentationController.sourceRect                       = CGRectMake
            (
                unityController.view.bounds.origin.x + unityController.view.bounds.size.width / 2,
                unityController.view.bounds.origin.y + unityController.view.bounds.size.height,
                0, 0
            );
        }

        [unityController presentViewController:controller animated:YES completion:nil];

        // 分享回调
        controller.completionWithItemsHandler =^
        (
             UIActivityType _Nullable activityType,
             BOOL                     completed,
             NSArray*       _Nullable returnedItems,
             NSError*       _Nullable activityError
        )
        {
            if (completed)
            {
                // 第一个参数:是场景中GameObject的名称
                // 第二个参数:是GameObject上某个脚本的某个方法名称
                // 第三个参数:是回调方法的参数
                UnitySendMessage("Logic", "OnShareSuccess", "");
            }
            else
            {
                UnitySendMessage("Logic", "OnShareCancel", "");
            }
        };
    }
}

需要注意的是,这个IOS代码文件,不要直接放在Xcode的工程里,而是放在Unity的插件文件夹内,即Plugins/IOS下,然后Unity导出Xcode工程会带入这个文件(否则文件引用UnityFramework的函数会变编译报错),如下图:

「Unity3D」极简调用IOS Obj-C代码实现原生分享
「Unity3D」极简调用IOS Obj-C代码实现原生分享

第二步,编写Unity端的C#代码。

代码文件:IOSNativeShare.cs


using System;
using UnityEngine;
using MojoUnity;

#if UNITY_EDITOR_OSX || UNITY_IOS
using System.Runtime.InteropServices;
#endif

public class IOSNativeShare : Singleton<IOSNativeShare>
{
    // 分享app的图片
    public Texture2D appImage;

    public string    appId;
    public string    site;

    public string ShareUrl
    {
        get
        {
            return $"https://{this.site}{this.appId}";
        }
    }


    #if UNITY_EDITOR_OSX || UNITY_IOS
    [DllImport ("__Internal")]
    private static extern void IOSSocialShare(string text, string url, string texData);
    #endif
 
 
    public void ShareApp()
    {
        #if UNITY_EDITOR_OSX || UNITY_IOS
        IOSSocialShare("分享文字", this.ShareUrl, Convert.ToBase64String(this.appImage.EncodeToPNG()));
        #endif
    }


    public void OnShareSuccess(string result)
    {
        // 分享成功
    }


    public void OnShareCancel(string result)
    {
        // 分享取消
    }
}

以上CS文件挂载在一个GameObject上,按照第一步UnitySendMessage的写法,这个GameObject的name是应该是——“Logic”,

第三步,Unity调用IOS的分享代码。

#if UNITY_EDITOR_OSX || UNITY_IOS
IOSNativeShare.Instance.ShareApp();
#endif

本文地址:https://blog.csdn.net/tom_221x/article/details/110260436