UIActivityViewController

這些話寫在前面⋯⋯

最近在開發的產品需要加入「分享」的功能,
希望將一些資訊及圖片分享到其他 App 或平台上;
這篇文章會先點出需求,再逐一闡述開發的過程。

需求

  • Facebook 分享 hash tag 及圖片
  • 其餘分享文字及圖片和網址

實作

我們利用 UIActivityViewController 來呈現分享的選單,並將分享的內容塞入 activityItems: [Any] 之中;
applicationActivities 則設為 nil,並沒有要客製 activity
若沒有需要依照不同類別做出不同的判斷,我們可以將內容放置進去;
像是 URL、String、UIImage等等。
而幾個特點要注意一下:

Facebook:

  • String 只支援一個 hash tag(像是:"#Archie"),若超過或其他一般文字則不會顯示
  • 有網址的話,就會顯示連結;意思是圖片和連結無法同時出現,會優先顯示連結

iMessage

  • 若 String 裡頭的時間格式為 dd/MM/yyyy HH:mm 則可以點擊,並加入行事曆
  • 圖片會以另一則訊息傳送
  • 網址會以縮圖顯示(就如一般訊息收到的邏輯)

依照類別提供不同內容

首先,我們可以先看 UIActivityType

extension UIActivityType {
    @available(iOS 6.0, *)
    public static let postToFacebook: UIActivityType
    @available(iOS 6.0, *)
    public static let postToTwitter: UIActivityType
    @available(iOS 6.0, *)
    public static let postToWeibo: UIActivityType // SinaWeibo
    @available(iOS 6.0, *)
    public static let message: UIActivityType
    @available(iOS 6.0, *)
    public static let mail: UIActivityType
    @available(iOS 6.0, *)
    public static let print: UIActivityType
    @available(iOS 6.0, *)
    public static let copyToPasteboard: UIActivityType
    @available(iOS 6.0, *)
    public static let assignToContact: UIActivityType
    @available(iOS 6.0, *)
    public static let saveToCameraRoll: UIActivityType
    @available(iOS 7.0, *)
    public static let addToReadingList: UIActivityType
    @available(iOS 7.0, *)
    public static let postToFlickr: UIActivityType
    @available(iOS 7.0, *)
    public static let postToVimeo: UIActivityType
    @available(iOS 7.0, *)
    public static let postToTencentWeibo: UIActivityType
    @available(iOS 7.0, *)
    public static let airDrop: UIActivityType
    @available(iOS 9.0, *)
    public static let openInIBooks: UIActivityType
    @available(iOS 11.0, *)
    public static let markupAsPDF: UIActivityType
}

而我們可以自行創建一個類別來實作 UIActivityItemSource
不過因為它是屬於 NSObjectProtocol,所以得一併繼承 NSObject
例如,我現在要寫一個給 Facebook 以及其他類分別不同 String 的 ItemSource:

class ActivityStringItemSource: NSObject, UIActivityItemSource {
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return ""
    }
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType?) -> Any? {
        guard let type = activityType else {
            return ""
        }
        switch type {
        case UIActivityType.postToFacebook, UIActivityType.postToTwitter:
            return "#Archie"
        default:
            return "Archie 的 UIActivityViewController 實作心得 #Swift"
        }
    }
}

並在創建 UIActivityViewController 的時候,宣告進去:

 let activityViewController = UIActivityViewController.init(activityItems: [ActivityStringItemSource()], applicationActivities: nil)

這樣便會依照不同的 UIActivityType 來給予特定的 String 內容;
而當然你也可以建立一個有關 URLUIImage 相關的 UIActivityItemSource
在分享出去的時候,便可以決定讓 Facebook 僅分享圖片,而在其他地方則帶有連結。

3D Touch

這些寫在前面⋯⋯

最近剛從 iPhone 6 Plus 晉升到 iPhone X,其中一項硬體差異便是「3D Touch」;
而這也讓我花了一些時間,來加入 3D Touch 的相關功能開發。
這篇文章前半部會寫 3D Touch 在主畫面上的一些差異,
後半部才會補上 Swift 的相關寫法。
 

iOS 版本:11.1.1(15B150)

首先,先將 App 分成有 Today extension 以及沒有 Today extension 的這兩種:

郵件 - 有 Today extension

鬧鐘 - 沒有 Today extension

從這兩張圖的比較下,我們可以得知在 iOS 11.1.1 之中,
若有 Today extension 的 App,在 3D Touch 的快捷鍵之中,
會顯示 Today extension,而反之則僅會露出原本的 App icon。
另一點是,快捷鍵的順序是依 index 越小則越靠近 App icon
所以使用者將 App 放置在畫面上半部或下半部會影響由上到下的順序。

鬧鐘 - 放置畫面下半部

所以便不必太在意快捷鍵的排序問題,包含 Today extension 順序也是。

接著來看看程式碼⋯⋯

畫面上的快捷鍵,在 iOS 裡頭是 UIKit 裡頭的 UIApplicationShortcutItem
它提供了一種建構的方式:

