Files
standardnotes-app-web/packages/mobile/ios/ReceiveSharingIntent/ReceiveSharingIntent.swift
2023-07-25 00:28:15 +05:30

165 lines
5.5 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 appDomain = Bundle.main.bundleIdentifier!
let groupName = "group.\(appDomain)"
let userDefaults = UserDefaults(suiteName: groupName)
userDefaults?.set(nil, forKey: "ShareKey.media")
userDefaults?.set(nil, forKey: "ShareKey.text")
userDefaults?.set(nil, forKey: "ShareKey.url")
let containerURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: groupName)!
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"
}