表现使得开发iOS

写在头里:前日晚间会分享200多张合计导图改变了自我什么?也许是因为忙,也许是因为自己不够重视自己?依旧因为这多少个对本人而言太简单,如故因为心里有太多的话不通晓如何去说啊?我到如今才起初写,但是一切都是可以的,相信自己。我的初心就是把团结的故事说给你听,告诉你什么采纳思维导图工具来改变我。这是讲稿。

Designer News.png

诸君直播间的伴儿们!

前段时间在design+code选购了一个读书iOS设计和编码在线课程,使用Sketch设计App,然后使用Swift(Swift)语言实现Designer
News
客户端。作者Meng
To已经开源到Github:MengTo/DesignerNewsApp ·
GitHub
。即使实现所有Designer
News客户端基本功效,但是拔取臃肿MVC(Model-View-Controller)架构,不易于代码的测试和复用,于是利用ReactiveCocoa实现MVVM(Model-View-View
Model)架构,加上一个用Objective-C实现的BDD测试框架Kiwi来单元测试,就足以表现使得开发iOS
App。

世家夜间好!

ReactiveCocoa

ReactiveCocoa是一个用Objective-C编写,具有函数式和响应式特性的编程框架。大多数的开发者他们排忧解难问题的思想形式都是何等完成任务,平日的做法就是编写很多命令,然后修改紧要数据结构的动静,那种编程范式叫做命令式编程(Imperative
Programming
)。与命令式编程不同的是函数式编程(Functional
Programming
),思考问题的法门是成就什么任务,怎么样描述这一个职责。关于对函数式编程入门概念的知晓,可以参考酷壳《函数式编程》这篇作品,浓厚浅出对函数式编程的盘算形式、特性和技术通过有些演示来教学。

不行喜气洋洋在二〇一八年11月13日那样的一个周末夜晚和豪门一块儿来聊一聊思维导图给自身带来的改观。

ReactiveCocoa解决什么问题?

  • 目标期间状态与气象的倚重过多问题
    借用ReactiveCocoa中一个例证来证实:用户在签到界面时,有一个用户名输入框和密码输入框,还有一个登录按钮。登录交互要求如下:
  1. 当用户名和密码符合验证格式,并且从前还没登录时,登录按钮才能点击。
  2. 当点击登录成功登录后,设置已报到状态。

观念的做法代码如下:

static void *ObservationContext = &ObservationContext;

- (void)viewDidLoad {
   [super viewDidLoad];

   [LoginManager.sharedManager addObserver:self forKeyPath:@"loggingIn" options:NSKeyValueObservingOptionInitial context:&ObservationContext];
   [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(loggedOut:) name:UserDidLogOutNotification object:LoginManager.sharedManager];

   [self.usernameTextField addTarget:self action:@selector(updateLogInButton) forControlEvents:UIControlEventEditingChanged];
   [self.passwordTextField addTarget:self action:@selector(updateLogInButton) forControlEvents:UIControlEventEditingChanged];
   [self.logInButton addTarget:self action:@selector(logInPressed:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)dealloc {
   [LoginManager.sharedManager removeObserver:self forKeyPath:@"loggingIn" context:ObservationContext];
   [NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)updateLogInButton {
   BOOL textFieldsNonEmpty = self.usernameTextField.text.length > 0 && self.passwordTextField.text.length > 0;
   BOOL readyToLogIn = !LoginManager.sharedManager.isLoggingIn && !self.loggedIn;
   self.logInButton.enabled = textFieldsNonEmpty && readyToLogIn;
}

- (IBAction)logInPressed:(UIButton *)sender {
   [[LoginManager sharedManager]
       logInWithUsername:self.usernameTextField.text
       password:self.passwordTextField.text
       success:^{
           self.loggedIn = YES;
       } failure:^(NSError *error) {
           [self presentError:error];
       }];
}

- (void)loggedOut:(NSNotification *)notification {
   self.loggedIn = NO;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
   if (context == ObservationContext) {
       [self updateLogInButton];
   } else {
       [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
   }
}

上述使用KVO、Notification、Target-Action等处理事件或消息的不二法门编写的代码分散到各类地点,变得乱七八糟和麻烦精晓;不过拔取RACSignal统一处理的话,代码更加简洁和易读。使用RAC后代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];

    @weakify(self);

    RAC(self.logInButton, enabled) = [RACSignal
        combineLatest:@[
            self.usernameTextField.rac_textSignal,
            self.passwordTextField.rac_textSignal,
            RACObserve(LoginManager.sharedManager, loggingIn),
            RACObserve(self, loggedIn)
        ] reduce:^(NSString *username, NSString *password, NSNumber *loggingIn, NSNumber *loggedIn) {
            return @(username.length > 0 && password.length > 0 && !loggingIn.boolValue && !loggedIn.boolValue);
        }];

    [[self.logInButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UIButton *sender) {
        @strongify(self);

        RACSignal *loginSignal = [LoginManager.sharedManager
            logInWithUsername:self.usernameTextField.text
            password:self.passwordTextField.text];

            [loginSignal subscribeError:^(NSError *error) {
                @strongify(self);
                [self presentError:error];
            } completed:^{
                @strongify(self);
                self.loggedIn = YES;
            }];
    }];

    RAC(self, loggedIn) = [[NSNotificationCenter.defaultCenter
        rac_addObserverForName:UserDidLogOutNotification object:nil]
        mapReplace:@NO];
}
  • 观念MVC架构中,由于Controller承担数据证实、映射数据模型到View和操作View层次结构等三个责任,导致Controller过于臃肿,不便民代码的复用和测试。
    在价值观的MVC架构中,重要有Model,
    View和Controller三部分组成。Model首要是保存数据和拍卖工作逻辑,View将数据显示,而Controller调解关于Model和View之间的所有交互。
    当数码到达时,Model通过Key-Value Observation来通知View Controller,
    然后View Controller更新View。当View与用户交互后,View
    Controller更新Model。

Typical MVC paradigm.png

正如您所见,View
Controller隐式承担过多责任:数据申明、映射数据模型到View和操作View层次结构。MVVM将洋洋逻辑从View
Controller移走到View-Model,等介绍完ReactiveCocoa后会介绍MVVM架构。还有部分有关咋样减负View
Controller好作品请参阅objc中国更轻量的View
Controllers体系:

  • 更轻量的 View
    Controllers

  • 整洁的 Table View
    代码

  • 测试 View
    Controllers

  • 应用Signal来替代KVO、Notification、Delegate和Target-Action等传递消息
    iOS开发中有多种音信传递形式,KVO、Notification、Delegate、Block和Target-Action,对于它们中间有哪些区别以及哪些抉择请参考《音讯传递机制》。但RAC提供RACSignal来归并音信传递机制,不再为怎么挑选何种传递信息格局而懊恼。

    RAC对常用UI控件事件举办封装成一个RACSignal对象,以便对暴发的各个风波进展监听。
    KVO示例代码如下:

// When self.username changes, logs the new name to the console.
//
// RACObserve(self, username) creates a new RACSignal that sends the current
// value of self.username, then the new value whenever it changes.
// -subscribeNext: will execute the block whenever the signal sends a value.
[RACObserve(self, username) subscribeNext:^(NSString *newName) {
    NSLog(@"%@", newName);
}];

Target-Action示例代码如下:

// Logs a message whenever the button is pressed.
//
// RACCommand creates signals to represent UI actions. Each signal can
// represent a button press, for example, and have additional work associated
// with it.
//
// -rac_command is an addition to NSButton. The button will send itself on that
// command whenever it's pressed.
self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^(id _) {
    NSLog(@"button was pressed!");
    return [RACSignal empty];
}];

Notification示例代码如下:

 // Respond to when email text start and end editing
 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UITextFieldTextDidBeginEditingNotification object:self.emailTextField] subscribeNext:^(id x) {
      [self.emailImageView animate];
      self.emailImageView.image = [UIImage imageNamed:@"icon-mail-active"];
      self.emailTextField.background = [UIImage imageNamed:@"input-outline-active"];
  }];

 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UITextFieldTextDidEndEditingNotification object:self.emailTextField] subscribeNext:^(id x) {
      self.emailTextField.background = [UIImage imageNamed:@"input-outline"];
      self.emailImageView.image = [UIImage imageNamed:@"icon-mail"];
  }];

除却,还足以采用AFNetworking访问服务器后对回到数据自创建一个RACSignal。示例代码如下:

 + (RACSubject*)storiesForSection:(NSString*)section page:(NSInteger)page
{
    RACSubject* signal = [RACSubject subject];

    NSDictionary* parameters = @{
        @"page" : [NSString stringWithFormat:@"%ld", (long)page],
        @"client_id" : clientID
    };

    [[AFHTTPSessionManager manager] GET:[DesignerNewsURL stroiesURLString] parameters:parameters success:^(NSURLSessionDataTask* task, id responseObject) {
                NSLog(@"url string = %@", task.currentRequest.URL);
                [signal sendNext:responseObject];
                [signal sendCompleted];
    } failure:^(NSURLSessionDataTask* task, NSError* error) {
                NSLog(@"url string = %@", task.currentRequest.URL);
                [signal sendError:error];
    }];

    return signal;
}

