Unity3D-呼叫IOS原生分享的實現
最近專案需要更改分享方式,以前接入各種SKD去分享的,現在要求直接使用IOS原生分享的介面!
一開始去網上找,發現並沒有人直接寫程式碼使用,但是在Unity的AssetStore中我找到了一個外掛,也就是IOSNative外掛,但是外掛帶的功能比較多,我自己基本用不到,然後就自己寫了一個和IOS互動的oc類,只調用系統自帶的分享框,並且拿到是否點選了分享還是取消的回撥。
先在匯出的xcode工程中建立一個類GJCSocialShare, 我在參考了IOSNative外掛的基礎上,修改了下顯示位置,使Ipad也能顯示在螢幕下方
.h檔案內容
#import <UIKit/UIKit.h> @interface GJCSocialShare : NSObject + (id) sharedInstance; - (void) nativeShare:(NSString*)text media: (NSString*) media; @end @interface GJC_DataConvertor : NSObject + (NSString*) charToNSString: (char*)value; + (const char*) NSIntToChar: (NSInteger) value; + (const char*) NSStringToChar: (NSString*) value; + (NSArray*) charToNSArray: (char*)value; + (const char*) serializeErrorWithData:(NSString*)description code: (int) code; + (const char*) serializeError:(NSError*)error; + (NSMutableString*) serializeErrorWithDataToNSString:(NSString*)description code: (int) code; + (NSMutableString*) serializeErrorToNSString:(NSError*)error; + (const char*) NSStringsArrayToChar:(NSArray*) array; + (NSString*) serializeNSStringsArray:(NSArray*) array; @end
這其中的DataConvertor是參考的IOSNative外掛裡面,為了更方便的使用資料
.mm檔案內容
#import "GJCSocialShare.h" #import <Social/Social.h> NSString* const STR_SPLITTER = @"|"; NSString* const STR_EOF = @"endofline"; NSString* const STR_ARRAY_SPLITTER = @"%%%"; @implementation GJCSocialShare static GJCSocialShare* gjc_sharedInstance; + (id)sharedInstance { if (gjc_sharedInstance == nil) { gjc_sharedInstance = [[self alloc] init]; } return gjc_sharedInstance; } -(void) nativeShare:(NSString*)text media:(NSString*)media { NSLog(@"==============>nativeShare"); UIActivityViewController *controller; if(media.length != 0) { NSData* imageData = [[NSData alloc]initWithBase64EncodedString:media options:0]; UIImage* image = [[UIImage alloc] initWithData:imageData]; NSLog(@"==============>image added"); if(text.length != 0) { NSLog(@"==============>text added"); controller = [[UIActivityViewController alloc] initWithActivityItems:@[text, image] applicationActivities:nil]; } else { NSLog(@"==============>no text"); controller = [[UIActivityViewController alloc] initWithActivityItems:@[image] applicationActivities:nil]; } } else { NSLog(@"==============>no image"); controller = [[UIActivityViewController alloc] initWithActivityItems:@[text] applicationActivities:nil]; } UIViewController* vc = UnityGetGLViewController(); NSArray* vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; if ([[vComp objectAtIndex:0] intValue] >= 8) { UIPopoverPresentationController *presentationController = [controller 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:controller animated:YES completion:nil]; controller.completionWithItemsHandler = ^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) { // NSLog(@"activityType :%@", activityType); if (completed){ UnitySendMessage("GJCNativeShare", "OnNativeShareSuccess", [GJC_DataConvertor NSStringToChar:activityType]); // NSLog(@"completed!"); }else{ if (activityType != nil){ UnitySendMessage("GJCNativeShare", "OnNativeShareCancel", [GJC_DataConvertor NSStringToChar:activityType]); }else{ UnitySendMessage("GJCNativeShare", "OnNativeShareCancel", [GJC_DataConvertor NSStringToChar:@""]); } // NSLog(@"cancel!"); } }; } @end @implementation GJC_DataConvertor +(NSString*) charToNSString:(char*)value { if (value != NULL) { return [NSString stringWithUTF8String: value]; } else { return [NSString stringWithUTF8String: ""]; } } +(const char*)NSIntToChar:(NSInteger)value { NSString* tmp = [NSString stringWithFormat:@"%ld", (long)value]; return [tmp UTF8String]; } + (const char*) NSStringToChar:(NSString*)value { return [value UTF8String]; } + (NSArray*)charToNSArray:(char*)value { NSString* strValue = [GJC_DataConvertor charToNSString:value]; NSArray* array; if([strValue length] == 0) { array = [[NSArray alloc] init]; } else { array = [strValue componentsSeparatedByString:STR_ARRAY_SPLITTER]; } return array; } + (const char*) NSStringsArrayToChar:(NSArray*) array { return [GJC_DataConvertor NSStringToChar:[GJC_DataConvertor serializeNSStringsArray:array]]; } + (NSString*) serializeNSStringsArray:(NSArray*) array { NSMutableString* data = [[NSMutableString alloc] init]; for(NSString* str in array) { [data appendString:str]; [data appendString: STR_ARRAY_SPLITTER]; } [data appendString: STR_EOF]; NSString* str = [data copy]; #if UNITY_VERSION < 500 [str autorelease]; #endif return str; } + (NSMutableString*)serializeErrorToNSString:(NSError*)error { NSString* description = @""; if(error.description != nil) { description = error.description; } return [self serializeErrorWithDataToNSString:description code: (int) error.code]; } + (NSMutableString*)serializeErrorWithDataToNSString:(NSString*)description code:(int)code { NSMutableString* data = [[NSMutableString alloc] init]; [data appendFormat:@"%i", code]; [data appendString: STR_SPLITTER]; [data appendString: description]; return data; } + (const char*) serializeErrorWithData:(NSString*)description code: (int) code { NSString* str = [GJC_DataConvertor serializeErrorWithDataToNSString:description code:code]; return [GJC_DataConvertor NSStringToChar:str]; } + (const char*) serializeError:(NSError*)error { NSString* str = [GJC_DataConvertor serializeErrorToNSString:error]; return [GJC_DataConvertor NSStringToChar:str]; } @end extern "C" { void _GJC_NativeShare(char* text, char* encodedMedia) { NSString* status = [GJC_DataConvertor charToNSString:text]; NSString* media = [GJC_DataConvertor charToNSString:encodedMedia]; [[GJCSocialShare sharedInstance] nativeShare:status media:media]; } }
這兩個檔案放在Assets的Plugins/iOS下面,另外還需要寫一個C#端的使用方法和回撥:
.cs檔案,注意檔案的名稱,以及掛在場景中物件的名稱,如果和我的不一樣,你需要把.mm中使用UnitySendMessage方法中新增的第一個引數的字串名字保持一致
using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_IPHONE && !UNITY_EDITOR using System.Runtime.InteropServices; #endif public class GJCNativeShare : MonoBehaviour { #if UNITY_IPHONE && !UNITY_EDITOR [DllImport ("__Internal")] private static extern void _GJC_NativeShare(string text, string encodedMedia); #endif public delegate void OnShareSuccess(string platform); public delegate void OnShareCancel(string platform); public OnShareSuccess onShareSuccess = null; public OnShareCancel onShareCancel = null; private static GJCNativeShare _instance = null; public static GJCNativeShare Instance { get { if (_instance == null) { _instance = GameObject.FindObjectOfType(typeof(GJCNativeShare)) as GJCNativeShare; if (_instance == null) { _instance = new GameObject ().AddComponent<GJCNativeShare> (); _instance.gameObject.name = _instance.GetType ().FullName; } } return _instance; } } public void NativeShare(string text, Texture2D texture = null) { Debug.Log("NativeShare"); #if UNITY_IPHONE && !UNITY_EDITOR if(texture != null) { Debug.Log("NativeShare: Texture"); byte[] val = texture.EncodeToPNG(); string bytesString = System.Convert.ToBase64String (val); _GJC_NativeShare(text, bytesString); } else { Debug.Log("NativeShare: No Texture"); _GJC_NativeShare(text, ""); } #endif } private void OnNativeShareSuccess(string result){ // Debug.Log("success: " + result); if (onShareSuccess!=null){ onShareSuccess(result); } } private void OnNativeShareCancel(string result){ // Debug.Log("cancel: " + result); if (onShareCancel != null){ onShareCancel(result); } } }
接下來就是使用,本方法可以傳遞一個分享的字串和一個螢幕截圖:
在Init中添加回調:
public void Init(){
blnInitNativeShare = true;
GJCNativeShare.Instance.onShareSuccess = OnShareSuccess;
GJCNativeShare.Instance.onShareCancel = OnShareCancel;
}
void OnShareSuccess(string platform){
//...your code
}
void OnShareCancel(string platform){
//...your code
}
然後是呼叫
public void ShareWithNative(){
StartCoroutine(TakeScreenshot());
}
private IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
var width = Screen.width;
var height = Screen.height;
var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
GJCNativeShare.Instance.NativeShare(shareDefaultText, tex);
Destroy(tex);
}
另外,需要在unity中選中.mm檔案,現在可以直接在Unity編輯器中選中需要新增的IOS framework包,把Social勾上即可在xcode中新增這個framework
看看效果圖:彈出框
分享文字
分享帶截圖文字
相關推薦
Unity3D-呼叫IOS原生分享的實現
連線 最近專案需要更改分享方式,以前接入各種SKD去分享的,現在要求直接使用IOS原生分享的介面! 一開始去網上找,發現並沒有人直接寫程式碼使用,但是在Unity的AssetStore中我找到了一個外掛,也就是IOSNative外掛,但是外掛帶的功能比較多,我自己基本用不到
Unity3D 嵌入iOS原生程式碼,並實現unity iOS之間的互動
Unity iOS嵌入 互動 傳值 專案需要用到iOS和Unity之間的互動, 就捯飭了一下 我專案是Unity工程大, iOS工程小, 所以在是Unity匯出的xcode工程裡嵌入iOS
Unity呼叫iOS原生內購
Unity在5.x以後的版本,都附帶了各種平臺的IAP(內購),網上一搜Unity IAP,就一大堆如何如何接入的教程,據說還挺方便的。本人也是用Unity 5.x,也曾經用了一下Unity的IAP,那為何現在還要討論呼叫iOS原生的IAP呢? 在這裡不得不吐槽一下Unity的IAP,雖然它目的
React Native呼叫Android原生程式碼實現車牌識別功能【附效果圖附原始碼】
這段時間研究了下React Native,Facebook推出的,結合了Web應用和Native應用的優勢,可以使用JavaScript來開發iOS和Android原生應用,決定簡單研究下,於是開始搭建環境,編寫HelloWorld,完成後又覺得HelloWo
iOS開發(OC)——iOS原生API實現檔案下載
新建繼承NSObject類Downloader Downloader.h程式碼 #import <Foundation/Foundation.h> #import <UIKit
[iOS 原生程式碼實現掃描二維碼/條形碼] AVCaptureDevice
//參照別人的教程的作業貼 記錄一下注意點 掃碼的主要原生程式碼如下 這裡比較關鍵的是對掃碼作用範圍的確定,metdataOutput.rectOfInterest 如果不設定,那麼預設就
React Native 呼叫iOS原生功能—直播
專案 中 採用React Native 開發 ,觀看直播呼叫iOS 原生介面 RN程式碼 import React, { Component } from 'react'; import { Platform, StyleSheet, Text, V
Unity3D呼叫iOS攝像頭全屏旋轉,ZXing測試
在測試Unity3D ZXing程式碼時,呼叫iOS攝像頭的效果總不令我滿意,你會發現用WebCamTexture呼叫的攝像頭畫面跟iOS自帶相簿呼叫的效果不一樣,焦距有點問題。雖然這不影響ZXing的呼叫,但我還是搜了下,解決了這個問題,還可以適應螢幕旋轉。參
Unity3D 呼叫Android原生方法2
記一次Unity通過Android系統函式獲取記憶體資訊的過程,感謝河馬爸爸指導。 Unity原生方法沒有獲取當前可用記憶體的方法,系統記憶體資訊android底層肯定有方法獲取,於是我搜到了這篇文章(http://blog.csdn.net/sxwyf248/articl
ios webView怎麼實現原生呼叫JS?
在iOS 7之後,apple添加了一個新的庫JavaScriptCore,用來做JS互動,因此JS與原生OC互動也變得簡單了許多。 第一種方法 首先匯入JavaScriptCore庫, 然後在OC中獲取JS的上下文 JSContext *context = [self.web
vue 實現 ios 原生picker 效果(實現思路分析)
sta 效果 cursor touchend orm dex tex sub alt 以前最早實現了一個類似的時間選擇插件,但是適用範圍太窄,索性最近要把這個實現方式發布出來,就重寫了一個高復用的vue組件。 支持安卓4.0以上,safari 7以上 效果預覽 gitHu
WebViewJavascriptBridge實現js與android和ios原生交互
WebViewJavascriptB Android IOS js 1、實現原生與js交互 <!-- 申明交互 這段代碼固定必須有 --> function setupWebViewJavascriptBridge(callback) { //android使用
ios webView怎麼實現JS調原生
1)在方法- (void)webViewDidFinishLoad:(UIWebView *)webView 中 self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScr
在微擎呼叫微信JSSDK實現分享功能
最近遇到一個專案是基於微擎框架做一個分享功能的,微擎本身是自帶分享功能的,只是這次想要實現自定義分享內容,故進行了以下程式碼處理 * $_W[‘account’][‘jssdkconfig’]是微擎封裝好的jssdk簽名包的內容 * php頁面程式碼 <?php if
JavaScript:使用原生JS實現Jsonp跨域,呼叫百度搜索介面完成聯想詞功能
Jsonp解釋 Jsonp這個術語聽起來很高大上,其實它的原理非常簡單,就是利用src不受同源策略限制這一點來實現的,很多標籤都有src特性。 你們可以想想為什麼img標籤能將不同源的百度logo拿過來? <img src="https://www.baidu.com/
呼叫微信介面實現網頁分享小功能
// 獲取access_token *注意* 經過實際開發測試,微信分享不支援跨域請求,因此獲取access_token的請求必須從伺服器發起,否則無法獲取到access_token所以以下都是服務端操作 一、微信util類 public class Share
iOS原生實現二維碼拉近放大
http://www.cocoachina.com/ios/20180416/23033.html 2018-04-16 15:34 編輯: yyuuzhu 分類:iOS開發 來源:程式鵝 8 3008 iOS &nb
Unity3D 呼叫Android與IOS的剪貼簿
Unity3D剪貼簿 最近遇到一個需要呼叫Android與IOS裝置本身剪貼簿的需求,就是在Unity中,要將文字複製到裝置本身的剪貼簿中,然後在其他應用程式中都能貼上。 最開始在網上查到的方式是使用Unity3D本身自帶的TextEditor 類進行使用,使用方法如
基於ES6和原生nodejs實現自定義路由,靜態檔案伺服器和增刪查改的MVC架構分享
基於ES6和原生nodejs來實現一個基於MVC的增刪查改功能示例分享 自定義路由的解耦實現 首先分別處理不同方式的請求: const http = require('http'); const url = require('url')
cocos2d-x + Lua接入iOS原生SDK的實現方案
相信很多朋友在使用cocos2d-x+lua開發遊戲時都遇到過接入iOS原生SDK的問題,比如常見的接應用內支付SDK,廣告SDK或是一些社交平臺SDK等等,我也沒少接過這類SDK。這篇文章主要是對我做過專案中接入iOS原生SDK實現方案的一個總結,在這裡分享給大家,希望對自己和大家的開發工作都有幫