2019年7月17日

iOS: Share Extension

Share Extension介紹

Share Extension介紹

Extension介紹

Extension?

為iOS提供的功能,讓APP之間能夠資料分享

Extension有哪些類型?

常見的類型如下:

  • Today Extension
  • Share Extension
  • Action Extension etc...

Extension在App的角色定位?

  • Extension是一個App的附加功能,因此,想要有extension功能,必須依附在一個主要的project App底下,而這個被依附的Project App稱之為Containing app
  • Extension的存在會隨著App的安裝或移除決定

Share Extension在XCode工作環境

APPLE提供的extension架構圖

  • Host app:user透過哪個app(可以是本機照片或本機檔案)分享檔案到我的app,而透過的這個app稱之
  • App extension:由extension負責接收從Host app傳進來的檔案
  • Containing app:主要開發的project app,負責將資料如何對外呈現
  • Shared resources:extension與Containing app透過蘋果提供的一個group space,透過這個space來讓Containing app存取extension所接收到的

Share Extension介紹

使用情景

一般使用的情況會是使用者想要分享網頁文章或照片到FB、IG上,而開發者就是透過自己定義Share Extension功能,讓使用者也能過分享到自己定義的APP上

決定Share Extension出現在分享清單中的關鍵

圖中就是share extension功能所呈現的畫面,而ShareExtension則是我開發share extension取的名字,當然你也可以自行取名。如果是以最上面第一張圖來看的話,這邊呈現的名稱就會是hostShareExt

要讓share extension出現在分享畫面的話,就要看APP允許接受什麼類型的內容,可選擇支援類型如下:

  • 可經由share extension自己目錄底下plist檔,調整欄位NSExtensionNSExtensionAttributes 改為Dictionary Type ➔ 新增下列欲選取的key
    • NSExtensionActivationSupportsAttachmentsWithMaxCount
    • NSExtensionActivationSupportsAttachmentsWithMinCount
    • NSExtensionActivationSupportsFileWithMaxCount
    • NSExtensionActivationSupportsImageWithMaxCount
    • NSExtensionActivationSupportsMovieWithMaxCount
    • NSExtensionActivationSupportsText
    • NSExtensionActivationSupportsWebURLWithMaxCount
    • NSExtensionActivationSupportsWebPageWithMaxCount

  • 例如:若我只想允許接收分享網頁連結的類型,就只新增NSExtensionActivationSupportsWebURLWithMaxCount屬性並設定其數量
  • NSExtensionActivationSupportsAttachmentsWithMaxCount:附件最多數量限制。附件類型包括File、Image、movie,可以單一、可以複選,但總數量不得超過指定數量

提供的預設介面

會有一個預設畫面、一個Cancel按鈕、一個Post按鈕

提供的實作方式

一開始主要提供基本的三個函式讓我們實作:

  • isContentValid
  • didSelectPost
  • configurationItems

extension收到檔案後,如何傳給Containing App?

蘋果提供一項叫App Groups的服務,允許開發者能夠在自己的App之間傳遞資料,可透過下列三種方式

  • UserDefaults
  • FileManager
  • CoreData

因此,開發者使用哪個指令操作,取資料就需要鍵值或路徑,而這個相對於在APP Group服務底下稱為group name,這也是開發者可以自行定義的

建立與啟用App Group

1.新建專案

2.建立Target

3.選擇Share Extension

4.建立完後,到Project的左側欄位,選擇Capabilities,開啟App Group功能,Container App(EX: ShareExtensionTest)與extension端(EX: ShareExtension)都要啟用。

5.點選+號,新增自己的group name

☝︎取名建議:結尾名稱跟ContainerApp名稱一致,如:group.XXX.XXX.yourContainerAppName,否則可能會有未知的錯誤

6.完成,可以看到XCode工作環境會多一層extension端的目錄。

實作時會遇到的問題

發生情況:沒有權限

extension端想要對接收到的檔案的url做操作(如:try Data(contentsOf: url)),都會發生

Code = 257 "The file "XXX.JPG" couldn’t be opened because you don’t have 
permission to view it.
這邊我列出覺得可能比較有幫助的解決方法:

解決方案 1

這個問題跟我的一模一樣,可惜他的解法對我無效

https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E6%95%99%E5%AE%A4/share-extension-couldnt-be-opened-because-you-don-t-have-permission-to-view-it-error-handling-88f7c2aea466

解決方案 2

這個問題跟我遇到的狀況不一樣,但也有點相似,留言串很多人提供不同的方法,逐一試之也都無效

https://stackoverflow.com/questions/24924809/the-file-myapp-app-couldnt-be-opened-because-you-dont-have-permission-to-vi/25365372

解決方案 3

最後是這個方法能解決我的問題,在對URL操作的前後加上兩段code

fileURL.startAccessingSecurityScopedResource()
...
fileURL.stopAccessingSecurityScopedResource()

https://stackoverflow.com/questions/36355105/the-file-couldn-t-be-opened-because-you-don-t-have-permission-to-view-it?rq=1

解決的案例

名詞解釋,以開發者角度而言:

  • Extension:接收從其他App分享過來的檔案,以下簡稱Ext
  • Containing App:將接收到的檔案做怎樣的呈現,以下簡稱CA

Case 1

  • 操作端:Ext
  • 沒有權限的操作:try? Data(contentsOf: data as! URL)
  • 檔案類型:圖片

Case 2

  • 操作端:Ext
  • 沒有權限的操作:

let tmpData = try? Data(contentsOf: data as! URL)
let data = try? propertyListEncoder().encode(tmpData!)
  • 檔案類型:圖片、Zip檔

Case 3

  • 操作端:CA
  • 沒有權限的操作:

if let shareUrl = FileManager.default.containerURL(forSecurityApplication
GroupIdentifier: yourSuiteName) {
  let imagePath = shareUrl.appendingPathComponent("test.JPG")
  let image = UIImage(contentsOfFile: imagePath.path)
}
  • 檔案類型:圖片

沒有留言:

張貼留言