有点朋友能够感觉有点奇怪,下边代码明明重临的是RACSubject,而不是RACSignal,其实RACSubject是RACSignal的子类,但是RACSubject写出代码更加从简,所以接纳RACSubject(官方不推荐行使)。等下将RAC核心类设计时,你就会询问它们中间的关系和哪些抉择。

你们精通呢?

ReactiveCocoa大旨类设计

关于RAC要旨类设计,官方文档有详尽的诠释:Framework
Overview

直播分享与此外地点不均等,是温馨一个人在一个屋子里对着一台手机说话,会有一种旗帜分明的孤独感,所以,后日,我有请求一些爱人,假使您有空,可以来直播间襄助自己。

Sequence和Signal基本操作

询问完整个RAC大旨类设计之后,要学会对Sequence和Signal基本操作,比如:用signal执行side
effects,转换streams, 合并stream和归并signal。详情请查阅官方文档:Basic
Operators

兴许此时此刻,在实事求是的社会风气中,我们无法想见,但在真实的真情实意中,我们是在联名的,您的这颗心会在您的房间、旅游的途中、朋友的闲话中如故其它的地方默默地陪着自身,我想自己是可以瞥见,感受到的。

MVVM架构

MVVM high level.png

在MVVM架构中,平常都将view和view
controller看做一个总体。相对于事先MVC架构中view
controller执行很多在view和model之间数据映射和互动的办事,现在将它交给view
model去做。
有关接纳哪类机制来更新view
model或view是从未有过强制的,但平时我们都选拔ReactiveCocoa。ReactiveCocoa会监听model的转移然后将这个改变映射到view
model的特性中,并且可以实施一些政工逻辑。
举个例子来说,有一个model包含一个dateAdded的属性,我想监听它的转移然后更新view
model的dateAdded属性。但model的dateAdded属性的数据类型是NSDate,而view
model的数据类型是NSString,所以在view
model的init方法中展开数据绑定,但需要数据类型转换。示例代码如下:

RAC(self,dateAdded) = [RACObserve(self.model,dateAdded) map:^(NSDate*date){ 
    return [[ViewModel dateFormatter] stringFromDate:date];
}];

ViewModel调用dateFormatter举行数量转换,且方法dateFormatter能够复用到此外地方。然后view
controller监听view model的dateAdded属性且绑定到label的text属性。

RAC(self.label,text) = RACObserve(self.viewModel,dateAdded);

现行我们抽象出日期转换来字符串的逻辑到view
model,使得代码可以测试复用,并且帮view controller瘦身

自身看我的良师郭立中、橙子伙伴朱进伟、马兰,老铁艾伦(Alan)、雨小朵、佳琦、Shirley、新情人紫衣等许多情侣曾经留言襄助我了。有着大爱的浙大才女尔玛先生、弗兰克(Frank)先生,好姊妹陌上花开,新对象王晓琴,熊猫伙伴张仁喜、橙子伙伴琼咪,杰克思维导图群的橙西瑰宝、尔玛心境群的枫之然,正念打卡群群主小英等朋友用分享连接给心上人的实际行动帮助了自己。我也信任有诸多有情人也正值手机的这端默默补助自己。这让自己倍感莫大的温暖。

Kiwi

Kiwi是一个iOS行为使得开发(Behavior Driven
Development
)的库。相相比于Xcode提供单元测试的XCTest是从测试的角度思考问题,而Kiwi是从行为的角度思考问题,测试用例都遵从三段式Given-When-Then的描述,清晰地表述测试用例是测试什么样的靶子或数据结构,在按照什么上下文或气象,然后做出什么响应。

describe(@"Team", ^{
    context(@"when newly created", ^{
        it(@"has a name", ^{
            id team = [Team team];
            [[team.name should] equal:@"Black Hawks"];
        });

        it(@"has 11 players", ^{
            id team = [Team team];
            [[[team should] have:11] players];
        });
    });
});

咱俩很容易依照上下文将其领取为Given..When..Then的三段式自然语言

Given a Team, when be newly created, it should have a name, it should have 11 player

用Xcode自带的XCTest测试框架写过测试代码的情人或者体会到,以上代码更加便于阅读和精通。固然以后有新的开发者参与或修护代码时,不需要太大的资本去读书和透亮代码。具体哪些选拔Kiwi,请参见两篇作品:

谢谢各位小伙伴们的支撑,我特别感谢一下本身的丈夫和孩子,是他们为自己创造了一个这么好的空中,能让我可以如此静心地与我们聊聊,也谢谢在直播间的您,有时光冷静地一同交换,也万分感谢一些四处奔波的伴儿们,后续可以抽时间来听。

Designer News UI

在编写Designer
News客户端代码从前,首先通过UI来询问所有App的概略。设计Designer News
UI的工具是Sketch,想获得Designer
News UI,请点击下载Designer New
UI

Designer News Design.png

假诺将拥有的页面都相继表达什么编写,会相比耗时间,所以只拿登陆页面来证实自身是怎么行事使得开发iOS,但我会将全体项目的代码上盛传github

实质上不管你咋样时候进入直播间,一切都是可以的。倘使听完后,请一定要给自家有些报告,有句话叫有回应,有福报,来自我的园丁郭立中,其实这句话深含关系的奥秘哦。我决不职业助教,而只是一位甘当终身学习,并且陪您成长的人,所以自己只讲一些故事,和我自己的有些想想,供您做参考。您就当先天是和一个老朋友在茶馆里聊天吗。

登陆界面

出于那个体系简单并且只有一个人付出(五人付出以来,选取Storyboard不易于代码合并),加上Storyboard可以可视化的添加UI组件和Auto
Layout的约束,并且可以同时预览五个不等分辨率BlackBerry的法力,极大地提升开发界面功用。

Login.png

明天是自己先是堂收费的分享课程,既然是收费课程,我自然得说干货,对得起你付出的不得了9.99元。假使你以为不值,分享完成后,你可以问我要红包的。假如你认为超值、也可以打赏哈,这你决定!

登陆交互

登陆界面有Email输入框和密码输入框,当用户选中其他一个输入框时,左侧对应的图标变成紫色,同时会有pop动画表示用户准备要输入内容。
当用户没有输入有效的Email或密码格式时,用户是不可能点击登陆按钮,唯有当用户输入有效的邮件和密码格式时,才能点击登陆按钮。

Login.gif

俺们可以利用RAC由此监听Text
菲尔德(Field)(Field)的UITextFieldTextDidBeginEditingNotificationUITextFieldTextDidEndEditingNotification的打招呼来处理用户选中Email输入框和密码输入框时改变图标和体现的动画。

#pragma mark - Text Field notification
- (void)textFieldStartEndEditing
{
    // Respond to when email text start and end editing
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UITextFieldTextDidBeginEditingNotification object:self.emailTextField] subscribeNext:^(id x) {
        [self.emailImageView animate];
        self.emailImageView.image = [UIImage imageNamed:@"icon-mail-active"];
        self.emailTextField.background = [UIImage imageNamed:@"input-outline-active"];
    }];

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UITextFieldTextDidEndEditingNotification object:self.emailTextField] subscribeNext:^(id x) {
        self.emailTextField.background = [UIImage imageNamed:@"input-outline"];
        self.emailImageView.image = [UIImage imageNamed:@"icon-mail"];
    }];

    // Respond to when password text start and end editing
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UITextFieldTextDidBeginEditingNotification object:self.passwordTextField] subscribeNext:^(id x) {
        [self.passwordImageView animate];
        self.passwordTextField.background = [UIImage imageNamed:@"input-outline-active"];
        self.passwordImageView.image = [UIImage imageNamed:@"icon-password-active"];
    }];

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UITextFieldTextDidEndEditingNotification object:self.passwordTextField] subscribeNext:^(id x) {
        self.passwordTextField.background = [UIImage imageNamed:@"input-outline"];
        self.passwordImageView.image = [UIImage imageNamed:@"icon-password"];
    }];
}

当点击登陆按钮后,客户端向服务端发送验证请求,服务端验证完账户和密码后,用户便能够成功登陆。所以,接下去要通晓RESTful
API的基本概念和Designer News提供的RESTful API。

     
然则自己是很有信心的。这堂课程可以说是价值连城的,因为这是一场心与心,思维与思想的交流,不是金钱就足以衡量的!

Designer News API

好了,言归正传,无法太多废话了。

RESTful API基本概念和设计

REST齐全是Representational State
Transfer,翻译过来就是突显层状态转化。要想真正明白它的含义,从多少个重大字出手:Resource,
Representation, State Transfer

  • ##### Resource(资源)

