读一读

发现有一种情况,就是原生的分享,选中Facebook分享时,有些ios系统版本加上第三方的输入法后会有问题。所以采用狸猫换太子的方式,自定义一个Facebook的activity,隐藏原来的activity。


使用方法,这里只贴一个分享图片的,分享文本的同理。在excludedActivityTypes里传入内容UIActivityTypePostFToFacebook隐藏点原来的Facebook选项,然后在applicationActivities传入自定义Activity的实例

+(void) NativeShareImage:(NSString *)imagePath excludedActivityTypes:(NSArray *)excludedActivityTypes
{
    NSLog(@"NativeTelegramShareImage local image path: %@", imagePath);
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    NSArray *activityItems = @[image];
    
    //excludedActivityTypes 传入UIActivityTypePostToFacebook 隐藏原来的Activity
    NSArray *activities = @[[CustomFacebookActivity new]];//自定义的facebook Activity
    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:activities];
    if(excludedActivityTypes != nil)
    {
        activityVC.excludedActivityTypes = excludedActivityTypes;
    }
    activityVC.completionWithItemsHandler = ^(NSString *activityType,BOOL completed,NSArray *returnedItems,NSError *activityError)
    {
        NSLog(@"%@", activityType);

        if (completed) { // 确定分享
            NSLog(@"分享成功");
        }
        else {
            NSLog(@"分享失败");
        }
    };

    UIViewController *vc =  UnityGetGLViewController();
    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) // iPad
     {
        UIPopoverPresentationController *presentationController = [activityVC popoverPresentationController];
        presentationController.sourceView = vc.view;
        presentationController.sourceRect = CGRectMake(vc.view.bounds.origin.x+vc.view.bounds.size.width/2,
                                                                vc.view.bounds.origin.y+vc.view.bounds.size.height,
                                                                0, 0);
        presentationController.permittedArrowDirections = 0;
     }

    [vc presentViewController:activityVC animated:YES completion:nil];
}


自定义的CustomFacebookActivity

//CustomFacebookActivity.h
NS_ASSUME_NONNULL_BEGIN
@interface CustomFacebookActivity : UIActivity

@end
NS_ASSUME_NONNULL_END
//CustomFacebookActivity.m
#import "CustomFacebookActivity.h"

#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <FBSDKShareKit/FBSDKShareKit.h>
#import <FBSDKGamingServicesKit/FBSDKGamingServicesKit.h>
#import <Foundation/NSJSONSerialization.h>

#include "FBUnitySDKDelegate.h"
#include "FBUnityUtility.h"
#include "FBSDK+Internal.h"

@interface CustomFacebookActivity ()
@property (nonatomic, strong) NSURL *dataURL; // 分享数据
@property (nonatomic, strong) UIImage *dataImg; // 分享数据
@property (nonatomic, strong) NSString *dataStr; // 分享数据
@end

@implementation CustomFacebookActivity

// 用来判断是什么Activity类型 自己定
- (NSString *)activityType{
    return @"com.report.activity.customfacebook";
}

// 决定在UIActivityViewController中显示的位置,最上面是AirDrop,中间是Share,下面是Action
+ (UIActivityCategory)activityCategory{
    return UIActivityCategoryShare;
}

// 显示的Title
- (NSString *)activityTitle{
    return @"Facebook";
}

// 显示的图标  需要在打包成xcode的时候 赋值引入过去
- (UIImage *)activityImage{
    /*
    For iPhone and iPod touch, images on iOS 7 should be 60 by 60 points; on earlier versions of iOS, you should use images no larger than 43 by 43 points. For iPad, images on iOS 7 should be 76 by 76 points; on earlier versions of iOS you should use images no larger than 60 by 60 points. On a device with Retina display, the number of pixels is doubled in each direction.
     */
     if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
     {
         return [UIImage imageNamed:@"facebook_76x76"];
    }else{
        return [UIImage imageNamed:@"facebook_60x60"];
    }
}

//设置 开关的时候显示的小图标
- (UIImage *)_activitySettingsImage {
    return [UIImage imageNamed:@"facebook_29x29"];
}

#pragma mark   -  数据处理
// 根据item的不同类型判断是否显示
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems{
    if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", @"fb://"]]])
    {
        return NO;  //未安装APP
    }

    BOOL support = NO;
    for (int i = 0; i < activityItems.count; i++) {
        if ([activityItems[i] isKindOfClass:NSString.class]) { //图片或文本
            //support = YES;  不支持文本
        }
        if ([activityItems[i] isKindOfClass:NSURL.class]) {
            support = YES;
        }
        if ([activityItems[i] isKindOfClass:UIImage.class]) {
            support = YES;
        }
        // 有一个支持就取消遍历
        if (support) break;
    }
    return support;
}


