mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 02:58:07 +00:00
Add shared extension
This commit is contained in:
parent
54fa7be51d
commit
faf84164a4
15 changed files with 557 additions and 134 deletions
|
|
@ -394,6 +394,7 @@ final class ContactsManager: ObservableObject {
|
|||
}
|
||||
|
||||
func addFriendListDelegate() {
|
||||
self.coreContext.doOnCoreQueue { _ in
|
||||
CoreContext.shared.mCore.friendListSubscriptionEnabled = true
|
||||
|
||||
CoreContext.shared.mCore.friendsLists.forEach { friendList in
|
||||
|
|
@ -485,8 +486,10 @@ final class ContactsManager: ObservableObject {
|
|||
friendList.addDelegate(delegate: friendListDelegateTmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addCoreDelegate(core: Core) {
|
||||
self.coreContext.doOnCoreQueue { _ in
|
||||
self.coreDelegate = CoreDelegateStub(
|
||||
onFriendListCreated: { (_: Core, friendList: FriendList) in
|
||||
Log.info("\(ContactsManager.TAG) Friend list \(friendList.displayName) created")
|
||||
|
|
@ -508,6 +511,7 @@ final class ContactsManager: ObservableObject {
|
|||
core.addDelegate(delegate: self.coreDelegate!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setupSubscriptions() {
|
||||
cancellables.removeAll()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@
|
|||
<dict>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>org.linphone.phone</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>linphone-message</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ struct RootView: View {
|
|||
ToastView().zIndex(3)
|
||||
}
|
||||
} else {
|
||||
ZStack {
|
||||
MainViewSwitcher(
|
||||
coreContext: coreContext,
|
||||
navigationManager: navigationManager,
|
||||
|
|
@ -197,12 +198,26 @@ struct RootView: View {
|
|||
pendingURL: $pendingURL,
|
||||
appDelegate: appDelegate
|
||||
)
|
||||
|
||||
if coreContext.coreIsStarted {
|
||||
VStack {} // Force trigger .onAppear
|
||||
.onAppear {
|
||||
if let url = pendingURL {
|
||||
URIHandler.handleURL(url: url)
|
||||
pendingURL = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SplashScreen()
|
||||
}
|
||||
}
|
||||
.onOpenURL { url in
|
||||
if SharedMainViewModel.shared.displayedConversation != nil && url.absoluteString.contains("linphone-message://") {
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
}
|
||||
if coreContext.coreIsStarted {
|
||||
URIHandler.handleURL(url: url)
|
||||
} else {
|
||||
|
|
@ -230,19 +245,7 @@ struct MainViewSwitcher: View {
|
|||
let appDelegate: AppDelegate
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
if coreContext.coreIsStarted {
|
||||
selectedMainView()
|
||||
|
||||
VStack {} // Force trigger .onAppear
|
||||
.onAppear {
|
||||
if let url = pendingURL {
|
||||
URIHandler.handleURL(url: url)
|
||||
pendingURL = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
|
|
|||
|
|
@ -218,6 +218,8 @@
|
|||
"conversation_event_participant_removed" = "%@ has left";
|
||||
"conversation_event_subject_changed" = "New subject: %@";
|
||||
"conversation_failed_to_create_toast" = "Failed to create conversation!";
|
||||
"conversations_files_waiting_to_be_shared_single" = "1 file waiting to be shared";
|
||||
"conversations_files_waiting_to_be_shared_multiple" = "%@ files waiting to be shared";
|
||||
"conversation_forward_message_title" = "Forward message to…";
|
||||
"conversation_info_add_participants_label" = "Add participants";
|
||||
"conversation_info_admin_menu_remove_participant" = "Remove from the group";
|
||||
|
|
|
|||
|
|
@ -218,6 +218,8 @@
|
|||
"conversation_event_participant_removed" = "%@ a quitté la conversation";
|
||||
"conversation_event_subject_changed" = "La conversation a été renommée : %@";
|
||||
"conversation_failed_to_create_toast" = "Échec de création de la conversation !";
|
||||
"conversations_files_waiting_to_be_shared_single" = "1 fichier en attente de partage";
|
||||
"conversations_files_waiting_to_be_shared_multiple" = "%@ fichiers en attente de partage";
|
||||
"conversation_forward_message_title" = "Transférer à…";
|
||||
"conversation_info_add_participants_label" = "Ajouter des participants";
|
||||
"conversation_info_admin_menu_remove_participant" = "Retirer participant";
|
||||
|
|
|
|||
|
|
@ -85,6 +85,47 @@ struct ContentView: View {
|
|||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
VStack(spacing: 0) {
|
||||
if !sharedMainViewModel.fileUrlsToShare.isEmpty && !telecomManager.callInProgress || (telecomManager.callInProgress && !telecomManager.callDisplayed) {
|
||||
HStack {
|
||||
Image("share-network")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 26, height: 26)
|
||||
.padding(.leading, 10)
|
||||
|
||||
if sharedMainViewModel.fileUrlsToShare.count > 1 {
|
||||
Text(String(format: String(localized: "conversations_files_waiting_to_be_shared_multiple"), sharedMainViewModel.fileUrlsToShare.count.description))
|
||||
.default_text_style_white(styleSize: 16)
|
||||
} else {
|
||||
Text(String(localized: "conversations_files_waiting_to_be_shared_single"))
|
||||
.default_text_style_white(styleSize: 16)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(
|
||||
action: {
|
||||
withAnimation {
|
||||
sharedMainViewModel.fileUrlsToShare = []
|
||||
}
|
||||
}, label: {
|
||||
Image("x")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 26, height: 26)
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 40)
|
||||
.padding(.horizontal, 10)
|
||||
.background(Color.gray)
|
||||
}
|
||||
|
||||
if (telecomManager.callInProgress && !fullscreenVideo && ((!telecomManager.callDisplayed && callViewModel.callsCounter == 1) || callViewModel.callsCounter > 1)) || isShowConversationFragment {
|
||||
HStack {
|
||||
Image("phone")
|
||||
|
|
@ -111,7 +152,8 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 30)
|
||||
.frame(height: 40)
|
||||
.padding(.horizontal, 10)
|
||||
.background(Color.greenSuccess500)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
|
|
|||
|
|
@ -203,6 +203,25 @@ struct ConversationFragment: View {
|
|||
if let conv = SharedMainViewModel.shared.displayedConversation {
|
||||
cachedConversation = conv
|
||||
}
|
||||
|
||||
if !SharedMainViewModel.shared.fileUrlsToShare.isEmpty {
|
||||
var urlList: [URL] = []
|
||||
SharedMainViewModel.shared.fileUrlsToShare.forEach { urlFile in
|
||||
urlList.append(URL(fileURLWithPath: urlFile))
|
||||
}
|
||||
|
||||
FilePicker.convertToAttachmentArray(fromResults: urlList) { mediasOrNil, errorOrNil in
|
||||
if let error = errorOrNil {
|
||||
print(error)
|
||||
}
|
||||
|
||||
if let medias = mediasOrNil {
|
||||
conversationViewModel.mediasToSend.append(contentsOf: medias)
|
||||
}
|
||||
}
|
||||
|
||||
SharedMainViewModel.shared.fileUrlsToShare.removeAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ class SharedMainViewModel: ObservableObject {
|
|||
@Published var dialPlansLabelList: [String] = []
|
||||
@Published var dialPlansShortLabelList: [String] = []
|
||||
|
||||
@Published var fileUrlsToShare: [String] = []
|
||||
|
||||
@Published var operationInProgress = false
|
||||
|
||||
let welcomeViewKey = "welcome_view"
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class URIHandler {
|
|||
private static let callSchemes = ["sip", "sip-linphone", "linphone-sip", "tel", "callto"]
|
||||
private static let secureCallSchemes = ["sips", "sips-linphone", "linphone-sips"]
|
||||
private static let configurationSchemes = ["linphone-config"]
|
||||
private static let sharedExtensionSchemes = ["linphone-message"]
|
||||
|
||||
private static var uriHandlerCoreDelegate: CoreDelegateStub?
|
||||
|
||||
|
|
@ -63,6 +64,8 @@ class URIHandler {
|
|||
initiateCall(url: url, withScheme: "sip")
|
||||
} else if configurationSchemes.contains(scheme) {
|
||||
initiateConfiguration(url: url)
|
||||
} else if sharedExtensionSchemes.contains(scheme) {
|
||||
processReceivedFiles(url: url)
|
||||
} else if scheme == SingleSignOnManager.shared.ssoRedirectUri.scheme {
|
||||
continueSSO(url: url)
|
||||
} else {
|
||||
|
|
@ -113,6 +116,21 @@ class URIHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private static func processReceivedFiles(url: URL) {
|
||||
Log.info("[URIHandler] processing received files from URL: \(url.path)")
|
||||
|
||||
var urlString = url.path
|
||||
if urlString.starts(with: "//") {
|
||||
urlString = String(urlString.dropFirst(2))
|
||||
}
|
||||
|
||||
for urlFile in urlString.components(separatedBy: ",") {
|
||||
SharedMainViewModel.shared.fileUrlsToShare.append(urlFile)
|
||||
}
|
||||
|
||||
SharedMainViewModel.shared.changeIndexView(indexViewInt: 2)
|
||||
}
|
||||
|
||||
private static func continueSSO(url: URL) {
|
||||
if let authorizationFlow = SingleSignOnManager.shared.currentAuthorizationFlow,
|
||||
authorizationFlow.resumeExternalUserAgentFlow(with: url) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 56;
|
||||
objectVersion = 70;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
|
|
@ -108,6 +108,7 @@
|
|||
D73449992BC6932A00778C56 /* MeetingWaitingRoomFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */; };
|
||||
D734499B2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */; };
|
||||
D737AEEF2DA011F2005C1280 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D737AEED2DA011F2005C1280 /* Localizable.strings */; };
|
||||
D7458F392E0BDCF4000C957A /* linphoneExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D7458F2F2E0BDCF4000C957A /* linphoneExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */; };
|
||||
D748BF2E2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D748BF2D2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift */; };
|
||||
D74C9CF82ACACECE0021626A /* WelcomePage1Fragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74C9CF72ACACECE0021626A /* WelcomePage1Fragment.swift */; };
|
||||
|
|
@ -204,6 +205,13 @@
|
|||
remoteGlobalIDString = 660AAF7A2B839271004C0FA6;
|
||||
remoteInfo = msgNotificationService;
|
||||
};
|
||||
D7458F372E0BDCF4000C957A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = D719ABAB2ABC67BF00B41C10 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D7458F2E2E0BDCF4000C957A;
|
||||
remoteInfo = linphoneExtension;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
|
@ -214,6 +222,7 @@
|
|||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
660AAF7F2B839272004C0FA6 /* msgNotificationService.appex in Embed Foundation Extensions */,
|
||||
D7458F392E0BDCF4000C957A /* linphoneExtension.appex in Embed Foundation Extensions */,
|
||||
);
|
||||
name = "Embed Foundation Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
@ -321,6 +330,7 @@
|
|||
D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomViewModel.swift; sourceTree = "<group>"; };
|
||||
D737AEEE2DA011F2005C1280 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable/en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
D737AEF02DA01203005C1280 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Localizable/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
D7458F2F2E0BDCF4000C957A /* linphoneExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = linphoneExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountLoginFragment.swift; sourceTree = "<group>"; };
|
||||
D748BF2D2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountWarningFragment.swift; sourceTree = "<group>"; };
|
||||
D74C9CF72ACACECE0021626A /* WelcomePage1Fragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomePage1Fragment.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -403,6 +413,20 @@
|
|||
D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterFragment.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
D7458F3C2E0BDCF4000C957A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
|
||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||
membershipExceptions = (
|
||||
Info.plist,
|
||||
);
|
||||
target = D7458F2E2E0BDCF4000C957A /* linphoneExtension */;
|
||||
};
|
||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
D7458F302E0BDCF4000C957A /* linphoneExtension */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (D7458F3C2E0BDCF4000C957A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = linphoneExtension; sourceTree = "<group>"; };
|
||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
660AAF782B839271004C0FA6 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
|
|
@ -425,6 +449,13 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D7458F2C2E0BDCF4000C957A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
|
|
@ -568,6 +599,7 @@
|
|||
660D8A702B517D260092694D /* GoogleService-Info.plist */,
|
||||
D719ABB52ABC67BF00B41C10 /* Linphone */,
|
||||
660AAF7C2B839272004C0FA6 /* msgNotificationService */,
|
||||
D7458F302E0BDCF4000C957A /* linphoneExtension */,
|
||||
D719ABB42ABC67BF00B41C10 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -577,6 +609,7 @@
|
|||
children = (
|
||||
D719ABB32ABC67BF00B41C10 /* LinphoneApp.app */,
|
||||
660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */,
|
||||
D7458F2F2E0BDCF4000C957A /* linphoneExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1037,12 +1070,35 @@
|
|||
);
|
||||
dependencies = (
|
||||
660AAF7E2B839272004C0FA6 /* PBXTargetDependency */,
|
||||
D7458F382E0BDCF4000C957A /* PBXTargetDependency */,
|
||||
);
|
||||
name = LinphoneApp;
|
||||
productName = Linphone;
|
||||
productReference = D719ABB32ABC67BF00B41C10 /* LinphoneApp.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
D7458F2E2E0BDCF4000C957A /* linphoneExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = D7458F3D2E0BDCF4000C957A /* Build configuration list for PBXNativeTarget "linphoneExtension" */;
|
||||
buildPhases = (
|
||||
D7458F2B2E0BDCF4000C957A /* Sources */,
|
||||
D7458F2C2E0BDCF4000C957A /* Frameworks */,
|
||||
D7458F2D2E0BDCF4000C957A /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
fileSystemSynchronizedGroups = (
|
||||
D7458F302E0BDCF4000C957A /* linphoneExtension */,
|
||||
);
|
||||
name = linphoneExtension;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = linphoneExtension;
|
||||
productReference = D7458F2F2E0BDCF4000C957A /* linphoneExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
|
|
@ -1050,7 +1106,7 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1430;
|
||||
LastSwiftUpdateCheck = 1640;
|
||||
LastUpgradeCheck = 1430;
|
||||
TargetAttributes = {
|
||||
660AAF7A2B839271004C0FA6 = {
|
||||
|
|
@ -1060,6 +1116,9 @@
|
|||
D719ABB22ABC67BF00B41C10 = {
|
||||
CreatedOnToolsVersion = 14.3.1;
|
||||
};
|
||||
D7458F2E2E0BDCF4000C957A = {
|
||||
CreatedOnToolsVersion = 16.4;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "LinphoneApp" */;
|
||||
|
|
@ -1085,6 +1144,7 @@
|
|||
targets = (
|
||||
D719ABB22ABC67BF00B41C10 /* LinphoneApp */,
|
||||
660AAF7A2B839271004C0FA6 /* msgNotificationService */,
|
||||
D7458F2E2E0BDCF4000C957A /* linphoneExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
|
@ -1121,6 +1181,13 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D7458F2D2E0BDCF4000C957A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
|
|
@ -1320,6 +1387,13 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D7458F2B2E0BDCF4000C957A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
|
|
@ -1328,6 +1402,11 @@
|
|||
target = 660AAF7A2B839271004C0FA6 /* msgNotificationService */;
|
||||
targetProxy = 660AAF7D2B839272004C0FA6 /* PBXContainerItemProxy */;
|
||||
};
|
||||
D7458F382E0BDCF4000C957A /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = D7458F2E2E0BDCF4000C957A /* linphoneExtension */;
|
||||
targetProxy = D7458F372E0BDCF4000C957A /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
|
|
@ -1664,6 +1743,74 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
D7458F3A2E0BDCF4000C957A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = linphoneExtension/linphoneExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = linphoneExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = linphoneExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
D7458F3B2E0BDCF4000C957A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = linphoneExtension/linphoneExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = linphoneExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = linphoneExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
|
|
@ -1694,6 +1841,15 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D7458F3D2E0BDCF4000C957A /* Build configuration list for PBXNativeTarget "linphoneExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
D7458F3A2E0BDCF4000C957A /* Debug */,
|
||||
D7458F3B2E0BDCF4000C957A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@
|
|||
"location" : "https://gitlab.linphone.org/BC/public/linphone-sdk-swift-ios.git",
|
||||
"state" : {
|
||||
"branch" : "stable",
|
||||
"revision" : "ffedf77da711ea0f90ddd99a1785a84268413122"
|
||||
"revision" : "2d65f089792cb91c50f51dc26417c7d4c0ebb988"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
24
linphoneExtension/Base.lproj/MainInterface.storyboard
Normal file
24
linphoneExtension/Base.lproj/MainInterface.storyboard
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
18
linphoneExtension/Info.plist
Normal file
18
linphoneExtension/Info.plist
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-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>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<string>TRUEPREDICATE</string>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
113
linphoneExtension/ShareViewController.swift
Normal file
113
linphoneExtension/ShareViewController.swift
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-iphone
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
import Social
|
||||
|
||||
class ShareViewController: SLComposeServiceViewController {
|
||||
|
||||
var remainingSlots = 12
|
||||
|
||||
override func isContentValid() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
handleSharedFiles()
|
||||
}
|
||||
|
||||
override func configurationItems() -> [Any]! {
|
||||
return []
|
||||
}
|
||||
|
||||
private func handleSharedFiles() {
|
||||
guard let extensionItems = self.extensionContext?.inputItems as? [NSExtensionItem] else { return }
|
||||
|
||||
var fileURLs: [URL] = []
|
||||
let dispatchGroup = DispatchGroup()
|
||||
|
||||
for item in extensionItems {
|
||||
if let attachments = item.attachments {
|
||||
for provider in attachments {
|
||||
guard remainingSlots > 0 else { break }
|
||||
if provider.hasItemConformingToTypeIdentifier("public.item") {
|
||||
remainingSlots -= 1
|
||||
dispatchGroup.enter()
|
||||
provider.loadFileRepresentation(forTypeIdentifier: "public.item") { urlFile, error in
|
||||
if let url = urlFile {
|
||||
if let urlSaved = self.copyFileToSharedContainer(from: url) {
|
||||
fileURLs.append(urlSaved)
|
||||
}
|
||||
}
|
||||
dispatchGroup.leave()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatchGroup.notify(queue: .main) {
|
||||
if !fileURLs.isEmpty {
|
||||
self.openParentApp(with: fileURLs)
|
||||
} else {
|
||||
self.extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func openParentApp(with fileURLs: [URL]) {
|
||||
let urlStrings = fileURLs.map { $0.path }
|
||||
let joinedURLs = urlStrings.joined(separator: ",")
|
||||
|
||||
let urlScheme = "linphone-message://\(joinedURLs)"
|
||||
if let url = URL(string: urlScheme) {
|
||||
var responder: UIResponder? = self
|
||||
while responder != nil {
|
||||
if let application = responder as? UIApplication {
|
||||
application.open(url)
|
||||
break
|
||||
}
|
||||
responder = responder?.next
|
||||
}
|
||||
}
|
||||
|
||||
self.extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
|
||||
func copyFileToSharedContainer(from url: URL) -> URL? {
|
||||
let fileManager = FileManager.default
|
||||
guard let sharedContainerURL = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.org.linphone.phone.linphoneExtension") else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let destinationURL = sharedContainerURL.appendingPathComponent(url.lastPathComponent)
|
||||
|
||||
do {
|
||||
if fileManager.fileExists(atPath: destinationURL.path) {
|
||||
try fileManager.removeItem(at: destinationURL)
|
||||
}
|
||||
|
||||
try fileManager.copyItem(at: url, to: destinationURL)
|
||||
return destinationURL
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
linphoneExtension/linphoneExtension.entitlements
Normal file
10
linphoneExtension/linphoneExtension.entitlements
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-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>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.linphone.phone.linphoneExtension</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Loading…
Add table
Reference in a new issue