用Swift構建一個簡單的iOS郵件應用的方法_Swift

來源:互聯網
上載者:User

在前幾個月內,我一直在做InboxKit的研究,它是關於Inbox平台的IOS SDK。Inbox為和郵件資料的互動提供高層API,使得你可以忽略IMAP,Exchange,MIME的解析以及thread探測(當然還有很多其他事情...),並使你致力於完成富有創意的APP的創作上。我們的目標很簡單:儘可能地打造一個優雅的,跨供應商的郵件應用。畢竟,它很難。

在Objective-C中,InboxKit使得建立郵件體驗變得很輕鬆,那麼,Swift又如何呢?Swift在WWDC後已正式被IOS社區所採納,我認為以後的SDK設計肯定會包括既有Objective-C又有Swift寫的範例。

我們的第一個Swift例子,我想寫一個簡單的app,它就像一個魔幻8球:

  •     顯示Inbox中未讀thread
  •     當你搖動手機,標記thread為已讀並顯示新的thread

(譯者註:文中的thread並不是線程的意思,在論壇中的一個文章叫thread,回複叫post.這裡可理解為一封郵件)

在 Swift 中使用 Objective-C SDK

InboxKit有6000行Objective-C代碼,我們還不打算把他們都轉換成Swift。為了編譯我們的Swift郵件應用,我更新了open-source SDK,包含了“Xcode 6 自訂架構“。自訂架構是Xcode6的新特色-支援第三方架構的建立和分發。當DEFINES_MODULE標誌設定為可用時,自訂架構會自動為Swift準備Objective-C模組的標頭檔。在Swift編譯時間,它會讀取這個模組標頭檔,把Objective-C的類和方法映射到Swift。

Cocoa Touch架構套件含這個SDK之後,在Swift中使用很簡單。比如我建立了一個新的Swift應用,只需要把這個SDK拖入工程中,然後在root view controller中添加import InboxKit。

Xcode 6 自訂架構非常棒, 可是目前只有Xcode 6和iOS 8支援. 如果你正在開發一款應用程式, 你仍然可以選擇pod InboxKit。

查看郵件

InboxKit 讓我們從Inbox同步作業引擎擷取郵件資料變得簡單起來。我們執行個體化一個 INThreadProvider ,以此展示來自我們郵箱帳號的線程,並且具象化需要的資料。供應者模型 是InboxKit的一個核心概念: 他們被用於擷取線程,資訊,連絡人和更多東西的集合 。供應者有點類似於Core Data中的 NSManagedObjectContext 和 YapDatabase的視圖——他們把複雜的東西封裝在內部,只是暴露出一個結果集,這個結果集是基於你提供的配置。 在InboxKit,供應者從本地SQLite store拉取快取資料,同時,讓對於Inbox API 的詢問變得透明。

我們的應用將展示來自Inbox的未讀線程,每次一個,所以我們這樣定義線程供應者:

 

複製代碼 代碼如下:
var provider:INThreadProvider! = namespace?.newThreadProvider();
provider.itemFilterPredicate = NSComparisonPredicate(format: "ANY tagIDs = %@", INTagIDInbox)
provider.itemSortDescriptors = [NSSortDescriptor(key: "lastMessageDate", ascending: false)]
provider.delegate = self
 
self.threadProvider = provider


由於我們已經建立了一個線程供應者,我們就可以使用它的條目數組來存放我們的視圖. 供應者不會同步擷取結果集, 所以我們需要實現INModelProviderDelegate協議並監聽更新. 當新的線程通過以下方式被建立的時候,供應者會調用-providerDataChanged 方法,這些建立新線程的方式包括:1.從緩衝從擷取 2.通過API載入 3.(某個時間)通過網路資料包被推送到應用. 實現協議確保了我們的應用總是顯示最新的資料.

還有其他一些代理方法,比如 providerDataAltered:它讓基於UICollection或者
UITableView建立信箱使用者介面變得更簡單,同時可以使用各種插入刪除動畫效果.但是目前,我們繼續看一些基礎的東西.
 

複製代碼 代碼如下:
func refreshInterface() {
    var items = self.threadProvider!.items
 
    if items.count == 0 {
        // display empty state
        self.subjectLabel.text = "No unread threads!"
        self.snippetLabel.text = ""
        self.participantsLabel.text = ""
        self.dateLabel.text = ""
    }
 
    if let thread = items[0] as? INThread {
        // display the thread
        self.subjectLabel.text = thread.subject
        self.snippetLabel.text = thread.snippet
        self.dateLabel.text = formatter.stringFromDate(thread.lastMessageDate);
 
        ....
    }}func providerDataChanged(provider: INModelProvider!) {
    self.refreshInterface()}func provider(provider: INModelProvider!, dataFetchFailed error: NSError!)  {
    self.displayError(error);}


標示讀取

在我們的 swift 樣本程式中,我們要在使用者搖動手機的時候,把當前線程標示讀取,並且顯示一個新的線程。用InboxKit,標示讀取是非常簡單的。
 

複製代碼 代碼如下:
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent!) {
    if (motion == UIEventSubtype.MotionShake) {
        var items = self.threadProvider!.items
        if let thread = items[0] as? INThread {
            thread.markAsRead()
        }
    }}

在後台,-markAsReadqueues這個方法使新的API動作進入隊列,通過這種行為來從線程中移除未讀標籤。 INThread對象和本機存放區的資料會被立刻更新,但是這個動作將會在手機上排隊,直到可以建立
串連。如果伺服器拒絕這次的動作,那麼本地的資料也會復原。

我們不需要重新整理我們的線程供應者-我們的工作已經完成!如果當前線程被標示讀取,那麼它就不再需要滿足我們線程供應者結果集的標準.供應者會自動
匹配它的內容,並且調用providerDataChanged方法,我們實現的代理方法將會重新整理我們顯示,來展現新集合中的第一個線程。

接下來的步驟

好了! 只用了幾十行代碼,我們就建立了一個樣本程式,它可以從我們的收件匣一條條的擷取線程,並且讓我們標示讀取.現在它僅僅需要點動畫和潤色.你可以從這裡查看demo的源碼:
: SwiftEightBall Sample App

我們僅僅接觸了InboxKit的一些淺顯的東西.在IOS SDK的上層建立我們的swift應用,這意味著我們需要為模型擷取本地類的支援,比如線程和通訊錄,
以及因為支援延時線程和訊息動作的SQLite而變得更強大的離線緩衝.
看看iOS SDK documentation 學習一下更多關於在郵件上層建立美觀大方應用的知識.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.