- (void)prepareWithActivityItems:(NSArray *)activityItems{

    // 点击动作即将执行的准备阶段, 可以用来处理一下值或者逻辑, items就是要传输的数据
    for (id obj in activityItems) {

        if([obj isKindOfClass:NSString.class]){
            self.dataStr = obj;
            break; // 只支持分享一张, 这里直接跳出循环
        }
        else if([obj isKindOfClass:NSURL.class])
        {
            self.dataURL = obj;
            break; // 只支持分享一张, 这里直接跳出循环
        }
        else if([obj isKindOfClass:UIImage.class])
        {
            self.dataImg = obj;
            break; // 只支持分享一张, 这里直接跳出循环
        }
    }
}


#pragma mark   -  事件处理  采用的是facebook的sdk分享
// 点击UIActivity的动作消息,处理点击后的相应逻辑, 没有自定义的UIViewController才会调用此方法, 需要在最后消除掉UIActivityviewController
- (void)performActivity{
    if(self.dataImg != nil)
    {
        NSLog(@"分享图片");
        FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
        photo.image = self.dataImg;
        photo.userGenerated = YES;

        FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init];
        content.photos = @[photo];

        UIViewController *rootViewController = UnityGetGLViewController();

        FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] init];
        dialog.fromViewController = rootViewController;
        dialog.shareContent = content;
        dialog.mode = FBSDKShareDialogModeNative;
        
        FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:999];
        dialog.delegate = delegate;

        if (![dialog show]) {
            NSLog(@"分享图片失败");
        }
    }
    else if(self.dataURL != nil)
    {
        NSLog(@"分享链接");
        FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
        content.contentURL = self.dataURL;

        UIViewController *rootViewController = UnityGetGLViewController();

        FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] init];
        dialog.fromViewController = rootViewController;
        dialog.shareContent = content;
        dialog.mode = FBSDKShareDialogModeNative;
        
        FBUnitySDKDelegate *delegate = [FBUnitySDKDelegate instanceWithRequestID:999];
        dialog.delegate = delegate;

        if (![dialog show]) {
            NSLog(@"分享链接失败");
        }
    }
    else if(self.dataStr != nil)
    {
        NSLog(@"分享文本");
         NSString *str_url = [NSString stringWithFormat:@"%@%@", @"fb://publish?text=", self.dataStr];
         NSURL *facebookURL = [NSURL URLWithString:str_url];
         if ([[UIApplication sharedApplication] canOpenURL:facebookURL]) {
             [[UIApplication sharedApplication] openURL:facebookURL options:@{} completionHandler:nil];
         } else {
             NSLog(@"分享文本失败");
         }

    }
}

@end


从UNITY复制图标到打包的xcode工程中

#if UNITY_IOS
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine;

public static class XCodePostProcessBuild
{
    [PostProcessBuild(int.MaxValue)]
	public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
	{
        if (target != BuildTarget.iOS)
		{
			Debug.LogWarning("Target is not iOS. XCodePostProcessBuild will not run");
			return;
		}

        string projectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
        var pbxProject = new PBXProject();
        pbxProject.ReadFromString(File.ReadAllText(projectPath));
        
#if UNITY_2019_3_OR_NEWER
        string mainTarget = pbxProject.GetUnityMainTargetGuid();  
        string frameworkTarget = pbxProject.GetUnityFrameworkTargetGuid();   
#else
        string mainTarget = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName());
        string frameworkTarget = mainTarget;
#endif

        DisableBitcode(pbxProject,mainTarget,frameworkTarget);

        pbxProject.SetBuildProperty(frameworkTarget, "FRAMEWORK_SEARCH_PATHS", "$(inherited)");
		pbxProject.AddBuildProperty(frameworkTarget, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks");
;
        SetXcodeImage(frameworkTarget,pbxProject,pathToBuiltProject);

        pbxProject.WriteToFile (projectPath);
    }

    static void DisableBitcode(PBXProject pbxProject,string mainTarget,string frameworkTarget)
    {
        pbxProject.SetBuildProperty(mainTarget, "ENABLE_BITCODE", "NO");
        pbxProject.SetBuildProperty(frameworkTarget, "ENABLE_BITCODE", "NO");
    }

