159 lines
5.2 KiB
Swift
159 lines
5.2 KiB
Swift
import Foundation
|
|
import Photos
|
|
import MobileCoreServices
|
|
|
|
@objc(ReceiveSharingIntent)
|
|
class ReceiveSharingIntent: NSObject {
|
|
|
|
struct Share: Codable {
|
|
var media: [SharedMediaFile] = []
|
|
var text: [String] = []
|
|
var urls: [String] = []
|
|
}
|
|
|
|
private var share = Share()
|
|
|
|
@objc
|
|
func getFileNames(_ url: String,
|
|
resolver resolve: RCTPromiseResolveBlock,
|
|
rejecter reject: RCTPromiseRejectBlock
|
|
) -> Void {
|
|
let fileUrl = URL(string: url)
|
|
let json = handleUrl(url: fileUrl);
|
|
if(json == "error"){
|
|
let error = NSError(domain: "", code: 400, userInfo: nil)
|
|
reject("message", "file type is Invalid", error);
|
|
}else if(json == "invalid group name"){
|
|
let error = NSError(domain: "", code: 400, userInfo: nil)
|
|
reject("message", "invalid group name. Please check your share extention bundle name is same as `group.mainbundle name` ", error);
|
|
}else{
|
|
resolve(json);
|
|
}
|
|
}
|
|
|
|
private func handleUrl(url: URL?) -> String? {
|
|
if let url = url {
|
|
let appDomain = Bundle.main.bundleIdentifier!
|
|
let userDefaults = UserDefaults(suiteName: "group.\(appDomain)")
|
|
if let key = url.host?.components(separatedBy: "=").last {
|
|
if let mediaJson = userDefaults?.object(forKey: "\(key).media") as? Data {
|
|
let mediaSharedArray = decode(data: mediaJson)
|
|
let sharedMediaFiles: [SharedMediaFile] = mediaSharedArray.compactMap {
|
|
guard let path = getAbsolutePath(for: $0.path) else {
|
|
return nil
|
|
}
|
|
|
|
return SharedMediaFile.init(path: path, fileName: fileNameForPath(path: path), mimeType: mimeTypeForPath(path: path))
|
|
}
|
|
self.share.media = sharedMediaFiles
|
|
}
|
|
if let textSharedArray = userDefaults?.object(forKey: "\(key).text") as? [String] {
|
|
self.share.text = textSharedArray
|
|
}
|
|
if let textSharedArray = userDefaults?.object(forKey: "\(key).url") as? [String] {
|
|
self.share.urls = textSharedArray
|
|
}
|
|
let encodedData = try? JSONEncoder().encode(self.share)
|
|
let json = String(data: encodedData!, encoding: .utf8)!
|
|
return json
|
|
}
|
|
return "error"
|
|
}
|
|
return "invalid group name"
|
|
}
|
|
|
|
|
|
private func getAbsolutePath(for identifier: String) -> String? {
|
|
if (identifier.starts(with: "file://") || identifier.starts(with: "/var/mobile/Media") || identifier.starts(with: "/private/var/mobile")) {
|
|
return identifier;
|
|
}
|
|
let phAsset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: .none).firstObject
|
|
if(phAsset == nil) {
|
|
return nil
|
|
}
|
|
let (url, _) = getFullSizeImageURLAndOrientation(for: phAsset!)
|
|
return url
|
|
}
|
|
|
|
private func getFullSizeImageURLAndOrientation(for asset: PHAsset)-> (String?, Int) {
|
|
var url: String? = nil
|
|
var orientation: Int = 0
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
let options2 = PHContentEditingInputRequestOptions()
|
|
options2.isNetworkAccessAllowed = true
|
|
asset.requestContentEditingInput(with: options2){(input, info) in
|
|
orientation = Int(input?.fullSizeImageOrientation ?? 0)
|
|
url = input?.fullSizeImageURL?.path
|
|
semaphore.signal()
|
|
}
|
|
semaphore.wait()
|
|
return (url, orientation)
|
|
}
|
|
|
|
private func decode(data: Data) -> [SharedMediaFile] {
|
|
let encodedData = try? JSONDecoder().decode([SharedMediaFile].self, from: data)
|
|
return encodedData!
|
|
}
|
|
|
|
private func toJson(data: [SharedMediaFile]?) -> String? {
|
|
if data == nil {
|
|
return nil
|
|
}
|
|
let encodedData = try? JSONEncoder().encode(data)
|
|
let json = String(data: encodedData!, encoding: .utf8)!
|
|
return json
|
|
}
|
|
|
|
class SharedMediaFile: Codable {
|
|
var path: String;
|
|
var fileName: String?;
|
|
var mimeType: String?;
|
|
|
|
init(path: String, fileName: String?, mimeType: String?) {
|
|
self.path = path
|
|
self.fileName = fileName
|
|
self.mimeType = mimeType
|
|
}
|
|
}
|
|
|
|
@objc
|
|
func clearFileNames(){
|
|
let containerURL = FileManager.default
|
|
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(Bundle.main.bundleIdentifier!)")!
|
|
let shareTempDirPath = containerURL.appendingPathComponent("ShareTemp", isDirectory: true)
|
|
do {
|
|
let fileNames = try FileManager.default.contentsOfDirectory(atPath: shareTempDirPath.relativePath)
|
|
for fileName in fileNames {
|
|
let filePath = shareTempDirPath.appendingPathComponent(fileName)
|
|
try FileManager.default.removeItem(at: filePath)
|
|
}
|
|
} catch {
|
|
print(error)
|
|
}
|
|
}
|
|
|
|
|
|
@objc
|
|
static func requiresMainQueueSetup() -> Bool {
|
|
return true
|
|
}
|
|
}
|
|
|
|
func fileNameForPath(path: String) -> String? {
|
|
let url = NSURL(fileURLWithPath: path)
|
|
return url.lastPathComponent
|
|
}
|
|
|
|
func mimeTypeForPath(path: String) -> String {
|
|
let url = NSURL(fileURLWithPath: path)
|
|
let pathExtension = url.pathExtension
|
|
|
|
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
|
|
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
|
|
return mimetype as String
|
|
}
|
|
return "application/octet-stream"
|
|
}
|
|
return "application/octet-stream"
|
|
}
|