IOS Apps 开发(Swift)(7)——Define Your Data Model
来源:互联网 发布:网站域名到期怎么回事 编辑:程序博客网 时间:2024/05/19 10:41
前言:网上一直没有找到用Swift开发IOS的好的教程,所以找了官网的文档翻译一下算了。如有错误欢迎指正。博主首发CSDN,mcf171专栏。
博客链接:mcf171的博客
原文链接:Define Your Data Model
——————————————————————————————
在本次课程中,我们将定义和测试 FoodTracker 的数据模型。一个数据模型是用来展现anpp的信息结构。
学习目标
在本次课程中,你可以了解到:
- 创建一个数据模型
- 在自定义类中创建一个可失败的初始化器
- 理解可失败和不可失败的初始化器
- 通过运行单元测试来检测数据模型
创建数据模型
现在我们要创建一个数据模型来存储我们的菜品场景信息。因此我们需要定义一个简单的类,包括名字、照片和打分
创建一个新的数据模型类
1、选择 File > New > File (or press Command-N).
2、在左边的对话框选择iOS下的Source
3、选择Swift文件,点击下一步
我们之前创建RatingControl类的时候是使用不同的步骤(iOS > Source > Cocoa Touch Class),这是因为现在我们是创建一个基类,不需要从其他类继承。
4、输入名字Meal
5、选择保存位置同时勾选测试
Xcode将创建一个Meal.swift的文件
在Swift中,我们能通过字符串来保存名字,使用UIImage保存图片,使用Int保存打分。因为图片不一定有,所以我们对于UIImage使用Optional类型
定义菜品的数据类型
1、返回标准编辑框
2、打开Meal.swift
3、修改import
import UIKit
默认情况下Swift文件引入的是 Foundation 框架,因此我们可以使用 Foundation 数据结构。 因为我们接下来是会用来自UIKit 框架的类,所以我们需要将UIKit引入到我们的代码中。同时引入 UIKit 也允许我们访问Foundation中的数据,所以我们可以所见为一行代码。
4、在import语句下写如下代码
class Meal { // MARK: Properties var name: String var photo: UIImage? var rating: Int}
代码定义了基本的属性值。
5、在上述代码下,添加初始化器
// MARK: Initialization init(name: String, photo: UIImage?, rating: Int) {}
初始化器是在一个类进行实例化的时候调用的方法。
6、在初始化器中加入以下代码
// Initialize stored properties.self.name = nameself.photo = photoself.rating = rating
如果没有使用正确的值来创建Meal会发生什么呢?比如说一个空的名字或者一个负数分数。我们需要返回一个nil来表明这个对象不能被创建。并且设置默认值。
7、在初始化器的最后我们添加 if 语句来检测是否合法
// Initialization should fail if there is no name or if the rating is negative.if name.isEmpty || rating < 0 { return nil}
因为初始化器现在可能返回 nil ,所以我们需要表明在初始化器表明
8、点击错误提示,选择 fix-it来修补错误
init?(name: String, photo: UIImage?, rating: Int) {
可失败的初始化器的声明形式就是如上所示,也就是意味初始化器可能返回空值。
到目前为止,我们的初始化器应该如下:
// MARK: Initialization init?(name: String, photo: UIImage?, rating: Int) { // Initialize stored properties. self.name = name self.photo = photo self.rating = rating // Initialization should fail if there is no name or if the rating is negative. if name.isEmpty || rating < 0 { return nil }}
里程碑:选择Product > Build (or pressing Command-B)编译工程。虽然我们还没有使用这个类,但是可以通过编译来检测是否我们有语法上的错误。
测试数据
尽管我们的数据模型已经建立了,但是我们还没有将这个数据模型整合到我们的App中。因此很难说我们就百分百的正确完成了这个数据模型。我们可能会在运行时碰到一些我们没有考虑到的边界情况。
查看FoodTracker的单元测试文件
2、打开FoodTrackerTest.swift
花几分钟理解一下下述代码
import UIKitimport XCTest class FoodTrackerTests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // This is an example of a functional test case. XCTAssert(true, "Pass") } func testPerformanceExample() { // This is an example of a performance test case. self.measureBlock() { // Put the code you want to measure the time of here. } } }
XCTest 框架是 Xcode的测试框架。单元测试本身也是一个类。FoodTrackerTests继承了XCTestCase。注释解释了了setUp和tearDown方法的用处
我们要写的主要代码是功能测试——检测是否能产生我们期望的值、和性能测试——我们的代码能否像我们期望的那样运行。因为我们没有写过任何性能密集型的代码,所以我们只需要测试功能性。
针对菜品对象初始化器写单元测试
1、在FoodTrackerTests.swift中删除测试模板
import UIKitimport XCTest class FoodTrackerTests: XCTestCase { }
在本次课程中我们不需要任何模板
2、在最后一个花括号增加如下注释
// MARK: FoodTracker Tests
3、在注视下增加单元测试方法
// Tests to confirm that the Meal initializer returns when no name or a negative rating is provided.func testMealInitialization() {}
4、首先增加一个能通过的测试用例。
// Success case.let potentialItem = Meal(name: "Newest meal", photo: nil, rating: 5)XCTAssertNotNil(potentialItem)
XCTAssertNotNil用来测试Meal对象是否在初始化后为nil,也就是意味着初始化器成功的创建了一个Meal对象。
5、现在增加一个失败的测试用例
// Failure cases.let noName = Meal(name: "", photo: nil, rating: 0)XCTAssertNil(noName, "Empty name is invalid")
XCTAssertNIl 则断言一个对象是nil。在这个测试用例中对象是nil因为我们的没有输出名字。
6、现在增加一个测试用例,这个测试用里会返回一个nil的对象,但是我们断言对象不是nil
let badRating = Meal(name: "Really bad rating", photo: nil, rating: -1)XCTAssertNotNil(badRating)
最终我们的testMealInitialization方法为:
// Tests to confirm that the Meal initializer returns when no name or a negative rating is provided.func testMealInitialization() { // Success case. let potentialItem = Meal(name: "Newest meal", photo: nil, rating: 5) XCTAssertNotNil(potentialItem) // Failure cases. let noName = Meal(name: "", photo: nil, rating: 0) XCTAssertNil(noName, "Empty name is invalid") let badRating = Meal(name: "Really bad rating", photo: nil, rating: -1) XCTAssertNotNil(badRating)}
我们可以通过Command + U 来运行我们的单元测试。或者我们可以运行一个单独的测试。最后一个测试用例会报错,因为我们知道他是nil但是断言为非nil
运行 testMealInitialzation单元测试
1、打开FoodTrackerTests.swift 找到testMealInitialization
2、在测试方法的左边找到一个菱形
3、将我们的鼠标移动到菱形块上,从而变成一个小的运行按钮
4、点击这个按钮
里程碑:当app运行单元测试的时候,前面两个测试用例会通过,最后一个会失败
正如我们看到的,单元测试可以帮助我们捕捉代码的错误地方,如果我们期望在最后的测试用例中Meal对象不是nil,那么我们能够在测试中捕捉错误。
修复测试用例
1、找到FoodTrackerTests.swift文件中的testMealInitialization方法
2、将最后一行改为
XCTAssertNil(badRating, "Negative ratings are invalid, be positive")testMealInitialization方法最后为:
// Tests to confirm that the Meal initializer returns when no name or a negative rating is provided.func testMealInitialization() { // Success case. let potentialItem = Meal(name: "Newest meal", photo: nil, rating: 5) XCTAssertNotNil(potentialItem) // Failure cases. let noName = Meal(name: "", photo: nil, rating: 0) XCTAssertNil(noName, "Empty name is invalid") let badRating = Meal(name: "Really bad rating", photo: nil, rating: -1) XCTAssertNil(badRating, "Negative ratings are invalid, be positive")}里程碑:再次运行测试用例的时候,所有测试用例都通过了
测试用例是我们代码中必要的一部分,因为他可以帮厨我们捕捉到我们可能忽视的错误。每个测试都需要检测特殊的,基本的行为。付过我们写的测试用例是非常长和复杂的,那么非常难追踪到发生错误的准确位置
ps:本课程工程文件Download File
- IOS Apps 开发(Swift)(7)——Define Your Data Model
- iOS Apps 开发(Swift)(11)——Persist Data
- iOS Apps 开发(Swift)(9)——Implement Navigation
- IOS Apps 开发(Swift)(2)——Learn the Essentials of Swift(1)
- IOS Apps 开发(Swift)(2)——Learn the Essentials of Swift(2)
- IOS Apps 开发(Swift)(3)——Build a Basic UI(1)
- IOS Apps 开发(Swift)(3)——Build a Basic UI(2)
- IOS Apps 开发(Swift)(4)——Connect the UI to Code(1)
- IOS Apps 开发(Swift)(4)——Connect the UI to Code(2)
- IOS Apps 开发(Swift)(6)——Implement a Custom Control(1)
- IOS Apps 开发(Swift)(6)——Implement a Custom Control(2)
- IOS Apps 开发(Swift)(1)——Jump Right In
- IOS Apps 开发(Swift)(5)——Work with View Controllers
- IOS Apps 开发(Swift)(8)——Create a Table View
- iOS Apps 开发(Swift)(10)——Implement Edit and Delete Behavior
- Swift语言IOS8开发战记10.Data Model
- iOS开发(Swift)——代理
- ios开发——swift
- 播放收音机 CD放音
- android 沉浸式状态栏(像ios那样的状态栏与应用统一颜色样式)
- leetcode82. Remove Duplicates from Sorted List II
- HTTP状态码
- altium 原理图更新UNIQUE ID一样怎么办
- IOS Apps 开发(Swift)(7)——Define Your Data Model
- 解决安装ECshop时PHP版本大于5.2时的问题
- 《数据结构与算法分析(c描述》—— 快速排序
- 整数转换成字符串
- 系统自动布局
- 框架开发原理/类加载器加载配置文件
- 一个前端工程师的面试经历
- 关于Jpgraph 的中文乱码问题
- spark运算结果写入hbase及优化