资源就是网络上的实业,它可以是文字、图片、声音、视频或一种服务。但网络有那般多资源,该如何标识它们啊?你可以用URL(统一资源定位符)来唯一标识和固定它们。只要取得资源对应的URL,你就足以访问它们。

  • ##### Representation(表现层)

资源是一种新闻实体,它有多种代表方法。比如,文本能够用.txt格式表示,也得以用xml、json或html格式表示。

  • ##### State Transfer(状态转换)

客户端访问服务端,服务端处理完后归来客户端,在这么些进程中,一般都会唤起数据状态的改动或转换。
客户端操作服务端,都是由此HTTP协议,而在这些HTTP协议中,有多少个动词:GET,
POST, DELETEUPDATE

  • GET表示收获资源
  • POST表示新增资源
  • DELETE表示删除资源
  • UPDATE表示更新资源

接头RESTful焦点概念后,我们来简单精晓RESTful API设计以便可以看懂Designer
News提供API。就拿Designer News获取Stories对应URL的一个例子来表达:
客户端请求
GET https://api-news.layervault.com/api/v1/stories?client_id=91a5fed537b58c60f36be1sdf71ed1320e9e4af2bda4366f7dn3d79e63835278

服务端再次回到结果(部分结果)

{
  "stories": [
    {
      "id": 46826,
      "title": "A Year of DuckDuckGo",
      "comment": "",
      "comment_html": null,
      "comment_count": 4,
      "vote_count": 17,
      "created_at": "2015-03-28T14:05:38Z",
      "pinned_at": null,
      "url": "https://news.layervault.com/click/stories/46826",
      "site_url": "https://api-news.layervault.com/stories/46826-a-year-of-duckduckgo",
      "user_id": 3334,
      "user_display_name": "Thomas W.",
      "user_portrait_url": "https://designer-news.s3.amazonaws.com/rendered_portraits/3334/original/portrait-2014-09-16_13_25_43__0000-333420140916-9599-7pse94.png?AWSAccessKeyId=AKIAI4OKHYH7JRMFZMUA&Expires=1459149709&Signature=%2FqqLAgqpOet6fckn4TD7vnJQbGw%3D",
      "hostname": "designwithtom.com",
      "user_url": "http://news.layervault.com/u/3334/thomas-wood",
      "badge": null,
      "user_job": "Online Designer at IDG UK",
      "sponsored": false,
      "comments": [
        {
          "id": 142530,
          "body": "Had no idea it had those customization settings — finally making the switch.",
          "body_html": "<p>Had no idea it had those customization settings — finally making the switch.</p>\\n",
          "created_at": "2015-03-28T18:41:37Z",
          "depth": 0,
          "vote_count": 0,
          "url": "https://api-news.layervault.com/comments/142530",
          "user_url": "http://news.layervault.com/u/3826/matt-soria",
          "user_id": 3826,
          "user_display_name": "Matt S.",
          "user_portrait_url": "https://designer-news.s3.amazonaws.com/rendered_portraits/3826/original/portrait-2014-04-12_11_08_21__0000-382620140412-5896-1udai4f.png?AWSAccessKeyId=AKIAI4OKHYH7JRMFZMUA&Expires=1459125745&Signature=%2BDdWMtto3Q10dd677sUOjfvQO3g%3D",
          "user_job": "Web Dood @ mattsoria.com",
          "comments": []
        },
  • 协议(protocol)
    用户与API通信接纳HTTPs协议
  • 域名(domain name)
    应当尽可能部署到专用域名下https://api-news.layervault.com/,但有时候会越来越扩展为https://api-news.layervault.com/api
  • 版本(version)
    应该将API版本号v1放入URL
  • 路径(Endpoint)
    路径https://api-news.layervault.com/api/v1/stories表示API具体网址,代表网络一种资源,所以不可能有动词,唯有采纳名词来代表。
  • HTTP动词
    动词GET,表示从服务端获取Stories资源
  • 过滤音信(Filtering)
    ?client_id=91a5fed537b58c60f36be1sdf71ed1320e9e4af2bda4366f7dn3d79e63835278指定client_id的Stories资源
  • 状态码(Status Codes)
    服务器向客户端再次来到表示成功或失利的状态码,状态码列表请参考Status
    Code
    Definitions
  • 错误处理(Error handling)
    服务端处理用户请求失利后,一般都回到error字段来表示错误音讯

{
    error: "Invalid client id"
}

自我先是问我们一个题材:

Designer News提供API

Designer News API
Reference
提供遵照HTTP协和服从RESTful设计的API,并且同意应用程序通过oAuth
2
授权协议来得到授权权限来拜访用户信息。

200多张合计导图改变了自家何以?这句话的紧要性词是如何?

访问API工具

貌似的话,在写访问服务端代码此前,我都会用Paw(下载地址)工具来测试API是否有效;另一方面,用JSON文件保留服务端再次来到的数据,用于moco如法炮打败务端的劳务。至于怎么需要moco模拟服务端,前面会讲课,现在透过用户登录Designer
News
其一例子介绍怎么着运用Paw来测试API。
咱俩先看看Designer News提供访问用户登录的API

Designer News Login API.png

依照上述提供的音讯,API的路子是https://api-news.layervault.com/oauth/token,参数有grant_typeusernamepasswordclient_secret。其中usernamepasswordDesigner
News
登记才能收获,而client_idclient_secret需要发送email到news@layervault.com申请。使用Paw发送请求和服务端重回结果如下:

New Send Request.png

(请回答)

Moco模拟服务端

Moco是一个足以轻松搭建测试服务器的工具。

对呀,是变动、是思考导图、也许是。。。。

干什么需要效法服务端

用作一个运动开发人士,有时由于服务端开发进度慢,空有一个BlackBerry应用但发布不出效能。幸好有了Moco,只需安排一下伸手和重返数据,很快就足以搭建一个模拟服务,无需等待服务端开发到位才能延续支付。当服务端完成后,修改访问地址即可。

突发性服务端API应该是何等样子都还没理解,由于有了moco模拟服务,在付出过程中,可以不断调整API设计,搞了然真正自己想要的API是怎么样样子的。就这么,在服务端代码还没真正入手以前,已经提供一份真正满意自己需要的API文档,剩下的就交付劳务端照着API去落实就行了。

再有一种状态就是,服务端已经写好了,剩下客户端还没完成。由于moco是本地服务,访问速度相比较快,所以通过利用moco来模拟服务端,这样不光可以提升客户端的访问速度,还增强网络层测试代码访问速度的平稳,Designer
News就是这么情况。

咱俩先是来聊天改变,我想说说自己的变更呢

咋样采纳Moco模拟服务

安装

只要你是利用Mac或Linux,可以品味一下步骤:

  1. 确定你安装JDK 6以上
  2. 下载脚本
  3. 把它坐落你的$PATH路径
  4. 安装它可以执行(chmod 755 ~/bin/moco)

近日你能够运行一下下令测试安装是否中标

  1. 编写配置文件foo.json,内容如下:

[
      {
        "response" :
          {
            "text" : "Hello, Moco"
          }
      }
]
  1. 运行Moco HTTP服务器
    moco start -p 12306 -c foo.json
  2. 开拓浏览器访问http://localhost:12306,你重放见”Hello, Moco”

图片 1

配置服务

出于有时候服务端再次回到的数额比较多,所以将服务端响应的多寡独立在一个JSON文件中。以登陆为例,将数据存放在login_response.json

{
    "access_token": "4422ea7f05750e93a101cb77ff76dffd3d65d46ebf6ed5b94d211e5d9b3b80bc",
    "token_type": "bearer",
    "scope": "user",
    "created_at": 1428040414
}

而将呼吁uri路径,方法(method)和参数(queries)等安排放在login_conf.json文件中

[
  {
    "request" :
      {
        "uri" : "/oauth/token",
        "method" : "post",
        "queries" : 
          {
            "grant_type" : "password",
            "username" : "liuyaozhu13hao@163.com",
            "password" : "freedom13",
            "client_secret" : "53e3822c49287190768e009a8f8e55d09041c5bf26d0ef982693f215c72d87da",
            "client_id" : "750ab22aac78be1c6d4bbe584f0e3477064f646720f327c5464bc127100a1a6d"
          }
      },
    "response" :
      {
        "file" : "./Login/login_response.json"
      }
  }
]

不清楚有没有留意到下边uri路径不是全路线http://localhost:12306/oauth/token,因为协议默认是http,而且平日运行在本机localhost,所以在起步模拟服务时只需点名端口12306就行。想进一步详实精通如何布置,请查阅官网的HTTP(s)
APIs

再有一个急需配备地点就是,由于实在支出中一定不止一个客户端请求,所以还亟需一个部署文件settings.json来含有很有些请求。

[
    {
        "include" : "./Story/stories_conf.json"
    },
    {
        "include" : "./Login/login_conf.json"
    },
    {
        "include" : "./Story/story_upvote_conf.json"
    }
]

起步服务

将路径跳转到DesignerNewsForObjc/DesignerNewsForObjcTests/JSON目录,找到settings.json文件,使用命令行来启动服务:
moco start -p 12306 -g settings.json

=====

使用Paw验证是否安排成功

Send request to Local Server.png

一、改变

1、身体上的更动

本人曾是一个84公斤重的宝妈,在一个半月前,我如故71.7公斤,可是现在我曾经63.3公斤了。在上个月,我减了8斤多的脂肪,我每一天可以不费劲的记录自己的饭食意况,然后分享在简书,这总体对于一个在身体上很懒的人来说,您觉得神奇啊?感觉是一个偶然吗?

图片 2

兴许你会说,这有甚呀?我还50公斤呢。是啊,您的份量是很轻,也恐怕特别健康。不过对于一个几十年胖子而言,您知道这件事会给自己带来多大的意义感吗?

或是你会说你这是临时的,没有什么,你肯定会反弹的。是呀,这一个题材,我关系好的同事也跟我说过,但是我有着很好的羁绊,有着伙伴们的支撑,再增长专业营养师(省干部休养所的沈医务卫生人员)的技巧,那种可能性又有多少啊?再说我又在乎多少吗?

我相信也许还有局部坐在手机面前的你,是习惯于鼓励别人的,其实真正这一部分人不少,说蓝心,哇,你好棒哦,分享一下措施呢!是的,在4个月后,我会来具体做连锁分享,到时让时光来告诉您一切!

这是本人的第一个转移,人体重量的变更,让自家打羽毛球时候更轻盈,肢体不再有一种累赘之感。

行为使得开发(BDD)

2、心情的转移

人有尊重心境和负面心绪

正当的心情有,满面春风、开心、喜悦、自豪、兴奋等

图片 3

负面的心气有伤心、愤怒、绝望、压抑、骄傲等等

图片 4

骨子里那是一个人表现出来的不比景观。

人都有不俗心境和负面心思,只是在一段时间里,他显得正面心绪多一些或者少一些罢了。

而我原本是一个自以为分外和气,脾气好的人,可是实际上是一个自制了成百上千激情的人。

不精晓我们玩过DSIC性格分析吗?假设没有玩过,分享后,我会告诉您应该咋样去玩。近期刚上学了郭立中先生的新课程慧眼识人术,还在学习期,特别想尝试自己控制的技巧哈,所以你们可以来找我,我帮您做分析,然后给自身有的汇报,看看自己是否有读心术?开玩笑啦!

实际上自己是想讲,我表面上是温和、脾气很好的考拉。世家了然考拉吗?就是澳大乌兰巴托的国宝哦。所以一旦你测下了是只树袋熊,请不要以为有哪些不好。而要知道她本身很有价值,是国宝哈。

考拉型人是一种老黄牛式的人,工作早出晚归,一心为人家贡献,却很少收获职场擢升。在家庭里也是,一心围着妻儿服务,因为不会维护自己,极有可能得到的是一堆抱怨。卡拉型人是有一颗玻璃心的,会以为委屈,会哭泣,会感受到痛苦。所以只要您附近有考拉性格的人,知道怎么跟考拉型的人相处吧?

请你善待它,因为它需要极高的安全感,它害怕,恐惧,受到惊吓。假如它需要搬家的话,都急需它在中途,连着树一起移居哦,醒来时需要停下来的,否则会碰着惊吓的。

图片 5

而是考拉型的格调的人即使有那个痛苦在,可是一旦觉醒,那将是一股巨大的能量。因为痛苦带来教益,没有白受的苦,只要你能转念,痛苦背后会给您带来巨大的价值。

设若你想正面心绪多于负面心境的话,可以看看ABC法则,我有在简书上分享应用思维导图来拆除激情的地雷这本书。假设急需,我也足以举办这块的分享,相比吻合在家庭和办事中饱受委屈的宝妈哈。

图片 6

这自己的改变是怎样吗?只说一项吧!

在家庭里,我不再是一个摆着脸色的人了,而变成了一个温和喜悦的人,类似于家里的小太阳吧。我是与大伯母亲一起住的,已经有10年了,大家了然与四叔岳母一起住,并不是很容易的事体,前9年,我由一个开玩笑快乐的人,成功地成为了一个黄脸婆,连自己都不待见自己的人,这样的人可以有好的心怀啊?不过经过这一年半的自身努力,特别是心绪学领域的成长,我成为了一个必然我,相对自信的人。

实在在微课上,大家也可以由此声音能看清自身的场所了吗?我们也足以去听听当自家画完100张合计导图里面的享受,也是在共学共好的荔枝直播间,你可以听出分明得变化哦!

好了,那是自家在心怀上的更动。

缘何需要BDD

不亮堂诸位在编制测试的时候,有没有沉思过一个题材:我应当测试什么?要应对这么些题目并不是那么简单,在没获得答案从前,你仍旧延续遵照你的想法编写测试。
-(void)testValidateEmail;
像那样的测试,存在一个常有问题。它不会报告您应有会暴发哪些,也不会预期实际会暴发什么样。还有,当它发出错误时,不会唤醒您在啥地方暴发错误,错误的原故是怎么,由此你需要深刻代码才能知晓战败的原由。这样就需要大量非凡和不必要的体味负荷。
此时BDD出现了,辅助开发者确定应该测试什么,它提供DSL(Domain-specific
language
,
域特定语言),测试用例都恪守三段式Given-When-Then的叙述,清晰地表明测试用例是测试什么样的对象或数据结构,在依照什么上下文或现象,然后做出咋样响应。
据此,我们应有关注行为,而不是测试。这行为具体是怎么?当您设计app里面的中间目的时,它的接口定义方法及其看重关系,这多少个艺术和依靠关系决定了您的目的怎么着与此外对象交互,以及它的效能是怎么样,定义你的对象的行为

其三、思维方面的变动

不晓得哪位大神说过,人与人里面的出入在于认知的出入。而自我认为之所以有认知的歧异,这是因为思维的逻辑层次或者思维方法不一致。

今非昔比的人揣摩情势不同等,看世界的角度也不平等。

刚刚实在有谈个人、家庭、这自己说说工作呢,干活只是生活的瑰宝,实现我价值的利器哈哈,所以,我们一定要了不起工作。

前年自己碰到一件非凡费劲的事情。我面临着一个人生首要拔取。选取是否需要跳槽?你们知道不?考拉性格的人实在是对店家极有忠实心的,假诺在一个供销社做,会百折不挠在一个小卖部做下去,不管打骂,侮辱,折磨,他都会在,除非您逐级地抽取它需要的东西走,它认为有一天尚未东西得以玩的时候,它会走。所以只要你是商家的领导者,请善待他们,他们是中坚力量,公司的主力军。

实际上对于当下的本身也一致,而我悄悄还有另一段辛酸的故事,可是不便于在此间说啊。我面临着个问题,当大家的营业所往异地搬的时候,我需要长久出差时,我应该怎么接纳?

不同的人是不同的思考情势的

一对人说,纪云,走吗,在东京(Tokyo)找一份工作,现在的空子多好啊,领导给你钱让你走,30多万,这种孝行什么地方找?别傻了!

一部分人说:家家和事业哪个首要?女孩子,有家才有事业,孩子是你的全体,做好一个四姨。

局部人说,你假诺去了常熟,你的儿女只要就此考不上中学,到时您后悔死了!你能接受这样的结果呢?

也有人说,纪云,你适合做科研,你看,你给集团开发了那么多产品,现在又是一个机遇,去常熟闯一闯吧,自家深信不疑,你一定可以

其实还有为数不少种想法,对应着不同的思维方法,然而自己想说的是,她俩悄悄都是爱因为爱自己,所以给了本人无数深入的见识。

而自我是什么想的吧?30多万的买断费,不想,这是在装。假设30多万,厚厚的一叠钞票摆在你的眼前,你不会双眼动一下?心里不念想着?当然也有高手哈,这是一贯不一点点缺乏感的人。

而自己是平流,确实是触动的,说不动心是假的。30多万,相当于自己两到3年的收入,而且依然不收税的。我当做一个好人当然想拿。

可是我又很纠结,我纠结什么啊?我能出来找到好的行事吗?这里的同事领导都这样好,我走对得起他们吧?我在这一行业做了这般长年累月,有很多缠绵悱恻的经历,我白受了吗?这是一种能力。来自心底的担惊受怕,当时自家的大姑也面临类似抉择,她挑选了家中,结果后来直接郁郁寡欢,很不心潮澎湃。我心中其实有一种常人难以通晓的恐怖在,我害怕,害怕像三姨一样不开玩笑。因而自己心头想采用工作

而除此以外一种能力呢?出自家庭,孩子,卓殊欣赏自己呆在她的身边,陪她成长,老公希望我在家里照顾儿女,工作他让自己毫无顾虑,他得以帮我找。大伯三姨其实也希望自己在家里,家里有个女主人在,这是多好的事体哈。

自家有一段时间无法平衡那二种力量。我所有不出名的伤痛,无法清楚地知道自己的取向,我很纠结,不明了怎么样去挑选。

就此我去了新人才学习生涯规划,期望自己找到答案。我在网上报了许多微课,期待找到答案,我在现实生活中也在考察同事的挑三拣四,他们什么做的?也可望从他们的随身找到答案。

这个我都没有找到答案,而整个似乎自己在罗先生的冥想课程上看到的那么,我的以后一片迷茫。

我痛苦,抑郁,一段时间不了然咋样去表明自己。

唯一陪伴自己的只是本人2016年赶上的新的爱护,思维导图。我在盘算导图上写下自己学的学科,我用思想导图来帮忙自己学车,我用心想导图帮我调动心态。

本来我也相当感谢所有的伴儿们,无论是现实中的,依然网络中的朋友,当时本身说的,做的,是有些负面能量的,感谢您们的兼容和收取。感谢这一个网络上给自家点赞的意中人,谢谢你们,知道啊?这么些时候是自身最薄弱的时候,你们的鼓励对自我而言是多么的最首要哈!

但是自己坚定不移着,有思考导图、断舍离、POA、等课程的伴随下,突然有一件我获取了答案。

我是一个不佳不坏的人,我得以允许自己做一个坏蛋。我索要了然自己,去啥地方做事实际上答案不在外界,在于自己的随身。

当自家开头关心自己时,仿佛整个有了答案。这些答案很简短。

这不是一个去不去外地工作的题目,而是一个想变成什么的人的题目。生命的意义在于成为你协调。我有如何的希望呢?自身想做氟化交通银行业的PTFE领域的大方吗?假使您想,就留下来,为那多少个目的而奋斗,假使不想,有新的趋向呢?若是已经成熟,这就去做
吧,实现团结的微梦想吧。

自己静心地问我要好,我想呢?我的内心的答案是毫无疑问的,我想,相当想。因为自身的行事特别有意义,大家知晓不粘锅吗?我们家里都有啊?当二零零七年毒不粘锅事件闹得沸腾时,也许很四个人都精通,甚至想把家里的锅子拿出去砸了,说不粘锅有毒!

实质上呢,并非不粘锅有毒,而是生产过程中动用的一种试剂有毒,异常微量的,基本在200多度已经表达的试剂。我们不说这事件幕后的另外意思,我只想说,我做的干活与诸位家庭有关的,我希望给大家提供一口安全的环保的不粘锅,我也直接为之一贯努力着,曾给合作社支出出五个体系的环保聚四氟乙烯乳液,共计8种产品。我也有申请了8项专利技术,我的专利一度拿到国家中国专利局的上佳专利奖证书

图片 7

工作让自身痛苦吗?实际上痛苦并喜欢着是一个研发人员的实相。考拉型的研发人士貌似不擅长互换,喜欢蒙头做业务,所以会有诸多抱屈在,不过他们会蕴藏着泪花把事情做完,为了项目末了的对象,讲贡献,讲集体主义精神。

本身也同等。但是透过学习,我通晓了不同的人不同的思维模式,我一筹莫展更改别人对我的办法,不过我能够调动自我对别人的点子。我得以去看,去听,去观察,去询问你语言中确实的含义,从而可以更好的关系。

个中工作中也有成百上千坑,有时光再给大家唠嗑哈。

地方说的是自我在肢体、激情、思维方面的三大改变。

BDD过程

表现使得开发大概五个步骤:

  1. 选料最重大的一言一行,并编制行为的测试文件。此时,由于测试对象的类还没编制,所以编译败北。创造测试对象的类并编制类的伪实现,让编译通过。
  2. 实现被测试类的一言一行,让测试通过。
  3. 万一发现代码中有再度代码,重构被测试类来清除重复

只要临时不清楚里面步骤细节,没有关联,继续向下阅读,前边有例子介绍来协理您知道四个步骤的含义。

有人会问,思维导图是怎么?也恐怕有人会问,你凭什么说你的改变来自于思考导图呢?思维导图学习有咋样利益?大家该怎么学习思考导图呢?不精通还有没有任何的问题啊?如若有,可以留言哈!我能够线上仍旧线下解答。

登陆验证

二、思维导图是何许?

借用思维导图一书中的定义

图片 8

合计导图是用图展现的一种发散性思维。发散性思维过程也就是大脑思维和暴发想法的过程。通过捕捉和表明发散性思维,思维导图将大脑内部的进程进展了表面表现。本质上,思维导图是在重新和宪章发散性思维,反过来又拓宽了大脑的本能,让大脑更强有力,更强有力!

这段相比理论,我的接头是,思维导图是大脑的一个表面表现。用图片,文字,线条等方法将大脑的想法画出来。

也就是说假如您的大脑思绪是无规律的,自然你画出的图是乱套而不要逻辑的。

假定你的大脑是明显的,自然是系统结构清晰可见的。

实际这绝非什么样,假设是乱套的,恰恰思维导图能够帮衬您,由不明晰到清晰。

前日我的伴儿阳光分享给我她的思维导图笔记

她问我,你觉得这一个导图如何?是否有点乱啊?

自己即刻有说,其实想想导图画出来,就是一个打点大脑的历程,一初步是会混杂的,可是逐步画,也就好了,你看他最后做到的导图多棒呀。她是一个万分有聪明的人,背后用着心打底,中央图,是一艘小艇,写着自悟自救,下面的帆上写着六个至关重要内容,说实话,特别赞!

思维导图更是一种心与心的互换,因为各类图案对各种人的意思不均等的,倘若同频的人来看,会立马点出您讲的情致,这是多好的一种看见哈。看见是人心底的一种基础需要。倘使你被看到的越多,你越会认为被精通,你的别样力量都自然则言地提高啦。

事实上想想导图又叫心智图,这是有道理的,应用了这样久确实是可以感受到众多方面的擢升。

图片 9

图片 10

网络访问层

三、思维导图怎么画?

骨子里这块原本不想讲,因为有同伴(神的男女在途中)有需要,所以有些讲一些简便的。

1、思维导图类型

沉凝导图有三大类,第一类是全文字型思维导图,这一般用来职场中,音讯量相比较大,波音公司曾用到飞机的类型中,节省了1千百万日币。第二类是全图型思维导图,一般每张图像对不同的人有例外的驾驭,所以全图型的思索导图需要人来诠释。第三类是图文型的思维导图,这是最常用的思维导图模式。.

2、5个关键技术

5个关键技术是可视化的工具,放射性思维,关键词技术,逻辑BOIS,颜色管理,这么些关键技术是急需在事实上过程中穿梭操练的,仔细回味的,这里因为日子关系不做分享。

图片 11

3、怎么画?

3.1先是需要准备工具

工具关键有两样,白纸和笔。

只要初学者磨炼,一般使用A4大大小小的白纸,完全空白的纸能够促使大脑不受任何自律的进展思考,能激发你不断想象力。对了,假诺想持续磨练,可以准备一本摄影本。这样可以把富有的思辨导图放在一块儿,一方面,复习起来相比较易于,另一方面,画一段时间后,有几十张时,拿着剧本看,也有一种满满的成就感。

笔一般拔取12色、24色水彩笔或者马克(马克)笔或者荧光笔。

一经在劳作上,唯有黑笔和白纸,画黑色简图也是足以的。粉黑色醒目,更符合人记得。彩色的导图会给人一种美感,不同的颜料、图像在不同的人记得库力代表着不同的意思,所以给导图扩张一些色彩时,你会感到到一种诚心的童趣。

图片 12

自然,画导图的最大重假若:带上你的大脑和你的想象力!

3.2、动笔画

图片 13

1)、用心沉凝并绘出骨干主旨(类似于小说的着力问题):

闭上眼睛,用心想一下你想要画的核心,结合这些主旨,你的大脑里会展示出怎么样的美术或者文字。

譬如思维导图书上的果品大旨,作者想到的是用一个篮子上边写着水果这多少个字来表明

然而一旦是当下的本身,右脑已经费很久了,这最简便易行的法子就是把主旨文字写下之后外面画一个圈圈。

图片 14

在纸的骨干画出您心里面想画的图片

白纸横放,在白纸的着力地方画大小长宽约5分米的图像。

图片 15

2)画主干:

着力是从中央大旨延伸出来的几条分支,是大的分类,类似于写著作时的大题目。主干线条要粗,需要肯定的曲线,由粗到细。

图片 16

骨干的画法可以协调计划,在粗线条的中间填上温馨喜好的色彩和绘画。

图片 17

图片 18

组合水果的大旨,你会想到如何呢?也许是橙子、苹果,香蕉,樱桃或者其他?

画思维导图,一般是从右上角的道岔先河,然后按顺时针的方向画。当然也有逆时针方向画的,这么些是同等对待的。这里也有一个小的注意点,主干需要紧密连接主题图,这意味着着思想与主题要旨精心相关,是一种放射性的思索。

3)画支干:

支干是从主干延伸出来的,是小的分类(类似于写著作时的小题目)。支干线条要细于主干。

图片 19

支干一般是一条条的画。比如说水果导图上的苹果,他联想到的大夫、夏娃、馅饼、蛇朝一个女人吐性子?这是意味着怎样?诱惑?可能两样的人有不同的领会。

图片 20

4)填写关键词

