发现有一种情况,就是原生的分享,选中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);