Swift Talk #09 Q&A

这一集中我们回答一下过去几周中我们收到的问题,涵盖了网络,table views,栈视图,App类和测试。

这一集不一样,在于这是用于回答问题的。我们想知道你们是否喜欢,如果你有意见反馈的话,及时给我们发邮件。

存储验证信息

第一个问题,当你发一个网络请求的额时候,你在哪里存储验证信息。那是关于网络的那集,我们用Resource结构体来展示网络层。在很多案例中,我们必须给几乎每个请求使用验证token,因为大多数终端是被验证的。因此需要把token放到Webservice类里。

final class Webservice {
    var authenticationToken: String?

    // ...
}

然后我们修改load方法中的网络请求,把token当做http header传进去。

如果业务逻辑中区分验证和非验证的请求很重要,可以把token放到Resource中。

HTTP头

下一个问题:你在哪里添加HTTP头,头作为Content-Type,也关联到你是如果解析resource?一个像Content-Type的头放到Resource结构体中是很好的,这就在终端中明确了。举个栗子,我们可以增加一个叫做headers的字典。

struct Resource<A> {
    let url: URL
    let method: HttpMethod<Data>
    let parse: (Data) -> A?
    let headers: [String: String]
}

我们也可以给header添加一个单独的属性。

struct Resource<A> {
    let url: URL
    let method: HttpMethod<Data>
    let parse: (Data) -> A?
    let contentType: String?
}

拥有headers字典是更宽泛的,这也更加灵活。我们可以修改我们的JSON数据源来自动的设置Content-Type或者Accept-Type.比如我们想要接收XML我需要不同的解析方法,并且我们可以通过给Resource增加另外的构造器来解析方法和自动匹配Content-Type.

我们甚至可以结合着两个问题,在我们WebService的load方法中,我们可以增加两个header,一个是明确的Resource的header还有一个是其他所有数据源的header。

多种cell类型

下一个问题:如何扩展Generic Table View Controllers视频集中的方法使同一个tableView中处理不同的cell类型。

首先,我们认为使用protocol会简单,但是我们在实际中使用,这显得并不容易。我们的结论是这是可能的,但是我们的方法并没有像泛型table view Controller给一个单独的cell类型好用。举个栗子,一个简单的解决方案有一个大的缺点:我们需要把强制转换从我买的table View controller(the library)中移到配置闭包中(使用回调的地方)。现在在tableView(cellForRowAt:),我们把我买的cell转成正确的类型让configue闭包调用正确的cell类型。

无论我们怎么解决这个问题,我们总是以拖鞋收场。我们没找到一个好的解决方案,如果有人发现,请告诉我们。

给ContentElement增加UITextView支持

另一个问题:在Stack Views with Enums视频集中,如果你想支持一个textView,如何处理这些闭包?因为一个textView有多个回调闭包。除非我们只有一个回调,我们可以用和.button相似的方法,但是在有多个回调的时候怎么办?

首先,ContentElement方法我们为了方便创建,所以这也许不是解决这个问题最好的工具。

其次,我们也可以给枚举增加一个自定义案例。这种方式,我们可以使用任何栈里面的视图并且我们传入一个完全配置好的UIView的子类。这让我们有更多复杂的视图和这些方便的枚举值一起用。

enum ContentElement {
    case label(String)
    case button(String, () -> ())
    case image(UIImage)
    case custom(UIView)
}

第三,我们也可以给textView增加一个特定的情况。为了保持所有的回调代理被检验,我们可以先把他们单独拎出来。

enum ContentElement {
    case label(String)
    case button(String, () -> ())
    case image(UIImage)
    case textView(String, didChange: (String) -> (), didBeginEditing: () -> ())
}

这很快变得不方便。然后我们可以在枚举中有一个单独的回调来管理这些事件,给每个事件用一个案例。

enum TextViewEvent {
  case didChange(String)
  case didBeginEditing
  case openURL(URL)
}

enum ContentElement {
    case label(String)
    case button(String, () -> ())
    case image(UIImage)
    case textView(String, (TextViewEvent) -> ())
}

顺便说一下,我们也可以在其他回调的数目不定的情况使用这个方法,比如在一个view Controller中,像我们在Connecting View Controllers视频集中描述的那样。

自定义UIStoryboardSegue子类

下一个问题:是否在Connnecting View Controllers中使用App类好的?如果我们增加一些功能的话,这会变得复杂。一个可能方法是创建UIStoryboaedSegue的子类,就像Andy Matuschak的Refactor the Mega Controller讲解中说的。除了把这些所有逻辑放到App类中,他把很多逻辑放到了segues中。那样的话这就不在view Controller中了。

这个问题有两个部分。首先我们必须决定是否要使用故事版。在我们的案例中,我们决定不使用故事版,然后我们使用了变得比较臃肿的app类。这确实是一个问题,但是这应该也很容易分解成多个类。

第二个部分是我们从来没有在故事版中尝试自定义的segue子类。然而当我们使用故事版时这好像是一个敏感的方法。并没有一个正确的方式。我们的解决方案是多实践多创新,这对于我们的使用的案例确实很有用。

故事版,Nib还是纯代码

这是我们得到的一个关联的问题:我们是应该用故事版,Nib还是纯代码呢?我们无法回答。这些方式我们在过去的项目中都用过,都好用。就去选择适合你和你的项目的方式。这三种方式都需要你小心的保持你代码的可维护性并持续重构。

测试

有很多问题是关于测试的:我们应该测试什么?我们测试应该有多少?什么才是最好的方式。又一次这个我们无法回答。我们自己使用不同的方式。曾经在一个Rails客户端项目,我们使用BDD并且很好用。一旦我们交付了这个项目,另一个人可以直接开始工作而不需要多很多时间来转换代码基础。

我们也有一些视频集中使用了TDD的方式来开发。在那些特定的案例中,折让开发更快更简单。有很多其他部分的app,我们只能手动测试。在很多项目中,我们仅仅测试很少的一部分或者根本就不测试。这取决于你的项目。再一次,这可能没有一个绝对正确的方式。这取决于你工作的人事环境,你的项目目标和重要性。

你需要自己找到什么对你有用,什么没有用,测试对你的作用。我们做的和决定都不重要,因为每个人需要自己去发现。不同的人能力和工作的方式都不同。

当你考虑测试的时候,需要记住哪些能够帮助你。举个栗子,测试可以作为验证来帮助你代码正确,但这也可以帮助你设计你的代码。进一步讲,测试可以帮助你定义你的API。最终,测试可以作为一个文档。如果是多人协作的话,这就很有用了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,180评论 1 23
  • 介绍 objc.io objc.io 是关于 Objective-C 最佳实践和先进技术的期刊,欢迎来到第一期! ...
    评评分分阅读 1,694评论 5 24
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,337评论 0 1
  • 文/高瞻 ec+谊熙加体验传播 & PGY蒲公英会议中心 创始人 前几天老领导组织吃饭,分开十几年,每次相聚都是其...
    高瞻阅读 450评论 0 1