基于你联想到的事物,我们在核心和支行线条的顶端写上想到的重点词,从每一个重要词(医师)发散出更多的分层(走开)。分支的数额取决于你所想到的东西的多寡。这里需要注意的是主旨和分支之间所有不同层次的逻辑关系,需要不停锻练,才足以升官。

重在词的领到也急需特别注意。关键词一般为名词、动词、形容词,在构思导图上需要尽可能简单。

在线条上,尽量按照一线一词。每个独立的辞藻都有上千个可能的联想,每条线上只写一个词回给你带来联想的擅自。有一句话叫,一线一词,思想自由

5)在动脑筋导图上涂上您喜爱的情调和隶属的记得标签

图片 21

如此这般一幅关于水果的想想导图就画好了。其实想想导图的画法依然很简单的,一共有三个大的下面,分别是主导核心,线条(主干、分支)、文字(关键词)、图像、颜色。

DesignerNewsURL

DesignerNewsURL类包装网络访问URL

#import <Foundation/Foundation.h>

extern NSString* const baseURL;
extern NSString* const clientID;
extern NSString* const clientSecret;

@interface DesignerNewsURL : NSObject

+ (NSString*)loginURLString;
+ (NSString*)stroiesURLString;
+ (NSString*)storyIdURLStringWithId:(NSInteger)storyId;
+ (NSString*)storyUpvoteWithId:(NSInteger)storyId;
+ (NSString*)storyReplyWithId:(NSInteger)storyId;
+ (NSString*)commentUpvoteWithId:(NSInteger)commentId;
+ (NSString*)commentReplyWithId:(NSInteger)commentId;

