使用 Swift 構建一個 iOS 的郵件應用

jopen 10年前發布 | 19K 次閱讀 Swift Apple Swift開發

使用 Swift 構建一個 iOS 的郵件應用

在前幾個月內,我一直在做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球:

  1. 顯示Inbox中未讀thread

    </li>

  2. 當你搖動手機,標記thread為已讀并顯示新的thread

    </li> </ol>

    使用 Swift 構建一個 iOS 的郵件應用

    (譯者注:文中的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</pre>

    由于我們已經創建了一個線程供應者,我們就可以使用它的條目數組來存放我們的視圖. 供應者不會同步獲取結果集, 所以我們需要實現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);}</pre>

    標記為已讀

    在我們的 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 學習一下更多關于在郵件上層創建美觀大方應用的知識.

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!