iphone plist中只声明NSAllowsArbitraryLoads不用声明NSAllowsArbitraryLoadsInWebContent
发现有一种情况,就是原生的分享,选中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);
}