    static void SetXcodeImage(string frameworkTarget,PBXProject pbxProject, string pathToBuiltProject)
    {
        //复制目录内容到指定的目录下
        AddDirectory(pbxProject, pathToBuiltProject, "Images", "Images", null);

        string target = pbxProject.GetUnityMainTargetGuid();
        //添加图片 让xcode识别
        pbxProject.AddFileToBuild(target, pbxProject.AddFile("Images/facebook_76x76@2x.png", "Images/facebook_76x76@2x.png", PBXSourceTree.Source));
        pbxProject.AddFileToBuild(target, pbxProject.AddFile("Images/facebook_60x60@2x.png", "Images/facebook_60x60@2x.png", PBXSourceTree.Source));
        pbxProject.AddFileToBuild(target, pbxProject.AddFile("Images/facebook_29x29@2x.png", "Images/facebook_29x29@2x.png", PBXSourceTree.Source));
    }

    public static void AddDirectory(PBXProject project, string pathToBuiltProject, string assetPath, 
    string xcodePath, Action<string> callback,bool recursiveDir = false,bool curDirFiles = false)
    {
        var path = Path.Combine(Application.dataPath, assetPath);
        var targetPath = Path.Combine(pathToBuiltProject, xcodePath);
        CopyDirectory(path, targetPath);
        var info = new DirectoryInfo(targetPath);

        if(recursiveDir)
        {
            var directories = info.GetDirectories();
            foreach (var dirInfo in directories)
            {
                string fileGuid = project.AddFile(xcodePath + "/" + dirInfo.Name, xcodePath + "/" + dirInfo.Name, PBXSourceTree.Source);

                if (callback != null)
                {
                    callback(fileGuid);
                }
            }
        }

        if (curDirFiles)
        {
            var filesList = info.GetFiles();
            foreach (var fileInfo in filesList)
            {
                string fileGuid = project.AddFile(xcodePath + "/" + fileInfo.Name, xcodePath + "/" + fileInfo.Name, PBXSourceTree.Source);

                if (callback != null)
                {
                    callback(fileGuid);
                }
            }
        }
        
    }

	public static void CopyDirectory(string sourcePath, string destinationPath)
	{
		if (destinationPath.EndsWith(".meta") || destinationPath.EndsWith(".DS_Store"))
			return;
		Debug.LogError("sourcePath:" + sourcePath);
		DirectoryInfo info = new DirectoryInfo(sourcePath);
		Directory.CreateDirectory(destinationPath);
		foreach (FileSystemInfo fsi in info.GetFileSystemInfos())
		{
			string destName = Path.Combine(destinationPath, fsi.Name);
            Debug.LogError("name:" + destName);
			if (destName.EndsWith(".meta") || destName.EndsWith(".DS_Store"))
				continue;

			if (fsi is System.IO.FileInfo)          //如果是文件,复制文件
				File.Copy(fsi.FullName, destName);
			else                                    //如果是文件夹,新建文件夹,递归
			{
				Directory.CreateDirectory(destName);
				CopyDirectory(fsi.FullName, destName);
			}
		}
	}
}
#endif



+(void) NativeShareImage:(NSString *)imagePath excludedActivityTypes:(NSArray *)excludedActivityTypes
{
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    NSArray *activityItems = @[image];
    
    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
    if(excludedActivityTypes != nil)
    {
        activityVC.excludedActivityTypes = excludedActivityTypes;
    }
    activityVC.completionWithItemsHandler = ^(NSString *activityType,BOOL completed,NSArray *returnedItems,NSError *activityError)
    {
        NSLog(@"%@", activityType);

        if (completed) { // 确定分享
            NSLog(@"分享成功");
        }
        else {
            NSLog(@"分享失败");
        }
    };

    UIViewController *vc =  UnityGetGLViewController();
    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) // iPad
     {
        UIPopoverPresentationController *presentationController = [activityVC popoverPresentationController];
        presentationController.sourceView = vc.view;
        presentationController.sourceRect = CGRectMake(vc.view.bounds.origin.x+vc.view.bounds.size.width/2,
                                                                vc.view.bounds.origin.y+vc.view.bounds.size.height,
                                                                0, 0);
        presentationController.permittedArrowDirections = 0;
     }

    [vc presentViewController:activityVC animated:YES completion:nil];
}



