Skip to content

Commit

Permalink
/issues/5009 - Refactored away the NSExtensionContext dependency from…
Browse files Browse the repository at this point in the history
… the ShareManager. Introduced different ShareItemProviders for the share extension and the main application. Improved item loading error handling.
  • Loading branch information
stefanceriu committed Oct 15, 2021
1 parent 33c4bbc commit 89f6503
Show file tree
Hide file tree
Showing 21 changed files with 524 additions and 273 deletions.
20 changes: 6 additions & 14 deletions Riot/Modules/Room/RoomViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -3167,16 +3167,14 @@ - (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXK
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSExtensionItem *item = [[NSExtensionItem alloc] init];
item.attachments = @[[[NSItemProvider alloc] initWithItem:selectedComponent.textMessage typeIdentifier:(__bridge NSString *)kUTTypeText]];

self.shareManager = [[ShareManager alloc] initWithItems:@[item]];
self.shareManager = [[ShareManager alloc] initWithShareItemProvider:[[SimpleShareItemProvider alloc] initWithTextMessage:selectedComponent.textMessage]];

MXWeakify(self);
[self.shareManager setCompletionCallback:^(ShareManagerResult result) {
MXStrongifyAndReturnIfNil(self);
[attachment onShareEnded];
[self dismissViewControllerAnimated:YES completion:nil];
self.shareManager = nil;
}];

[self presentViewController:self.shareManager.mainViewController animated:YES completion:nil];
Expand Down Expand Up @@ -3364,31 +3362,25 @@ - (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXK

if (attachment.type == MXKAttachmentTypeFile ||
attachment.type == MXKAttachmentTypeImage ||
attachment.type == MXKAttachmentTypeVideo) {
attachment.type == MXKAttachmentTypeVideo ||
attachment.type == MXKAttachmentTypeVoiceMessage) {

[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {

NSDictionary *attachmentTypeToIdentifier = @{@(MXKAttachmentTypeFile): (__bridge NSString *)kUTTypeFileURL,
@(MXKAttachmentTypeImage): (__bridge NSString *)kUTTypeImage,
@(MXKAttachmentTypeVideo): (__bridge NSString *)kUTTypeVideo};

[self startActivityIndicator];

[attachment prepareShare:^(NSURL *fileURL) {
[self stopActivityIndicator];

NSExtensionItem *item = [[NSExtensionItem alloc] init];
item.attachments = @[[[NSItemProvider alloc] initWithItem:fileURL typeIdentifier:attachmentTypeToIdentifier[@(attachment.type)]]];

self.shareManager = [[ShareManager alloc] initWithItems:@[item]];
self.shareManager = [[ShareManager alloc] initWithShareItemProvider:[[SimpleShareItemProvider alloc] initWithAttachment:attachment]];

MXWeakify(self);
[self.shareManager setCompletionCallback:^(ShareManagerResult result) {
MXStrongifyAndReturnIfNil(self);
[attachment onShareEnded];
[self dismissViewControllerAnimated:YES completion:nil];
self.shareManager = nil;
}];

[self presentViewController:self.shareManager.mainViewController animated:YES completion:nil];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

@objc public enum ShareItemType: UInt {
case fileURL, text, URL, image, video, movie, voiceMessage, unknown
}

@objc public protocol ShareItemProtocol {
var type: ShareItemType { get }
}

@objc public protocol ShareItemProviderProtocol {
var items: [ShareItemProtocol] { get }

func areAllItemsImages() -> Bool

func areAllItemsLoaded() -> Bool

func loadItem(_ item: ShareItemProtocol, completion: @escaping (Any?, Error?) -> Void)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

private class SimpleShareItem: ShareItemProtocol {
let attachment: MXKAttachment?
let textMessage: String?

init(withAttachment attachment: MXKAttachment) {
self.attachment = attachment
self.textMessage = nil
}

init(withTextMessage textMessage: String) {
self.attachment = nil
self.textMessage = textMessage
}

var type: ShareItemType {
guard textMessage == nil else {
return .text
}

guard let attachment = attachment else {
return .unknown
}

if attachment.type == MXKAttachmentTypeImage {
return .image
} else if attachment.type == MXKAttachmentTypeVideo {
return .video
} else if attachment.type == MXKAttachmentTypeFile {
return .fileURL
} else if attachment.type == MXKAttachmentTypeVoiceMessage {
return .voiceMessage
} else {
return .unknown
}
}
}

@objc class SimpleShareItemProvider: NSObject, ShareItemProviderProtocol {

private let attachment: MXKAttachment?
private let textMessage: String?

let items: [ShareItemProtocol]

@objc public init(withAttachment attachment: MXKAttachment) {
self.attachment = attachment
self.items = [SimpleShareItem(withAttachment: attachment)];
self.textMessage = nil
}

@objc public init(withTextMessage textMessage: String) {
self.textMessage = textMessage
self.items = [SimpleShareItem(withTextMessage: textMessage)];
self.attachment = nil
}

func loadItem(_ item: ShareItemProtocol, completion: @escaping (Any?, Error?) -> Void) {
if let textMessage = self.textMessage {
completion(textMessage, nil)
return
}

attachment?.prepareShare({ url in
completion(url, nil)
}, failure: { error in
completion(nil, error)
})
}

func areAllItemsLoaded() -> Bool {
return true
}

func areAllItemsImages() -> Bool {
return (attachment != nil && attachment?.type == MXKAttachmentTypeImage)
}
}
4 changes: 3 additions & 1 deletion RiotShareExtension/Shared/ShareManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#import <MatrixKit/MatrixKit.h>

@protocol ShareItemProviderProtocol;

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, ShareManagerResult) {
Expand All @@ -28,7 +30,7 @@ typedef NS_ENUM(NSUInteger, ShareManagerResult) {

@property (nonatomic, copy) void (^completionCallback)(ShareManagerResult);

- (instancetype)initWithItems:(NSArray<NSExtensionItem *> *)items;
- (instancetype)initWithShareItemProvider:(id<ShareItemProviderProtocol>)shareItemProvider;

- (UIViewController *)mainViewController;

Expand Down
Loading

0 comments on commit 89f6503

Please sign in to comment.