其中 icon 的部分要使用 UIApplicationShortcutIcon 來建構,
而它有內建的 UIApplicationShortcutIconType 可以使用;
或者從你自行提供的 templateImageName 去抓取也行,
不過一個重點是它會使用 template 模式呈現,所以你無法在圖片中自行決定色彩。
再來再設定 UIApplication.shared.shortcutItems 即可完成新增 3D Touch 快捷鍵的畫面。
一個小小重點是,只要處理有關 UI 方面的設置,都需要在 Main thread 下完成。
 

畫面上有了快捷鍵之後⋯⋯

我們需要在 AppDelegate 裡頭攥寫點擊後的動作,

透過剛剛建構時,所定義的不同 shortcutItem.type 來決定要做些什麼事情,
這部分就有點像使用者點推播進來後要怎麼做後續一樣,
整體大致上就是這樣!
 

未完待續⋯⋯

還沒研究在 App 裡頭的 3D Touch 內容,待之後開發有需求會再補在這篇!

失業給付 + 提早就業獎金

這些話寫在前面⋯⋯

由於和上一間公司的工作方式處不來,而對方決定以資遣的方式來處理,
故便在六月中解鎖了「領取資遣證明」的成就。
 

知道對方要資遣你時,先確認幾件事

  • 近三年內勞保是否有投保滿一年
  • 對方是否通報勞保局
  • 對方是否會開立資遣證明

至於對方是用什麼條款開立,個人是認為沒什麼差異。
 

若上述的答案皆為「是」的話,你可以⋯⋯

申請「失業給付」,而這篇文章會以我申請的流程為主,並以流水帳的方式呈現。
 

2017/06/14(三)

對方中午開立資遣證明,並在上方註明最後工作日為 2017/06/16(五),
也就是會支薪到週五的意思;
而上方會寫上這個月將依比例給付多少薪資以及資遣費計算結果。
 
當天,便電話聯繫板橋就業服務站,詢問相關資訊和預約失業給付申請;
而對方有提供給我幾項重點:

  • 失業給付申請得在最後工作日的隔一天後,以我的案例是 2017/06/17(六)以後申請
  • 可以透過電話進行預約申請,並建議於預約時間前十分鐘先去填寫書面資料
  • 記得帶預計讓失業給付入帳的銀行簿子影本,或帶正本去影印
  • 攜帶證件及資遣證明正本
  • 新北市的就業服務站失業認定無需當日現場報到,而台北市則需要

2017/06/19(一)

上午便到板橋就業服務站填寫書面資料,並和服務人員進行後續動作;
期間對方和我閒聊一些工作上的事,以及職業選擇之類的,
並提供一些就業的資訊和講座。
流程上會需要在 14 天內,進行兩次以上的「找工作」;
對方會要求要上「台灣就業通」(或是其他政府機關提供的找工作平台),
去申請面試,並於兩週後和服務人員回報狀況。
回報的內容是一張表,需要填寫完之後送回就業服務站,也就是「第一次失業認定」;
板橋就業服務站可以透過郵寄的方式,將表格回寄,並打電話給當時接洽的人員即可,
而台北市則需要再跑一趟親送。
 

2017/07/03(一)

打電話向服務人員確認狀況,並告知 14 天內沒有工作(以勞保投保記錄為主),
請對方將第一次認定的申請書送到勞保局,而後續他們會繼續處理。
 

2017/07/04(二)

持讀卡機到勞保局網頁,以自然人憑證查詢相關進度和資訊;
這邊建議下載「勞保局行動服務」,並進行「個人查詢」的裝置認證,
認證完後,之後都可以透過此 App 查詢,無需再用讀卡機進行登入。
 

2017/07/12(三)

核付通過,並會在 3 至 5 個工作天匯款至當初提供的銀行戶頭之內。
 

2017/07/17(一)

收到第一個月的失業給付,而若還未找到工作,則每個月需要再進行認定;
不過我已經有在工作,故沒有進行後續的失業給付申請認定。
 

找到工作後,接下來呢⋯⋯

當時在申請失業給付時,服務人員會告知「提早就業獎金」的申請規則和獎金計算方式:
為尚未領取失業給付金額(以我來說,便是 5 個月的失業給付金額) x 50% 一次性發放。
 

2017/10/05(四)

使用讀卡機到勞保局網頁線上申請「提早就業獎金」,兩分鐘內點選完後送出。

2017/11/01(三)

核付通過,並會在 3 至 5 個工作天匯款至「提早就業獎金」所申請的銀行戶頭之內。

2017/11/06(一)

提早就業獎金入帳,並附上「勞保局行動服務」的就保給付截圖:

 

這些寫在最後⋯⋯

得知要被資遣的當下其實多少都會覺得失落,但這其實也只是離職的其中一種方式;
雙方都知道彼此不是對方想要的,不論是你不想做這份工作或是他和你處不來,
只是開口的不是勞方,而是資方主動提起罷了。
記得要對方開立相關證明文件,去申請給付並好好找下一份工作,
而被資遣也沒什麼覺得好丟臉的,合則來,不合則散而已。
 
提供給需要的朋友們!
成就解鎖:「第一次被資遣就上手」
也謝謝提供相關資訊的阿寬