@end

此地还有个技术就是在DesignerNewsURL.m心想事成文件有个原则编译,判断是在测试环境依然产品环境来决定baseURL的值,可以很有益于在测试环境与产品环境互相切换。

#ifndef TEST
NSString* const baseURL = @"https://api-news.layervault.com";
#else
NSString* const baseURL = @"http://localhost:12306";
#endif

NSString* const clientID = @"750ab22aac78be1c6d4bbe584f0e3477064f646720f327c5464bc127100a1a6d";
NSString* const clientSecret = @"53e3822c49287190768e009a8f8e55d09041c5bf26d0ef982693f215c72d87da";

四、思维导图有咋样用?

图片 22

思想导图其实是一个工具,代表着您大脑里面的想法。倘诺你控制了它的主旨画法,可以用来你需要的此外场所。

也就是说,你有哪些,就可以用在啥地方。因为它实质上是个大脑想法的一个表面表现。

可以用来阅读,写作、能够用来定制年度计划,可以用于旅游的光景导游词的梳理。

这是足以结合自己的急需去扩展的。

当你用于读书时,可以帮您急忙阅读,回想。

当你烦闷时,你可以用来自我的心态梳理。

当您出行旅游时,可以用心想导图整理导游词,或者结合当下的状态去梳理需要回想的情节。

