Skip to content

Commit

Permalink
TW-728: fix sharing screenshot is not working in IOS
Browse files Browse the repository at this point in the history
  • Loading branch information
sherlockvn committed Oct 16, 2023
1 parent 343712e commit 2a97937
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 115 deletions.
4 changes: 4 additions & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ target 'Runner' do
use_modular_headers!

flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

target 'Twake Share' do
inherit! :search_paths
end
end

post_install do |installer|
Expand Down
196 changes: 111 additions & 85 deletions ios/Runner.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppGroupId</key>
<string>$(CUSTOM_GROUP_ID)</string>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>im.fluffychat.app</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppGroupId</key>
<string>$(CUSTOM_GROUP_ID)</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import Photos

class ShareViewController: SLComposeServiceViewController {
// TODO: IMPORTANT: This should be your host app bundle identifier
let hostAppBundleIdentifier = "com.linagora.ios.twake"
var hostAppBundleIdentifier = "com.linagora.ios.twake"
let sharedKey = "ShareKey"
var appGroupId = ""
var sharedMedia: [SharedMediaFile] = []
var sharedText: [String] = []
let imageContentType = kUTTypeImage as String
Expand All @@ -15,12 +16,30 @@ class ShareViewController: SLComposeServiceViewController {
let urlContentType = kUTTypeURL as String
let fileURLType = kUTTypeFileURL as String;

private func loadIds() {
// loading Share extension App Id
let shareExtensionAppBundleIdentifier = Bundle.main.bundleIdentifier!;


// convert ShareExtension id to host app id
// By default it is remove last part of id after last point
// For example: com.test.ShareExtension -> com.test
let lastIndexOfPoint = shareExtensionAppBundleIdentifier.lastIndex(of: ".");
hostAppBundleIdentifier = String(shareExtensionAppBundleIdentifier[..<lastIndexOfPoint!]);

// loading custom AppGroupId from Build Settings or use group.<hostAppBundleIdentifier>
appGroupId = (Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as? String) ?? "group.\(hostAppBundleIdentifier)";
}

override func isContentValid() -> Bool {
return true
}

override func viewDidLoad() {
super.viewDidLoad();

// load group and app id from build info
loadIds();
}

override func viewDidAppear(_ animated: Bool) {
Expand Down Expand Up @@ -64,7 +83,7 @@ class ShareViewController: SLComposeServiceViewController {

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
let userDefaults = UserDefaults(suiteName: this.appGroupId)
userDefaults?.set(this.sharedText, forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .text)
Expand All @@ -85,7 +104,7 @@ class ShareViewController: SLComposeServiceViewController {

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
let userDefaults = UserDefaults(suiteName: this.appGroupId)
userDefaults?.set(this.sharedText, forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .text)
Expand All @@ -98,30 +117,55 @@ class ShareViewController: SLComposeServiceViewController {
}

private func handleImages (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {

func completed(copied: Bool, newPath: URL) {
if(copied) {
sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image))
}

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count ?? 0) - 1 {
let userDefaults = UserDefaults(suiteName: "group.\(hostAppBundleIdentifier)")
userDefaults?.set(toData(data: sharedMedia), forKey: sharedKey)
userDefaults?.synchronize()
redirectToHostApp(type: .media)
}
}

attachment.loadItem(forTypeIdentifier: imageContentType, options: nil) { [weak self] data, error in

if error == nil, let url = data as? URL, let this = self {

// Always copy
let fileName = this.getFileName(from: url, type: .image)
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!
.appendingPathComponent(fileName)
let copied = this.copyFile(at: url, to: newPath)
if(copied) {
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image))
}

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .media)
guard let this = self else { return }

if error == nil {

let groupRootURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!

if let url = data as? URL {
// Always copy
let fileName = this.getFileName(from: url, type: .image)
let newPath = groupRootURL.appendingPathComponent(fileName)
let copied = this.copyFile(at: url, to: newPath)
completed(copied: copied, newPath: newPath)
} else if let image = data as? UIImage,
let jpegData = image.jpegData(compressionQuality: 1.0) {

let fileName = "\(Int64(Date().timeIntervalSince1970)).jpg"
let newPath = groupRootURL.appendingPathComponent(fileName)

var copied = false
do {
try jpegData.write(to: newPath)
copied = true
} catch {
this.dismissWithError()
}
completed(copied: copied, newPath: newPath)
} else {
this.dismissWithError()
}

} else {
self?.dismissWithError()
this.dismissWithError()
}
}
}
Expand All @@ -134,7 +178,7 @@ class ShareViewController: SLComposeServiceViewController {
// Always copy
let fileName = this.getFileName(from: url, type: .video)
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
.appendingPathComponent(fileName)
let copied = this.copyFile(at: url, to: newPath)
if(copied) {
Expand All @@ -146,7 +190,7 @@ class ShareViewController: SLComposeServiceViewController {

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
let userDefaults = UserDefaults(suiteName: this.appGroupId)
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .media)
Expand All @@ -166,15 +210,15 @@ class ShareViewController: SLComposeServiceViewController {
// Always copy
let fileName = this.getFileName(from :url, type: .file)
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
.appendingPathComponent(fileName)
let copied = this.copyFile(at: url, to: newPath)
if (copied) {
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .file))
}

if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
let userDefaults = UserDefaults(suiteName: this.appGroupId)
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .file)
Expand All @@ -200,6 +244,8 @@ class ShareViewController: SLComposeServiceViewController {
}

private func redirectToHostApp(type: RedirectType) {
// ids may not loaded yet so we need loadIds here too
loadIds();
let url = URL(string: "ShareMedia-\(hostAppBundleIdentifier)://dataUrl=\(sharedKey)#\(type)")
var responder = self as UIResponder?
let selectorOpenURL = sel_registerName("openURL:")
Expand Down Expand Up @@ -291,7 +337,7 @@ class ShareViewController: SLComposeServiceViewController {
private func getThumbnailPath(for url: URL) -> URL {
let fileName = Data(url.lastPathComponent.utf8).base64EncodedString().replacingOccurrences(of: "==", with: "")
let path = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(hostAppBundleIdentifier)")!
.containerURL(forSecurityApplicationGroupIdentifier: appGroupId)!
.appendingPathComponent("\(fileName).jpg")
return path
}
Expand Down Expand Up @@ -332,4 +378,4 @@ extension Array {
subscript (safe index: UInt) -> Element? {
return Int(index) < count ? self[Int(index)] : nil
}
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion scripts/build-ios.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ FLUFFYCHAT_ORIG_TEAM="4NXF6Z997G"
### Rotate IDs ###
[ -n "${FLUFFYCHAT_NEW_GROUP}" ] && {
# App group IDs
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/FluffyChat Share/FluffyChat Share.entitlements"
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/Twake Share/Twake Share.entitlements"
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/Runner/Runner.entitlements"
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/Runner.xcodeproj/project.pbxproj"
# Bundle identifiers
Expand Down

0 comments on commit 2a97937

Please sign in to comment.