用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球:

  • 显示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学习一下更多关于在邮件上层创建美观大方应用的知识.

(0)

相关推荐

  • iOScollectionView广告无限滚动实例(Swift实现)

    今天公司里的实习生跑过来问我一般App上广告的无限滚动是怎么实现的,刚好很久没写博客了,就决定写下了,尽量帮助那些处于刚学iOS的程序猿. 做一个小demo,大概实现效果如下图所示: 基本实现思路: 1. 在你需要放置无限滚动展示数据的地方把他的数据,在原本的基础上把你要展示的数据扩大三倍.(当然扩大两倍也是可以的,三倍的话,比较好演示) // MARK: - 设置数据源 func collectionView(_ collectionView: UICollectionView, number

  • Swift自定义iOS中的TabBarController并为其添加动画

    自定义TabBarController 有时候默认的TabBarController不能满足我们的开发需求,比如你想用彩色的图标,系统却只调用图标的轮廓,所以我们需要自己定义一下TabBar. 方法一:修改TabBarController中的TabBar 新建 CustomTabBarController 类继承自 UITabBarController,并在Storyboard中设置: 首先自定义 tabBar 的背景,在 viewDidLoad() 方法中添加: 复制代码 代码如下: // 用

  • swift在IOS应用图标上添加提醒个数的方法

    在应用图标右上角添加消息数提醒,可以很方便的告知用户该应用中有无新消息需要处理.下面用xcode 7.3.1来简要说明一下如何用swift语言进行此功能的实现. 1.修改 AppDelegate.swift // // AppDelegate.swift // RainbowDemo // // Created by Jackwang on 16/8/17. // Copyright © 2016年 Jackwang . All rights reserved. // import UIKit

  • Swift实现iOS应用中短信验证码倒计时功能的实例分享

    在开始之前,我们先来了解一个概念 属性观测器(Property Observers): 属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外. 可以为属性添加如下的一个或全部观察器: willSet在新的值被设置之前调用 didSet在新的值被设置之后立即调用 接下来开始我们的教程,先展示一下最终效果: 首先声明一个发送按钮: 复制代码 代码如下: var sendButton: UIButton! 在viewDidLoad方法中给发

  • 使用Swift实现iOScollectionView广告无限滚动效果(DEMO)

    今天公司里的实习生跑过来问我一般App上广告的无限滚动是怎么实现的,刚好很久没写博客了,就决定写下了,尽量帮助那些处于刚学iOS的程序猿. 做一个小demo,大概实现效果如下图所示: 基本实现思路: 1. 在你需要放置无限滚动展示数据的地方把他的数据,在原本的基础上把你要展示的数据扩大三倍.(当然扩大两倍也是可以的,三倍的话,比较好演示) // MARK: - 设置数据源 func collectionView(_ collectionView: UICollectionView, number

  • iOS瀑布流的简单实现(Swift)

    这段时间突然想到一个很久之前用到的知识-瀑布流,本来想用一个简单的方法,发现自己走入了歧途,最终只能狠下心来重写UICollectionViewFlowLayout.下面我将用两种方法实现瀑布流,以及会介绍第一种实现的bug. <1>第一种 效果图如下所示: 这种实现方法的思路: 1)首先调用随机函数,产生随机高度,并把它保存到数组中 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection

  • Swift 共享文件操作小结(iOS 8 +)

    前言 适用于 iOS 8 + 本地共享文件列表 正文 一.准备 1.1 默认 App 的文件共享是关闭的,需要在 plist 中设置启用: Application supports iTunes file sharing 设置为 YES 启用后把设备连接到 iTunes 上,在 iTunes 应用里的文件共享就能看到你的 App 了(如果看不见需要断开重新拔插一下数据线),可以拷贝一些视频进去,便于测试. 1.2 导入库 Photos.framework AVKit.framework 用于播放

  • iOS开发中Swift3 监听UITextView文字改变的方法(三种方法)

    在项目中使用文本输入框出UITextField之外还会经常使用 UITextView ,难免会有需求监听UITextView文本框内文本数量.下面介绍在swift3中两种常用方式 方式一: 全局通知 1.注册通知 在合适位置注册监听UITextView文本变化的全局通知 //UITextView 监听开始输入的两种方法 //方法一:通知 NotificationCenter.default.addObserver(self, selector: #selector(ComposeVC.textV

  • IOS swift3.0 下闭包语法整理

    IOS swift3.0 下闭包语法整理 一.闭包的概念 有oc基础的都知道,闭包其实是oc里面的block,语法格式不一样,但作用是一样的.主要是用于callBack(异步回调)或者两个类之间的通信.它的本质一个函数,一个可执行的代码块,只是这个函数是没有名字的,也就是匿名函数.你也可以把他看作如 int.float一样,是一种数据类型,一种可以作为参数传递的数据类型. 二.基本语法 1.闭包的声明 //定义一个求和闭包 //闭包类型:(Int,Int)->(Int) let add:(Int

  • 使用Swift代码实现iOS手势解锁、指纹解锁实例详解

    一.手势密码 1. 1.1.用UIButton组成手势的节点. 1.2.当手指接触屏幕时,调用重写的 touchesBegan:withEvent方法(在touchesBegan里调用setNeedsDisplay,这样就会自动调用drawRect方法). 1.3.当手指在屏幕上滑动时,调用重写的touchesEnded:withEvent方法. 这两个方法执行的操作是一样的:通过locationInView获取 触摸的坐标,然后用 CGRectContainsPoint 判断手指是否经过UIB

  • IOS Swift 开发QRCore(二维码)实例详解

    1.搭个界面 2.写代码 // // ViewController.swift // GeneratorQRCode // // Created by targetcloud on 2016/12/3. // Copyright © 2016年 targetcloud. All rights reserved. // import UIKit class ViewController: UIViewController { @IBOutlet weak var qrImg: UIImageVie

  • 使用Swift实现iOS App中解析XML格式数据的教程

    在IOS中,提供了一套解析XML数据的API.其实也很简单,就是NSXMLParser和NSXMLParserDelegate. 可以直接指定到XML的URL去实例化NSXMLParser 复制代码 代码如下: public convenience init?(contentsOfURL url: NSURL) 解析文件,返回的是一次解析的结果 复制代码 代码如下: NSXMLParser.parse() -> Bool 监听解析节点的属性 复制代码 代码如下: NSXMLParserDeleg

  • Swift使用WKWebView在iOS应用中调用Web的方法详解

    自从iOS8开始,Apple引入了WKWebView欲代替UIWebView.相比而言,WKWebView消耗内从更少,功能也更加强大.让我们来看看WKWebView怎么使用吧! 0.初始化 (1)首先需要引入WebKit库 复制代码 代码如下: #import <WebKit/WebKit.h> (2)初始化方法分为以下两种 复制代码 代码如下: // 默认初始化 - (instancetype)initWithFrame:(CGRect)frame; // 根据对webview的相关配置,

  • iOS swift 总结NavigationController出现问题及解决方法

    IOS swift 总结NavigationController出现问题及解决方法 最近用Swift语言做了一些iOS项目,颇有些心得,记下一些深刻的问题造福自己,服务大家 1.以NavigationController做为容器后状态栏的字体颜色就会不在受系统的控制,要在NavigationController中的根ViewController中设置方可生效,代码如下: self.navigationController!.navigationBar.barStyle = UIBarStyle.

随机推荐