当您做项目时管理,一张合计导图可以让你纵观全局。

它的功利莫过于您不要质疑,通过不断训练,你自己执行后得以逐步发现。

有一句话叫有用才会有用(郭立中先生名言)

图片 23

图片 24

分享案例1:思维导图记住导游词

享受一个老大幽默的例子吗。

有两遍我们带孩子去华雷斯的福冈陵玩,目标是愿意子女在玩的还要,对革命历史和博爱、三民主义等专出名词有肯定的摸底。去后边,我下载了一篇导游词,准备带到风景,边看边给孩子讲。

在列车上,我看了弹指间导游词,内容蛮多,好几页纸,有点看了后边忘了背后的感觉。于是自己从背包里拿了一张纸,整理了刹那间思路,画一张简易版的思想导图,协助自己知道,记念。

通过边写边画,读完导游词后感到思路清楚多了,知道麦迪逊陵是孙哈特福德先生安葬的地点,理解怎么孙嘉兴先生会采取在此安眠,他的重点考虑是何许;惠州陵的设计者是什么人,为何如此设计?加的夫陵由有什么样部分构成,下面又有如何有趣的故事。

图片 25

粗略的盘算导图

其次天带娃去常州陵时,一件奇怪的作业暴发了,我忘掉了带导游词,心里有些慌。不过既然事情爆发了,埋怨自己没啥用哈,只可以想法子去解决。想着想着,脑公里出现了这张思维导图,尽管很LOW,不过80%情节本身还记得,我告诉外甥怎么墓道两旁不是石像,而是雪松。是因为松树生命力强,不屈不挠,象征着孙先生的高雅质地和革命精神。为何是392个台阶,因为这暗喻了即刻有3亿9千2百万的同胞。

新生自己把这件事告诉了郭立中先生,他以为在此之前也有接近的痛感,指出我享受出来,并且让我去他的盘算导图群复训。这是本身第一次发现思维导图,原本是如此有趣的事务!

案例2,将合计导图用于断舍离课程学习

我备感思维导图很好地诠释了断、舍、离

断舍离原是扶桑人山下英子提出的一种现在不胜流行的家居整理方法。曾有一部高丽国电影“怦然心动的盘整魔法”讲述了一个女生员通过整治房间从而整理自己人生的故事。 
     
断舍离包括两个部分,舍(识别不需要,不佳受),心里清楚我毫不什么;断(专注于当时):声明自己要什么,集中精力干什么;离:怎么卖力达到这一个目的。

       
使用思维导图来阅读或者做速记时,首先会舍去不需要的片段,留下自己觉得重要的一部分,当整张思维导图完成时,我们会意识读书或者记笔记的目标已经高达,同时也记住了您需要学习的情节。

一旦您用于断舍离课程学习时也是一模一样啊。记录一下生存中的美好。

当打开这张合计导图时,我的笔触仿佛立马穿越到了2016年一月22日那一天。在漂亮的三合院,我遭遇了和蔼可亲的來永旭先生,遇上了伙伴ELian。她是一名专做思考导图的旅长,晓茜一位心情咨询师,会师对面识人术的ANNA,做大妈再启程平台的能妈,LISAEric森的教练,幽默好玩的东霞,会玩塔罗牌的丽英,佛缘的Monika,相当爱老婆的唯一帅哥張郡泽,和自家同一期待疗愈成长的SHE-RA.很多美妙的故事在我们中间时有暴发了,我首先次感受到了心文学的能力,有一种做完了心灵SPA的感觉

在此地我意识了我的能力,我相当感谢我的校官來永旭先生,他给了不少率先次,第一次线上分享,第一次让我协会线下沙龙活动,后续会有第一次做培训师,还有为数不少另外地点。他启发我,让自身不住地研讨许四个人生的可能。

回去导图这块,其实这张导图很初级,是本身的第十二张导图,有些小的先天不足,可是没什么,挺好的,一张真实的记录。

首先看,中心图,一只蚕蛹变成了蝴蝶。代表着我锐变,唯一的路是爱自己,通过断舍离,实现内在成长。

附带看分支:一般的道岔是从右上角起初看的,來永旭先生,活动的管理员、遇上的人,学到的措施、肿么办?为何有用,断舍离是怎么?其实从这张图的逻辑结构上看,当时的逻辑是相比粗放的,点都在,不过点和点之间的逻辑关系有些欠缺。可是记录下来就好。人方可没有完美起来,但是起头了,就会日益变好的。

图片 26

案例3、将合计导图用于POA课程学习

网友通常说,蓝心,你为啥可以有那么好的行重力呢?

事实上秘密在于POA课程的读书。

实在万分感谢橙子高校这一个平台,我的变动始于是从这么些平台来的,古典老师是一位生涯规划师,在收获上有顶级个体专栏。

遇上朱颖磊先生是因为橙子高校琼咪举行的一回线下活动。课程价格非凡公益,几十块钱,喝一杯咖啡的钱。朱颖磊先生是一位从500强公司里的老总,转行到培训师,现在又在塑造培训师的办事,他的活计经历非凡丰盛,让自家敬佩的是,他真正。

世家有没有察觉,我赶上的名师基本都是很公益的教授,郭立中先生,來永旭先生,还有朱颖磊先生,前面赶上的盘算导图的Elian、陌上花开、冥想师罗春娟还有有着大爱的尔玛先生,等等伙伴和爱人,其实她们有一个表征,吸引我的性状,公益、助人。