+(void) NativeShareText:(NSString *)textContent excludedActivityTypes:(NSArray *)excludedActivityTypes
{
    NSArray *activityItems = nil;
    if( [__NtNotificationWrapper checkUrlWithString:textContent] )
    {
        NSURL *shareURL = [NSURL URLWithString:textContent];
        activityItems = @[shareURL];
    }
    else
    {
        activityItems = @[textContent];
    }

    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
    if(excludedActivityTypes != nil)
    {
        activityVC.excludedActivityTypes = excludedActivityTypes;
    }

    UIViewController *vc =  UnityGetGLViewController();
    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) // iPad
     {
        UIPopoverPresentationController *presentationController = [activityVC popoverPresentationController];
        presentationController.sourceView = vc.view;
        presentationController.sourceRect = CGRectMake(vc.view.bounds.origin.x+vc.view.bounds.size.width/2,
                                                                vc.view.bounds.origin.y+vc.view.bounds.size.height,
                                                                0, 0);
        presentationController.permittedArrowDirections = 0;
     }

    [vc presentViewController:activityVC animated:YES completion:nil];


    activityVC.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError)
    {
        NSLog(@"%@", activityType);

        if (completed) { // 确定分享
            NSLog(@"分享成功");
        }
        else {
            NSLog(@"分享失败");
        }
    };
}



char* __NT_GetSystemFonts()
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *home;
    home = @"/System/Library/Fonts/";

    NSDirectoryEnumerator *myDirectoryEnumerator = [fileManager enumeratorAtPath:home];;
    NSMutableSet *files = [[NSMutableSet alloc] init];
    for (NSString *path in myDirectoryEnumerator.allObjects) {
                    
        [files addObject:[NSString stringWithFormat:@"%@%@", home, path]];
        
    }
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject: [files allObjects]
                                                               options:NSJSONWritingPrettyPrinted
                                                                 error:nil];
    if ([jsonData length] > 0 )
    {
        NSString *jsonString = [[NSString alloc] initWithData:jsonData
                                                        encoding:NSUTF8StringEncoding];

        return __makeCString(jsonString);
    }

    return __makeCString(@"");
}



//装箱 拆箱
CGPoint point = {100, 200};
NSValue *v1 = [NSValue valueWithPoint:point];
NSArray *varr = [NSArray arrayWithObjects:v1, nil];
NSPoint po = [v1 pointValue];

NSNumber *num1 = [NSNumber numberWithInt:200];
NSNumber *num2 = [NSNumber numberWithInt:300];
NSArray *arrnum = @[num1, num2];
int sum = 0;
for(NSNumber *num in arrnum)
{
    sum += [num intValue];
}
NSLog(@"num : %d", sum);



//字典 键值对的数据结构
NSDictionary *dic1 = @{@"name":@"chicai", @"age":@"18"};
NSDictionary *dic2 = [[NSDictionary alloc] init];
NSArray *keys = [dic1 allKeys];
for(NSString * key in keys)
{
    NSLog(@"key=%@,val=%@", key, dic1[key]);
}

//可变字典
NSMutableDictionary *mdic = [[NSMutableDictionary alloc] initWithCapacity:20];
[mdic setObject:@"chifan" forKey:@"name"];
[mdic setObject:@"18" forKey:@"age"];
[mdic removeObjectForKey:@"age"];
for(NSString *key in [mdic allKeys])
{
    NSLog(@"key=%@,val=%@", key, mdic[key]);
}



//集合内容不会重复
NSSet *set = [NSSet setWithObjects:@"1",@"3",@"6",@"3",nil];//NSMutableSet为可变集合
NSArray *sarr = [set allObjects];
for(NSString *str in set)
{
    NSLog(@"%@", str);
}



NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:100];
for(int i = 1;i<10;i++)
{
    [mArray addObject:[NSString stringWithFormat:@"%d",i]];
}
[mArray removeObjectAtIndex:2];
[mArray insertObject:@"666" atIndex:5];
[mArray removeAllObjects];



NSArray *array = @[@"1",@"2",@"3"];
NSLog(@"count %ld",[array count]);
for(int i = 0;i<[array count];i++)
{
    NSLog(@"%@",array[i]);
}
for(NSString *sss in array)
{
    NSLog(@"%@", sss);
}



NSMutableString *mStr = [NSMutableString stringWithCapacity:100];
NSLog(@"%@", mStr);
[mStr appendFormat:@"%@",@"123"];
NSLog(@"%@", mStr);
NSRange r = {0,2};
[mStr replaceCharactersInRange:r withString:@"hehe"];
NSLog(@"%@", mStr);
[mStr deleteCharactersInRange:r];
NSLog(@"%@", mStr);