这多少个深深地抓住着自我。引领我走向一个公益的主旋律。

POA其实是一个公式,是一种合计方法

图片 27

增强行引力的意义,从数学公式上看亟待聚焦目标(少),给力的同伴(多)和章程(多)。

这节课除了说了什么增强行重力外,还有关于亲子教育和亲密关系相处的秘方,假若感兴趣,可以好雅观看这张合计导图哈。

图片 28

行为使得开发LoginClient

在编制代码往日,大家应超越想想怎么着筹划LoginClient类。首先依据Single
responsibility
principle
(责任单一原则),LoginClient一言九鼎承担用户登录的网络访问。需要提供一个接口,只要给定用户名(username)和密码(password),用户就能登录,由于自家是接纳RAC来处理回来结果,所以这一个接口重返RACSignal对象。

  • 制造一个LoginClientkiwi文件,编写对应行为。

Create LoginClient 1.png

Create LoginClient 2.png

SPEC_BEGIN(LoginClientSpec)

describe(@"LoginClient", ^{

    context(@"when user input correct username and password", ^{
      __block RACSignal *loginSignal;

      beforeEach(^{
          NSString *username = @"liuyaozhu13hao@163.com";
          NSString *password = @"freedom13";
          loginSignal = [LoginClient loginWithUsername:username password:password];
      });

      it(@"should return login signal that can't be nil", ^{
          [[loginSignal shouldNot] beNil];
      });

      it(@"should login successfully", ^{
          __block NSString *accessToken = nil;

          [loginSignal subscribeNext:^(NSString *x) {
              accessToken = x;
              NSLog(@"accessToken = %@", accessToken);
          }error:^(NSError *error) {
              [[accessToken shouldNot] beNil];
          } completed:^{
              [[accessToken shouldNot] beNil];
          } ];
      });

    });
});

SPEC_END

据悉三段式Given-When-Then讲述,下边代码我们得以领会为:在给定LoginClient对象,当用户输入正确的用户名和密码时,应该登录成功。
这时,由于还没创制LoginClient类,所以会不通过编译,创设LoginClient类,并编写它的伪实现,让LoginClientSpec.m由此编译。

LoginClient.h.png

LoginClient.m.png

运转测试,测试战败。

LoginClient Failed.png

  • 贯彻LoginClient,通过其测试

LoginClient.m .png

LoginClient Pass Test.png

  • 由于无冗余代码,无需重构

五、常见的题材

1、我掌握您画的导图挺美好的,我不会画画,所以我不会画;

实在我也未曾绘画基础,从前看画画的人,可认为不务正业了,不过当自家自己开班画基本图后,我发觉就算本人画的不得了,挺丑,然而我很享受这种画画的感觉,一种轻松快活的觉得。

自家画后,才通晓原来描绘是如此地可以!

其实我们在人生中,专门喜欢自己设限,别人好狠心,自身没学过,所以自己不会。我没充裕天赋,所以我不会。只是用羡慕的看法看着别人。

实在当您起初了,痛下决心做了,你意识,一切不难,而且你有精卫填海的对象时,整个社会风气都会帮你。这让自身记忆了安琪的学习力一书第二章节里的一句话。尽管你真正努力地走动,全世界都会为您让步!

2、思维导图是画给协调看的,不是别人。

有无数群友,特别相信我,会把她的率先张合计导图发给自己看。特别感谢他们的深信。

诚如自己都会问她一个题目,这张导图是您需要的吧?解决了你的题目啊?在画导图的经过你觉得喜笑颜开啊?假如是您需要的,也能透过这么些办法梳理心绪,或者记住了有些东西。这就是好的导图。导图是给自己看的,不是外人。当然假设你的导图是用以工作汇报时,这是亟需考虑旁人的要求的。

3、软件好依旧手绘好呢?

本条题目重重人问我。我一向感觉各有优势。软件版,是在网络上画的,字是电脑的字,不会含有自己的觉得。可是排版清晰,可以修改,适合网络分享。特别是东尼博赞的法定版本更是好。可以几个人搭档,更有甚者,可以直接与WORD,PPT相连接,做好导图后,可以一向分享。可是这一个是收费软件,如今,我们需要依据自己的急需来。普通的Xmind,百度脑图都得以满意我们一般人的要求了。

手绘思维导图,介于创意无限,与我连接相比强,这是自家的,独一无二的导图

尽管画得相比较慢,可是因为有手的参与,更能锻炼大脑。在画的过程中,专属的记得符号,线条上的留白,画画给予你的自由自在的觉得,这是总计机不可能替代的。这是自身爱不释手手绘的来头之一。

实质上,软件和手绘版各有可取,并有相关性。我曾见过自己的姊妹陌上花开教职工,将软件版思维导图和手绘导图放在一张图上,很好地接连了软件版和手绘的导图。不过达到老师的水平需要持续的勤学苦练哈。

4、大家怎么起来读书思想导图呢?

学学思想导图有众多艺术,找到适合自己的章程最关键。

A、假诺您的逻辑思维能力丰硕好,读东尼博赞的沉思导图,这本经典读物丰盛了。

与此同时需要逐字阅读往往阅读,我读过2遍,收获很大。

B、线上依旧线下报班学习,市面上有诸多课程哈,唯一专注的是开端提议跟着东尼博赞的管理师或者认证师学习,因为市面上有成百上千教育者并不领悟思维导图到底是如何,容易把学生带偏。

5、学习思想导图有什么样注意点?

考虑导图是一门技术课程,不是知识性课程,并不是说上一节课就足以搞定的,其实需要漫长坚持、刻意训练,才方可领略它的补益。

临场任何一个社群都是足以的,只要有一雨后春笋的同频伙伴在,互相援助就可以

实质上那是学任何一门技术的很快学习方法呢,在一个针锋相对安全的空中里,那时候的安全是其一场域是足以被人所采取的,你所做的,无论是好的,或者是不佳的,都可以被看见,被接到。在这么的条件下,你流连忘返地做协调喜欢的作业,受到他人的终将和称赞,当然还要也会有携带。

这么的章程会很适合学习。至少适合考拉型的本身去学学,提升。我是郭立中先生的思考导图课程的第二期学员,近日早已是第八期了,每一遍老学生都是可以免费参加复训的,我每听一遍,对思想导图又有例外的敞亮,这样已经坚韧不拔1年半了,今日的申报也好不容易一场学习总括吧,也能够是二零一七年的年份学习总计了。

Model层

是因为本次登陆请求服务端再次回到数据相比较简单,只是拿到access_token字段数据,所以不需要model来映射和存储数据。可是在得到六个Stories时,就会动用到model来拍卖。

感谢

本人很感谢自己的沉思导图郭立中先生,是在集团党校的相逢,让自己精晓了这么一个简约的读书工具,我也需要感谢自己的拼命,一步步地百折不挠,让自己的品位思维和垂直思维拿到一步步地开展,随着与心思学的结缘,得到了心智方面不大提高。

感谢自己的断舍离來永旭先生,您一回次拓宽了自我的本人界限,引领我向着未知领域去追究前行

谢谢POA的朱颖磊先生,您的独特的思索情势,让自家进一步有了行引力,也很是感谢您课程上有关人生的诠释,让我在亲密关系上有了很大的前进

谢谢我的好姐妹Elian和陌上花开,是你们随便自身是快意依旧痛苦,都可以即时听自己倾诉,给自身安慰和正好的拉扯;

感谢尔玛先生,您的大爱和接到程度是自己所崇拜的,您第一个享受了自家的团子,大力帮自己推广微课,在心思群里鼓励我,让自己痛快自由地赞助外人;

更亟待感谢我的同伴们,是你们长时间的陪伴,让自家遇见了一个实际的友爱。

出人意料发现自己再三回忘记了做自我介绍:

图片 29

骨子里,你只需要牢记我是一个乐于终身陪伴你学习成长的人,知道怎么二零一八年十二月13日分享呢?因为13象征着终身。我期待一生陪着您。

自己在二零一八年所有一些微梦想,也许你看过自家的心上人圈,您也足以知道,也可以过来帮忙我实现

图片 30

自身二〇一九年会做一些公益活动,其中一项是接纳思维导图拆解佛学书籍,其实这出自想帮朋友Elian,因为她爱好佛学,以思想导图的主意来赞助人家。我本想拆3本,可是出于特定的缘分变成了10多本,我遇见了法师,听了他关于正念的解读,遇上了一些居士,听她们说佛学怎么样转移了生活。我不懂,所以会学,会体会,会知道。在读的率先本书禅与新意,有诸如此类一个故事:

在美国的加州,有一种大树叫红杉树,红杉树是世界上可以长得高高的的植物,一棵树可以长到90米,我们见过吗?30层楼的莫大,这棵树该有多高啊,有些人恐怕会问了,你看可以长这么高的植物,它的根一定扎得很深很深吧,其实加州的红杉树,它是浅根型的植物,它的根扎得并不深,那么为何狂风暴雨来的时候,这颗红杉树不会倒呢,因为红杉树有一个特性,就是凝聚的长在一道,长成一片森林,在地底下,它的根虽然长得不深,不过在地底下,它们是并行的根就会牢牢相连,就会形成一片根的网络,除非是狂风暴雨,大到可以掀开整个地面,否则没有一棵红杉树会倒下,那些优势在哪儿吗?因为不用扎太深的根,所以红杉树可以将札根的这个能量用来提高伸展,而且更可以更便宜,更敏捷,更大方的吸纳养分,这就是她们力所能及长得特别高的紧要原因之一,

同样的,大家同频的伙伴们,大家也要像它们等同,大家得以互相辅助,来连成一片生命之根的网络。大家都是小人物,我们得以相互辅助,相互匡助,共同提升,一起成长,共学共好!

连续共学共好直播间会推出系列公益课程,希望大家多享受温馨的学习心体面会,携手共同成人。

持续公益的分享:

网友A.sunshineHJX 分享:非暴力交换的学习体会

网友心情学老师麦大大分享:积极心绪学在生活中的利用

在布里斯(Rhys)托(Stowe)出境游遇见的社宣部兵马俑教师张晓暮来分享:兵马俑与铜马车的故事(领会一下历史知识)

更多公益分享等着您来报名哈!

更多移动请关注

图片 31

眼下群众号里一片空白,大家的前程,等待大家联合去创设!欢迎您一起来玩!

我相信相信的能力,一切是最好的配置,

明日的分享到此停止,分外感谢您的聆听!祝我们晚安!

Controller与ViewModel层

controller是拍卖用户交互的输入,日常自己都会将处理用户交互的逻辑、数据绑定和数量校验都交给ViewModel来精简controller代码,同时最大程度地复用业务逻辑的代码。
咱俩先想起用户登陆时的步骤:1.
用户先输入email和密码,唯有email和密码符合格式要求时才能点击按钮。2.
用户成功登陆后,跳转到故事列表主页。
俺们先分析一下什么促成步骤1,
想要对email和密码举行验证,必须要监听它们多少个值的生成,所以需要对emailTextFieldpasswordTextField使用RAC展开多少绑定。

创建LoginViewControllerSpeckiwi文件,测试绑定行为代码如下:

SPEC_BEGIN(LoginViewControllerSpec)

describe(@"LoginViewController", ^{
    __block LoginViewController *controller;

    beforeEach(^{
        controller = [UIViewController loadViewControllerWithIdentifierForMainStoryboard:@"LoginViewController"];
        [controller view];
    });

    afterEach(^{
        controller = nil;
    });

    describe(@"Email Text Field", ^{
        context(@"when touch text field", ^{
            it(@"should not be nil", ^{
                [[controller.emailTextField shouldNot] beNil];
            });
        });

        context(@"when text field's text is hello", ^{
            it(@"shoud euqal view model's email property", ^{
                controller.emailTextField.text = @"hello";
                [controller.emailTextField sendActionsForControlEvents:UIControlEventEditingChanged];
                [[controller.viewModel.email should] equal:@"hello"];
            });
        });
    });

    describe(@"Password Text Field", ^{
        context(@"when touch text field", ^{
            it(@"should not be nil", ^{
                [[controller.passwordTextField shouldNot] beNil];
            });
        });

        context(@"when text field' text is hello", ^{
            it(@"should equal view model's password property", ^{
                controller.passwordTextField.text = @"hello";
                [controller.passwordTextField sendActionsForControlEvents:UIControlEventEditingChanged];

                [[controller.viewModel.password should] equal:@"hello"];
            });
        });
    });
});

SPEC_END

此地有多个关键点,一个是从Storyboard中加载controller,否则不可能博取emailText菲尔德(Field)和password,假若利用手写UI代码就不需要了。另一个就是emailText菲尔德(Field)或passwordTextField必须调用sendActionsForControlEvents:UIControlEventEditingChanged方法,才能触发textField的text属性改变。

编译失利后,在LoginViewController.m编写- (void)bindViewModel措施通过测试

RAC(self.viewModel, email) = self.emailTextField.rac_textSignal;
RAC(self.viewModel, password) = self.passwordTextField.rac_textSignal;

落实完数据绑定行为后,接下去要多上将验,交给LoginViewModel来处理。创建LoginViewModelSpec.m文件,提供emailpassword属性给LoginViewModel,重回验证结果的RACSignal,测试注脚行为代码如下:

SPEC_BEGIN(LoginViewModelSpec)

describe(@"LoginViewModel", ^{
    // Initialize
    __block LoginViewModel *viewModel;

    beforeEach(^{
        viewModel = [[LoginViewModel alloc] init];
    });

    afterEach(^{
        viewModel = nil;
    });

    context(@"when email and password is valid", ^{
        it(@"should get valid signal", ^{
            viewModel.email = @"liuyaozhu13hao@163.com";
            viewModel.password = @"123456";

            __block BOOL result;

            [[viewModel checkEmailPasswordSignal] subscribeNext:^(id x) {
                result = [x boolValue];
            } completed:^{
                [[theValue(result) should] beYes];
            }];
        });
    });

    context(@"when email is valid, but password is invalid", ^{
        it(@"should get invalid signal", ^{
            viewModel.email = @"liuyaozhu13hao@163.com";
            viewModel.password = @"1";

            __block BOOL result;

            [[viewModel checkEmailPasswordSignal] subscribeNext:^(id x) {
                result = [x boolValue];
            } completed:^{
                [[theValue(result) shouldNot] beYes];
            }];
        });
    });

    context(@"when password is valid, but email is invalid", ^{
        it(@"should get invalid signal", ^{
            viewModel.email = @"liuyaozhu";
            viewModel.password = @"123456";

            __block BOOL result;
            [[viewModel checkEmailPasswordSignal] subscribeNext:^(id x) {
                result = [x boolValue];
            } completed:^{
                [[theValue(result) shouldNot] beYes];
            }];
        });
    });
});

SPEC_END

编译败北后(已经创设LoginViewModel类),添加- (RACSignal*)checkEmailPasswordSignal并落实认证数据,通过测试

- (RACSignal*)checkEmailPasswordSignal
{
    RACSignal* emailSignal = RACObserve(self, email);
    RACSignal* passwordSignal = RACObserve(self, password);

    return [RACSignal combineLatest:@[ emailSignal, passwordSignal ] reduce:^(NSString* email, NSString* password) {
        BOOL result = [email isValidEmail] && [password isValidPassword];

        return @(result);
    }];
}

说到底索要在LoginViewModel始建属性为loginButtonCommandRACCommand来拍卖点击登陆按钮的相互。在LoginViewControllerSpec.m测试loginButton.rac_command无法为空

describe(@"Login Button", ^{
      context(@"when load view", ^{
            it(@"should be not nil", ^{
                [[controller.loginButton shouldNot] beNil];
            });

            it(@"should have rac command that not be nil", ^{
                [[controller.loginButton.rac_command shouldNot] beNil];
            });
      });
 });

测试败北,在LoginViewController.m编写- (void)bindViewModel主意以下代码片段

self.loginButton.rac_command = self.viewModel.loginButtonCommand;

LoginViewModel.m推迟起头化loginButtonCommand属性

#pragma mark - Lazy initialization
- (RACCommand*)loginButtonCommand
{
    if (!_loginButtonCommand) {
        _loginButtonCommand = [[RACCommand alloc] initWithEnabled:[self checkEmailPasswordSignal] signalBlock:^RACSignal * (id input) {
            self.active = YES;

            return [[LoginClient loginWithUsername:self.email password:self.password] doNext:^(NSString *token) {
                self.active = NO;
                // Save the token
                [LocalStore saveToken:token];
                // Dismiss view controller and fetch data, reload
                self.dismissBlock();
            }];
        }];
    }

    return _loginButtonCommand;
}

透过测试,完成登陆基本流程,至于登陆成功后咋样回到故事列表页面,那里不详细介绍,各位可以经过翻阅工程代码便可以取得答案。

总结

近日一段时间都再看关于敏捷开发的图书(用户故事与飞跃方法硝烟中的Scrum和XP,
浅析极限编程),对神速开发很感兴趣,但意识很少集团或博客介绍咋样举办敏捷开发iOS,所以在网上搜集一些素材,发现有广大优质的推行(测试驱动开发,重构,持续集成测试,增量设计,增量计划)值得去读书,通过投机对快捷开发中各类实践的知晓来重写这多少个Designer
News,这么些Designer
News功用还没任何成功,希望各位看完这篇作品尝试以如此情势来完成所有app。如若自己多少意见或执行精晓有误,请各位多多率领。

扩展阅读

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图