4.0归档解档 swift_openstack swift 2.20.0 2.21.0 - CSDN
  • swift3.0归档和解

    2016-10-12 23:23:28
    1.对用户的模型数据(自定义类:HCUserModel)进行归档和解 1.1 需要遵循NSCoding协议 1.2 需要实现func encode(with aCoder: NSCoder){}归档方法 1.3需要实现 required init(coder aDecoder: NSCoder){}解档...

    1.对用户的模型数据(自定义类:HCUserModel)进行归档和解档

    1.1 需要遵循NSCoding协议

    1.2 需要实现func encode(with aCoder: NSCoder){}归档方法

    1.3需要实现 required init(coder aDecoder: NSCoder){}解档方法

    1.4 重写init方法

    2.HCUserModel的数据内容如下:

    import UIKit


    class HCUserModel: NSObject,NSCoding {

        

        var id:Int?

        var nickname:String?

        var phone:String?

        var account:String?

        var password:String?

        var type:Int?

        var icon:String?

        var attentionnumber:Int?

        var registertime:String?

        var qrcode:String?

        var signature:String?

        var dynamicstruts:Int?

        var score:Int?

        

        // MARK:- 处理需要归档的字段

        func encode(with aCoder:NSCoder) {

            

            aCoder.encode(id, forKey:"id")

            aCoder.encode(nickname, forKey:"nickname")

            aCoder.encode(phone, forKey:"phone")

            aCoder.encode(account, forKey:"account")

            aCoder.encode(password, forKey:"password")

            aCoder.encode(type, forKey:"type")

            aCoder.encode(icon, forKey:"icon")

            aCoder.encode(attentionnumber, forKey:"attentionnumber")

            aCoder.encode(registertime, forKey:"registertime")

            aCoder.encode(qrcode, forKey:"qrcode")

            aCoder.encode(signature, forKey:"signature")

            aCoder.encode(dynamicstruts, forKey:"dynamicstruts")

            aCoder.encode(score, forKey:"score")

        }

        

        // MARK:- 处理需要解档的字段

        requiredinit(coder aDecoder:NSCoder) {

            super.init()

            id = aDecoder.decodeObject(forKey:"id")as?Int

            nickname = aDecoder.decodeObject(forKey:"nickname")as?String

            phone = aDecoder.decodeObject(forKey:"phone")as?String

            account = aDecoder.decodeObject(forKey:"account")as?String

            password = aDecoder.decodeObject(forKey:"password")as?String

            type = aDecoder.decodeObject(forKey:"type")as?Int

            icon = aDecoder.decodeObject(forKey:"icon")as?String

            attentionnumber = aDecoder.decodeObject(forKey:"attentionnumber")as? Int

            registertime = aDecoder.decodeObject(forKey:"registertime")as?String

            qrcode = aDecoder.decodeObject(forKey:"qrcode")as?String

            signature = aDecoder.decodeObject(forKey:"signature")as?String

            dynamicstruts = aDecoder.decodeObject(forKey:"dynamicstruts")as? Int

            score = aDecoder.decodeObject(forKey:"score")as?Int

        }

        overrideinit() {

            super.init()

        }

    }


    3. 实现归档把模型保存到本地Document文件夹:
    3.1 获取本地Document路径,一般路径都设为全局变量,方便解档直接使用:

    let userAccountPath ="\(NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,

    FileManager.SearchPathDomainMask.userDomainMask,true).first!)/userAccount.data"


    3.2 对获取到的模型进行归档操作,要注意模型必须是确定的类型,如果是可选类型会报发送未识别的消息的错误(切记)

    NSKeyedArchiver.archiveRootObject(userModel!, toFile:userAccountPath)


    4.实现解档从Document文件夹获取本地模型数据

    4.1 判断Document文件夹下是否有已保存好的模型,有的话就解档取出模型

     if NSKeyedUnarchiver.unarchiveObject(withFile:userAccountPath) !=nil {

                

                userModel =NSKeyedUnarchiver.unarchiveObject(withFile:userAccountPath)as? HCUserModel

            }





    展开全文
  • Swift4.0入门视频教程,课程内容包含Swift入门知识、数据类型(元组、Dictionary、运算符)、流程控制、函数、类与对象、扩展协议、常见概念、实用进阶、案例实战。 1、119节大容量课程:包含了Swift4.0语言大部分...
    Swift4.0入门实例视频教程—4744人已学习 
    课程介绍    
    201712291158262922.
        Swift4.0入门视频教程,课程内容包含Swift入门知识、数据类型(元组、Dictionary、运算符)、流程控制、函数、类与对象、扩展协议、常见概念、实用进阶、案例实战。 1、119节大容量课程:包含了Swift4.0语言大部分知识点; 2、创新的教学模式:手把手教您iOS开发技术入门,一看就懂,一学就会; 3、完美贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标; 4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间; 5、视频短小精悍:即方便于您的学习和记忆,也方便日后对功能的检索;
    课程收益
        掌握Swift 4.0语言,并通过一整套实例教程,使学员掌握从生成证书、创建app、架构、开发、打包上传、提交审核等整个开发流程!
    讲师介绍
        李发展更多讲师课程
        10年以上IT行业工作经验、三年以上IT行业教学经验。丰富的项目经验和授课经验,授课形式不拘一格。熟悉JAVA,iOS,Swift,平面设计、网页设计、Javascript开发等技术。代表作品:拥有百万下载量、千份五星好评的iOS应用《互动教程 for Photoshop》、《互动教程 for Xcode》、《互动教程 for Illustrator》、《互动教程 for Pages》等。
    课程大纲
      第1章:入门知识
        1.iOS项目模板的介绍  6:37
        2.使用Playground学习Swift  2:55
        3.Swift语言中的常量和变量  1:53
        4.Swift的标识符和关键字  1:57
        5.Swift的表达式Expressions  1:29
        6.给Swift代码添加注释语句  2:12
        7.Swift的几个打印输出语句  1:42
        8.在控制台输出类的实例及其属性  1:42
      第2章:数据类型
        1.Swift的(Boolean)布尔类型  2:40
        2.Swift的(Int)整形类型  4:45
        3.Swift的(Float)和(Double)浮点类型  4:47
        4.字符串(String)及对字符(Characters)的遍历  2:26
        5.Swift字符串的使用详解  5:39
        6.Swift中的元组(Tuples)  2:04
        7.基本数据类型之间的互相转换  2:52
        8.一维数组(Array)的使用详解  2:57
        9.多维数组的创建和遍历  1:49
        10.数组的几种遍历方式  2:09
        11.字典(Dictionary)的使用详解  5:12
        12.Swift的一元、二元和三元运算符  2:52
        13.Swift的位运算符和防溢出运算符  2:26
        14.比较运算符和区间运算符  3:10
      第3章:流程控制
        1.使用for-in循环遍历数组  3:36
        2.使用循环语句获得序列中的最小值  2:56
        3.switch-case语句的实例解析  2:27
        4.continue、break和fallthrough的区别  3:16
        5.while和repeat-where循环语句  2:35
        6.if和if-let判断语句的使用解析  3:17
      第4章:函数
        1.函数func以及函数的参数和返回值  3:22
        2.函数的外部参数名  2:24
        3.创建拥有任意数量参数的函数  2:05
        4.函数的输入输出inout参数解析  1:54
        5.给函数的参数设置默认的取值  1:52
        6.使用函数作为另一个函数的参数  3:00
        7.函数类型的解析  2:10
        8.使用函数类型作为函数的返回类型  2:10
        9.函数可以拥有多个返回值  2:04
        10.藏在函数内部的函数  1:47
        11.递归函数的使用解析  1:58
        12.Swift那些非常实用的内部函数  4:58
      第5章:类与对象
        1.Swift的枚举(enum)类型及遍历  2:46
        2.给枚举类型添加方法  2:11
        3.Swift的结构(struct)类型及其下标(subscript)  3:11
        4.类(class)的初始化方法、属性和方法  2:46
        5.类的引用(reference)特征  2:07
        6.类和结构两个类型的比较  2:48
        7.类属性的set和get方法解析  1:53
        8.类属性的willSet和didSet方法解析  2:21
        9.类析构方法(deinit)的使用  1:29
        10.给类添加下标(subscript)  2:04
        11.类的静态方法(class func)  1:51
        12.将一个类的实例作为另一个类的属性  2:03
        13.类的继承以及方法的重写(override)  2:18
        14.父类在实例类型转化时的应用  2:02
        15.使用is语句检查实例的类型  3:44
        16.使用Any表示任意值类型  2:25
      第6章:扩展协议
        1.使用扩展(extension)扩展类型的属性  1:57
        2.使用extension对方法进行扩展  1:37
        3.使用协议(protocol)进行方法的声明  4:28
        4.问号?和感叹号!的用法解析  5:27
        5.Swift中的闭包(Closure)详解  4:29
        6.Swift语言中的泛型编程  3:18
        7.Swift的do-try-catch错误处理模式  4:48
        8.实例的引用特征和Swift的内存管理  2:19
        9.实例的交叉引用和弱引用(weak)  3:00
        10.Swift的懒加载(lazy initialization)使用解析  2:28
      第7章:常见概念
        1.范围Range、ClosedRange和NSRange的使用  2:43
        2.点CGPoint和变形CGAffineTransform的使用  2:34
        3.尺寸CGSize的使用详解  2:35
        4.范围CGRect的使用详解  3:00
        5.使用NSString对字符串进行各种操作  3:28
        6.日期Date和DateFormatter日期的格式化  4:59
        7.日历Calendar和日期组件DateComponents  1:47
        8.日历Calendar和时区TimeZone  1:54
        9.使用定时组件Timer执行定时任务  4:01
        10.使用UserDefaults和归档方式存取用户数据  6:16
        11.路径URL的使用详解  2:24
        12.使用DispatchGroup管理线程组  1:48
        13.使用UIScreen查询设备屏幕信息  2:09
        14.使用UIColor设置界面组件的颜色属性  3:11
      第8章:实用进阶
        1.Swift语言中的两种单例模式  3:05
        2.Swift语言中的三种消息传递模式  7:05
        3.闭包在定时任务、动画和线程中的使用  3:59
        4.通过protocol在两个对象中进行消息传递  8:25
        5.通过间接代理进行对象间的消息传递  6:04
        6.通过属性进行对象间的消息传递  6:25
        7.使用通知的方法进行对象间的数据传递  6:14
        8.使用performSegue在故事板页面之间进行数据传递  11:11
        9.Swift中的栈Stack和队列Queue详解  5:22
        10.Swift中的链表LinkedList详解  2:58
        11.使用Swift创建一个二叉树BinaryTreeNode  3:51
        12.冒泡排序算法的Swift实现  9:41
        13.选择排序算法的Swift实现  7:58
        14.快速排序算法的Swift实现  10:34
        15.插入排序算法的Swift实现  6:25
        16.希尔排序算法的Swift实现  6:55
        17.归并排序算法的Swift实现  8:57
        18.基数排序算法的Swift实现  8:29
        19.堆排序算法的Swift实现  9:00
      第9章:完整实例
        1.在iTunesConnect中创建产品ACTHelper  10:37
        2.在Xcode9中创建新项目ACTHelper  4:49
        3.创建开发证书和发布证书及其它文件  14:23
        4.在ACTHelper项目中使用CocoaPod管理插件  4:00
        5.创建BaseViewController作为控制器的基类  9:10
        6.创建App的欢迎页面  8:59
        7.登陆页面:创建自定义视图及相关组件  19:43
        8.登陆页面:创建自定义表单Row以及基控制器  16:27
        9.创建用户登陆页面  23:34
        10.用户注册账号信息的输入和短信验证码  31:31
        11.用户注册头像和科目信息输入页面  20:27
        12.用户注册考试成绩输入页面及相关自定义组件  24:49
        13.试题解析页面及相关自定义组件  18:28
        14.试题科目列表及答案列表等自定义组件  27:49
        15.创建试题解析列表页面和试卷选择页面  38:26
        16.创建试题详情页面和浮动菜单组件  35:53
        17.试题原文显示页面和数学公式的渲染  14:32
        18.账号设置列表页面和分享、反馈、评分功能  13:05
        19.会员个人信息设置页面和登出功能  14:03
        20.App发布前的设置以及打包、上传和提交审核  11:46
    大家可以点击【查看详情】查看我的课程
    展开全文
  • Swift 4 在 Swift 3 的基础上,提供了更强大的稳健性和稳定性,为 Swift 3 提供源码兼容性,对标准库进行改进,并添加了归档和序列化等功能。 你可以通过观看 WWDC 2017: What’s New in Swift 或完整发行说明...

    Swift 4 现已正式发布!Swift 4 在 Swift 3 的基础上,提供了更强大的稳健性和稳定性,为 Swift 3 提供源码兼容性,对标准库进行改进,并添加了归档和序列化等功能。

    你可以通过观看 WWDC 2017: What’s New in Swift 或完整发行说明快速了解 Swift 4 功能概述。

    一、语言更新

    String

    Swift 4 包含一个更快、更易使用的 String 实现,保留了 Unicode 的正确性,并新增了对创建、使用和管理子字符串的支持。

    详情:

    集合

    Swift 4 改进了创建、使用和管理集合类型。

    详情:

    归档和序列化

    Swift 4 支持结构化和枚举类型的归档,并可以对外部格式(如 JSON 和 plist )进行类型安全的序列化。

    详情:

    其他

    二、新兼容模式

    Swift 4 发布后,你可能不需要修改代码就可以使用新版本的编译器。编译器支持两种语言模式:

    • Swift 3.2:这种模式下,编译器将接受使用 Swift 3.x 编译器构建的大多数源代码。为了提供这种级别的源兼容性,先前存在的 API(作为 Apple 提供的标准库或 API 的一部分)的更新将不会出现在此模式中。 Swift 4 中的大部分新语言特性都以这种语言模式提供。

    • Swift 4.0:此模式包含所有 Swift 4.0语言和 API 更改,部分项目可能需要进行源迁移。

    语言模式由 -swift-version 指定给编译器,由 Swift 包管理器和 Xcode 自动处理。

    详情:

    三、包管理器升级

    Swift 4 为 Swift Package Manager 引入了新的工作流功能和更完整的 API :

    • 在 Tag 你的第一个正式版本之前,可以轻松多包开发,或者在多个软件包的分支上一起工作。

    • 可选择控制发布给用户的包。

    • 新的 Package API 允许软件包指定一些新的设置,使作者能够更好地控制软件包的构建方式,以及如何在磁盘上组织源码。总的来说,用于创建包的 API 现在更为清晰,同时保留了与旧包的源兼容性。

    • 在 macOS 上,Swift 软件包的构建现在会在一个防止网络访问和文件系统修改的沙箱中进行,有助于减轻恶意程序的影响。

    详情:

    四、相关地址

    文档

    • Swift 4.0 相关文档已在官网更新,在苹果的 iBooks 商店也可免费下载。

    下载

    展开全文
  • Swift 4是苹果计划于2017年秋季推出的最新版本,其主要重点是提供与Swift 3代码的源兼容性,并努力实现ABI稳定性。 本文重点介绍对Swift的更改将对您的代码产生最大的影响。 而且,让我们开始吧!

    本文由陈云峰翻译,转载请注明。

    注意:本教程将使用Swift 4版本捆绑在Xcode 9 beta 1中。

    Swift 4

    Swift 4是苹果计划于2017年秋季推出的最新版本,其主要重点是提供与Swift 3代码的源兼容性,并努力实现ABI稳定性。

    本文重点介绍对Swift的更改将对您的代码产生最大的影响。 而且,让我们开始吧!

    入门

    Swift 4包含在Xcode 9中。您可以从Apple的开发者门户下载最新版本的Xcode 9(您必须拥有一个活跃的开发者帐户)。 每个Xcode测试版将在发布时捆绑最新的Swift 4快照。

    在阅读时,您会注意到[SE-xxxx]格式的链接。 这些链接将带您到相关的Swift Evolution提案。 如果您想了解有关任何主题的更多信息,请务必查看。

    我建议您在操场上尝试每个Swift 4功能或更新。 这将有助于巩固您的头脑中的知识,并使您有能力深入了解每个主题。 试图扩大/打破他们的例子来玩弄这些例子。 玩得开心!

    注意:本文将针对每个Xcode测试版进行更新。 如果您使用不同的Swift快照,这里的代码不能保证工作。

    迁移到Swift 4

    从Swift 3迁移到4将比从2.2到3更麻烦。一般来说, 大多数变化是相加的,不应该需要大量的个人感觉。 因此,Swift迁移工具将为您处理大部分更改。

    Xcode 9同时支持Swift 4以及Swift 3.2中的Swift 3中间版本。 您的项目中的每个目标可以是Swift 3.2或Swift 4,如果需要,您可以逐个迁移。 然而,转换为Swift 3.2并不是完全免费的 – 您可能需要更新代码部分才能与新SDK兼容,并且由于Swift尚未ABI稳定,因此您将需要使用Xcode 9重新编译依赖项。

    当您准备迁移到Swift 4时,Xcode再次提供了一个迁移工具来帮助您。 在Xcode中,您可以导航到编辑/转换/到当前Swift语法…以启动转换工具。

    选择要转换的目标后,Xcode将提示您对Objective-C推理的偏好。 选择推荐的选项通过限制引用来减少二进制大小(有关此主题的更多信息,请查看下面的限制@objc推断 )

    为了更好地了解您的代码中期望的更改,我们将首先介绍Swift 4中的API更改。

    API更改

    在跳转到Swift 4中介绍的补充之前,我们先来看看现有API所做的更改/改进。

    字符串

    String在Swift 4中获得了很多很好的爱。这个提案包含很多变化,所以让我们分解最大的。 [SE-0163] :

    如果你感觉怀旧,字符串再次收藏,就像他们是Swift 2.0之前一样。 此更改消除了对String上的String数组的需求。 您现在可以直接在String对象上进行迭代:

    let galaxy = "Milky Way "
    for char in galaxy {
      print(char)
    }

    是!

    您不仅可以通过String逻辑迭代,还可以从SequenceCollection获取所有的响铃和口哨:

    galaxy.count       // 11
    galaxy.isEmpty     // false
    galaxy.dropFirst() // "ilky Way "
    String(galaxy.reversed()) // " yaW ykliM"
    
    // Filter out any none ASCII characters
    galaxy.filter { char in
      let isASCII = char.unicodeScalars.reduce(true, { $0 && $1.isASCII })
      return isASCII
    } // "Milky Way "

    上面的ASCII示例显示了对Character 。 您现在可以直接从Character访问Character 。 以前,您需要实例化一个新的String [SE-0178] 。

    另外还有一个是StringProtocol 。 它声明了以前在String上声明的大部分功能。 这种变化的原因是改善切片如何工作。 Swift 4添加了Substring类型,用于引用String上的子序列。

    StringSubstring实现了StringProtocol使它们具有几乎相同的功能:

    // Grab a subsequence of String
    let endIndex = galaxy.index(galaxy.startIndex, offsetBy: 3)
    var milkSubstring = galaxy[galaxy.startIndex...endIndex]   // "Milk"
    type(of: milkSubstring)   // Substring.Type
    
    // Concatenate a String onto a Substring
    milkSubstring += ""     // "Milk"
    
    // Create a String from a Substring
    let milkString = String(milkSubstring) // "Milk"

    另一个很大的改进是String如何解释图形集合。 此解决方案来自于Unicode 9的改编。以前,由多个代码点组成的Unicode字符会导致count大于1.常见的情况是具有所选肤色的表情符号。 以下是几个示例,显示前后行为:

    "‍".count // Now: 1, Before: 2
    "".count // Now: 1, Before: 2
    "‍❤️‍‍".count // Now: 1, Before, 4

    这只是“ 字符串宣言”中提到的更改的一个子集。 您可以阅读有关将来希望看到的原始动机和提出的解决方案。

    词典和集合

    至于Collection类型, SetDictionary并不总是最直观的。 幸运的是,斯威夫特队给了他们一些非常需要的爱[SE-0165] 。

    基于序列的初始化
    列表首先是从一系列键值对(元组)创建一个字典的能力:

    let nearestStarNames = ["Proxima Centauri", "Alpha Centauri A", "Alpha Centauri B", "Barnard's Star", "Wolf 359"]
    let nearestStarDistances = [4.24, 4.37, 4.37, 5.96, 7.78]
    
    // Dictionary from sequence of keys-values
    let starDistanceDict = Dictionary(uniqueKeysWithValues: zip(nearestStarNames, nearestStarDistances)) 
    // ["Wolf 359": 7.78, "Alpha Centauri B": 4.37, "Proxima Centauri": 4.24, "Alpha Centauri A": 4.37, "Barnard's Star": 5.96]

    重复键处理
    您现在可以使用重复的键来处理初始化字典的任何方式。 这有助于避免覆盖键值对,而不会有任何问题:

    // Random vote of people's favorite stars
    let favoriteStarVotes = ["Alpha Centauri A", "Wolf 359", "Alpha Centauri A", "Barnard's Star"]
    
    // Merging keys with closure for conflicts
    let mergedKeysAndValues = Dictionary(zip(favoriteStarVotes, repeatElement(1, count: favoriteStarVotes.count)), uniquingKeysWith: +) // ["Barnard's Star": 1, "Alpha Centauri A": 2, "Wolf 359": 1]

    上面的代码使用zip和速记+来通过添加两个冲突的值来解析重复的键。

    注意:如果您不熟悉zip ,您可以在Apple的Swift文档中快速了解它

    过滤
    DictionarySet现在都可以将结果过滤到原始类型的新对象中:

    // Filtering results into dictionary rather than array of tuples
    let closeStars = starDistanceDict.filter { $0.value < 5.0 }
    closeStars // Dictionary: ["Proxima Centauri": 4.24, "Alpha Centauri A": 4.37, "Alpha Centauri B": 4.37]

    字典映射
    Dictionary获得了一个非常有用的方法来直接映射其值:

    // Mapping values directly resulting in a dictionary
    let mappedCloseStars = closeStars.mapValues { "\($0)" }
    mappedCloseStars // ["Proxima Centauri": "4.24", "Alpha Centauri A": "4.37", "Alpha Centauri B": "4.37"]

    字典默认值
    在Dictionary上访问某个值时,常见的做法是使用nil coalescing运算符给出默认值,以防数值为nil 。 在Swift 4中,这变得更加清洁,并允许您在线突变中做一些真棒:

    // Subscript with a default value
    let siriusDistance = mappedCloseStars["Wolf 359", default: "unknown"] // "unknown"
    
    // Subscript with a default value used for mutating
    var starWordsCount: [String: Int] = [:]
    for starName in nearestStarNames {
      let numWords = starName.split(separator: " ").count
      starWordsCount[starName, default: 0] += numWords // Amazing 
    }
    starWordsCount // ["Wolf 359": 2, "Alpha Centauri B": 3, "Proxima Centauri": 2, "Alpha Centauri A": 3, "Barnard's Star": 2]

    以前,这种类型的突变将需要在一个blo肿的if-let语句中包装。 在Swift 4中,可能是一条线!

    字典分组
    另一个令人惊讶的有用的补充是从Sequence Dictionary并将它们分组到桶中的能力:

    // Grouping sequences by computed key
    let starsByFirstLetter = Dictionary(grouping: nearestStarNames) { $0.first! }
    
    // ["B": ["Barnard's Star"], "A": ["Alpha Centauri A", "Alpha Centauri B"], "W": ["Wolf 359"], "P": ["Proxima Centauri"]]

    当通过特定模式对数据进行分组时,这很方便。

    预留容量
    SequenceDictionary现在都具有明确保留容量的能力。

    // Improved Set/Dictionary capacity reservation
    starWordsCount.capacity  // 6
    starWordsCount.reserveCapacity(20) // reserves at _least_ 20 elements of capacity
    starWordsCount.capacity // 24
    

    这些类型的重新分配可能是一项昂贵的任务。 使用reserveCapacity(_:)是一个简单的方法来提高性能,当您了解需要存储多少数据时。

    这是一大堆信息,所以绝对检查这两种类型,并寻找使用这些添加剂来调整代码的方法。

    私有访问修饰符

    Swift 3的一个元素,一些不太喜欢的是添加fileprivate 。 从理论上讲,这是非常好的,但实际上它的使用往往会令人困惑。 目标是在成员本身中使用private的,并且在您想要在同一文件中的成员共享访问的情况下很少使用fileprivate 。

    问题是Swift鼓励使用扩展将代码分解成逻辑组。 扩展被认为在原始成员声明范围之外,这导致对fileprivate的广泛需求。

    Swift 4通过在类型和所述类型的任何扩展之间共享相同的访问控制范围来实现原始意图。 这只适用于相同的源文件[SE-0169] :

    struct SpaceCraft {
      private let warpCode: String
    
      init(warpCode: String) {
        self.warpCode = warpCode
      }
    }
    
    extension SpaceCraft {
      func goToWarpSpeed(warpCode: String) {
        if warpCode == self.warpCode { // Error in Swift 3 unless warpCode is fileprivate
          print("Do it Scotty!")
        }
      }
    }
    
    let enterprise = SpaceCraft(warpCode: "KirkIsCool")
    //enterprise.warpCode  // error: 'warpCode' is inaccessible due to 'private' protection level
    enterprise.goToWarpSpeed(warpCode: "KirkIsCool") // "Do it Scotty!"

    这允许您使用fileprivate作为其预期目的,而不是作为带状编码组织。

    新增API

    现在让我们来看看Swift 4的新功能。这些更改不应该打破你现有的代码,因为它们是简单的加法。

    归档和序列化

    谷物人

    到目前为止,在Swift中,为了序列化和归档您的自定义类型,您必须跳过一些环。对于class类型,您需要对NSObject进行子类化并实现NSCoding协议。

    structenum这样的值类型需要许多hacks,例如创建一个可以扩展NSObjectNSCoding的子对象。

    Swift 4通过将序列化到所有三种Swift类型[SE-0166]来解决这个问题:

    struct CuriosityLog: Codable {
      enum Discovery: String, Codable {
        case rock, water, martian
      }
    
      var sol: Int
      var discoveries: [Discovery]
    }
    
    // Create a log entry for Mars sol 42
    let logSol42 = CuriosityLog(sol: 42, discoveries: [.rock, .rock, .rock, .rock])

    在这个例子中,您可以看到,使Swift类型可Encodable和可Decodable所需的唯一Decodable是实现可编Codable协议。 如果所有属性都是Codable ,则协议实现由编译器自动生成。

    本文由陈云峰翻译,转载请注明。

    要实际编码对象,您需要将其传递给编码器。 Swift编码器正在Swift 4中积极实施。每个编码器根据不同的方案对您的对象进行编码[SE-0167] ( 注意:此提案的一部分仍在开发中):

    let jsonEncoder = JSONEncoder() // One currently available encoder
    
    // Encode the data
    let jsonData = try jsonEncoder.encode(logSol42)
    // Create a String from the data
    let jsonString = String(data: jsonData, encoding: .utf8) // "{"sol":42,"discoveries":["rock","rock","rock","rock"]}"

    这采取了一个对象,并自动将其编码为JSON对象。 确保查看JSONEncoder暴露的属性来自定义其输出。

    该过程的最后一部分是将数据解码为具体对象:

    let jsonDecoder = JSONDecoder() // Pair decoder to JSONEncoder
    
    // Attempt to decode the data to a CuriosityLog object
    let decodedLog = try jsonDecoder.decode(CuriosityLog.self, from: jsonData)
    decodedLog.sol         // 42
    decodedLog.discoveries // [rock, rock, rock, rock]

    使用Swift 4编码/解码,您可以在Swift中获得预期的类型安全性,而不依赖于@objc协议的开销和限制。

    键值编码

    到目前为止,您可以参考函数而不调用它们,因为函数是Swift中的闭包。 你不能做的是保持对属性的引用,而不实际访问属性保存的底层数据。

    对Swift 4来说,令人兴奋的补充是能够引用类型的关键路径来获取/设置实例的基础值[SE-0161] :

    struct Lightsaber {
      enum Color {
        case blue, green, red
      }
      let color: Color
    }
    
    class ForceUser {
      var name: String
      var lightsaber: Lightsaber
      var master: ForceUser?
    
      init(name: String, lightsaber: Lightsaber, master: ForceUser? = nil) {
        self.name = name
        self.lightsaber = lightsaber
        self.master = master
      }
    }
    
    let sidious = ForceUser(name: "Darth Sidious", lightsaber: Lightsaber(color: .red))
    let obiwan = ForceUser(name: "Obi-Wan Kenobi", lightsaber: Lightsaber(color: .blue))
    let anakin = ForceUser(name: "Anakin Skywalker", lightsaber: Lightsaber(color: .blue), master: obiwan)

    在这里,您将通过设置他们的名字,光剑和主人来创建强制用户的几个实例。 要创建一个关键路径,您只需使用一个反斜杠后跟您感兴趣的属性:

    // Create reference to the ForceUser.name key path
    let nameKeyPath = \ForceUser.name
    
    // Access the value from key path on instance
    let obiwanName = obiwan[keyPath: nameKeyPath]  // "Obi-Wan Kenobi"

    在这种情况下,您正在为ForceUsername属性创建一个关键路径。 然后,通过将其传递给新的下标keyPath来使用此键路径。 默认情况下,此下标现在可用于每种类型。

    以下是使用关键路径深入到子对象,设置属性和构建关键路径引用的更多示例:

    // Use keypath directly inline and to drill down to sub objects
    let anakinSaberColor = anakin[keyPath: \ForceUser.lightsaber.color]  // blue
    
    // Access a property on the object returned by key path
    let masterKeyPath = \ForceUser.master
    let anakinMasterName = anakin[keyPath: masterKeyPath]?.name  // "Obi-Wan Kenobi"
    
    // Change Anakin to the dark side using key path as a setter
    anakin[keyPath: masterKeyPath] = sidious
    anakin.master?.name // Darth Sidious
    
    // Note: not currently working, but works in some situations
    // Append a key path to an existing path
    //let masterNameKeyPath = masterKeyPath.appending(path: \ForceUser.name)
    //anakin[keyPath: masterKeyPath] // "Darth Sidious"

    Swift的关键路径的美丽在于它们是强类型的! 没有更多的Objective-C字符串风格混乱!

    多行字符串文字

    许多编程语言的一个非常常见的特征是能够创建多行字符串文字。 Swift 4通过在三个引号[SE-0168]中包装文本来添加这个简单而有用的语法:

    let star = "⭐️"
    let introString = """
      A long time ago in a galaxy far,
      far away....
    
      You could write multi-lined strings
      without "escaping" single quotes.
    
      The indentation of the closing quotes
           below deside where the text line
      begins.
    
      You can even dynamically add values
      from properties: \(star)
      """
    print(introString) // prints the string exactly as written above with the value of star

    这在构建XML / JSON消息或构建长格式的文本以在UI中显示时非常有用。

    单面范围

    为了减少冗长度并提高可读性,标准库现在可以使用单面范围[SE-0172]来推断起始和终点索引。

    派上用场的一种方法是创建一个从索引到集合的开始或结束索引的范围:

    / Collection Subscript
    var planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
    let outsideAsteroidBelt = planets[4...] // Before: planets[4..<planets.endIndex]
    let firstThree = planets[..<4]          // Before: planets[planets.startIndex..<4]

    如您所见,单面范围减少了明确指定开始索引或结束索引的需要。

    无限序列
    当起始索引为可数类型时,它们还允许您定义无限Sequence :

    // Infinite range: 1...infinity
    var numberedPlanets = Array(zip(1..., planets))
    print(numberedPlanets) // [(1, "Mercury"), (2, "Venus"), ..., (8, "Neptune")]
    
    planets.append("Pluto")
    numberedPlanets = Array(zip(1..., planets))
    print(numberedPlanets) // [(1, "Mercury"), (2, "Venus"), ..., (9, "Pluto")]

    模式匹配
    单面范围的另一个很好的用途是模式匹配:

    // Pattern matching
    
    func temperature(planetNumber: Int) {
      switch planetNumber {
      case ...2: // anything less than or equal to 2
        print("Too hot")
      case 4...: // anything greater than or equal to 4
        print("Too cold")
      default:
        print("Justtttt right")
      }
    }
    
    temperature(planetNumber: 3) // Earth

    通用下标

    下标是使数据类型以简洁方式可访问的重要组成部分。 为了提高其有用性,下标现在可以是通用的[SE-0148] :

    struct GenericDictionary<Key: Hashable, Value> {
      private var data: [Key: Value]
    
      init(data: [Key: Value]) {
        self.data = data
      }
    
      subscript<T>(key: Key) -> T? {
        return data[key] as? T
      }
    }

    在这个例子中,返回类型是通用的。 你可以使用这个通用的下标,如下所示:

    // Dictionary of type: [String: Any]
    var earthData = GenericDictionary(data: ["name": "Earth", "population": 7500000000, "moons": 1])
    
    // Automatically infers return type without "as? String"
    let name: String? = earthData["name"]
    
    // Automatically infers return type without "as? Int"
    let population: Int? = earthData["population"]

    返回类型不仅可以是通用的,而且实际的下标类型也可以是通用的:

    extension GenericDictionary {
      subscript<Keys: Sequence>(keys: Keys) -> [Value] where Keys.Iterator.Element == Key {
        var values: [Value] = []
        for key in keys {
          if let value = data[key] {
            values.append(value)
          }
        }
        return values
      }
    }
    
    // Array subscript value
    let nameAndMoons = earthData[["moons", "name"]]        // [1, "Earth"]
    // Set subscript value
    let nameAndMoons2 = earthData[Set(["moons", "name"])]  // [1, "Earth"]

    在这个例子中,你可以看到,传递两个不同的Sequence类型( ArraySet )会导致一个数组的各自的值。

    更多更新

    它处理了Swift 4中最大的变化。现在让我们通过一些较小的位和块来更快速地进行一些。

    MutableCollection.swapAt(_:_ )

    MutableCollection现在具有mutate方法swapAt(_:_:) ,就像它的声音一样; 交换给定索引值[SE-0173] :

    // Very basic bubble sort with an in-place swap
    func bubbleSort<T: Comparable>(_ array: [T]) -> [T] {
      var sortedArray = array
      for i in 0..<sortedArray.count - 1 {
        for j in 1..<sortedArray.count {
          if sortedArray[j-1] > sortedArray[j] {
            sortedArray.swapAt(j-1, j) // New MutableCollection method
          }
        }
      }
      return sortedArray
    }
    
    bubbleSort([4, 3, 2, 1, 0]) // [0, 1, 2, 3, 4]

    相关类型限制

    您现在可以使用where子句来限制关联类型[SE-0142] :

    protocol MyProtocol {
      associatedtype Element
      associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == Iterator.Element
    }

    使用协议约束,许多associatedtype声明可以直接约束其值,而不必跳过环。

    类和协议存在

    最终将其从Objective-C转换为Swift的功能是定义符合类和一组协议的类型的能力[SE-0156] :

    protocol MyProtocol { }
    class View { }
    class ViewSubclass: View, MyProtocol { }
    
    class MyClass {
      var delegate: (View & MyProtocol)?
    }
    
    let myClass = MyClass()
    //myClass.delegate = View() // error: cannot assign value of type 'View' to type '(View & MyProtocol)?'
    myClass.delegate = ViewSubclass()

    限制@objc推论

    要将Objective-C或Swift API公开,请使用@objc编译器属性。 在许多情况下,Swift编译器为您推断出这一点。 质量推理的三个主要问题是:

      1. 潜在的二进制大小显着增加
      2. 知道何时@objc

    被推断不明显

    1. 不经意间创建Objective-C选择器碰撞的机会增加。

    Swift 4通过限制@objc [SE-0160]的推论来解决这个问题。 这意味着在需要Objective-C的完整动态调度功能的情况下,您需要使用@objc 。

    您需要进行这些更改的几个示例包括private方法, dynamic声明和NSObject子类的任何方法。

    NSNumber桥接

    NSNumber和Swift数字之间已经有很多时髦的行为,这些行为一直困扰着语言太久。 幸运的是,Swift 4压缩了这些错误[SE-0170] 。

    以下是一个示例演示示例:

    let n = NSNumber(value: 999)
    let v = n as? UInt8 // Swift 4: nil, Swift 3: 231

    Swift 3中的奇怪行为表明,如果数字溢出,则从0开始。在此示例中,999%2 ^ 8 = 231。

    Swift 4通过强制可选的转换来解决问题,只有当数字可以在包含类型中被安全地表达时才返回值。

    Swift包管理器

    在过去几个月里,Swift Package Manager已经有了一些更新。 一些最大的变化包括:

    • 从分支或提交哈希采购依赖关系
    • 更多控制可接受的包版本
    • 用更为常见的解决方案替代非直观的钉扎命令
    • 能够定义用于编译的Swift版本
    • 指定每个目标的源文件的位置

    这些都是获得SPM所需要的重大步骤。 SPM还有很长的路要走,但是我们可以通过保持积极的建议来帮助形成一个。

    有关最近解决的提案的全面了解,请查看“ Swift 4软件包管理器更新” 。

    从哪里走?

    还在举行视频
    想要更快学习吗?节省时间与我们的视频课程

    Swift语言多年来一直在增长和成熟。 提案过程和社区参与使得跟踪管道中出现的变化非常容易。 它也使东方任何一个人直接影响演变。

    随着Swift 4中的这些变化,我们终于到了一个ABI稳定性就在拐角处的地方。 升级Swift版本的痛苦越来越小。 构建性能和工具大大提高。 在苹果生态系统之外使用Swift变得越来越可行。 并且想一想,我们可能只是从一个直观的实现中完全重写String的一些;]。

    斯威夫特还有更多的东西。 要保持最新的所有更改,请确保查看以下资源:

    你对Swift 4有什么想法? 你最喜欢的变化是什么? 你还想从语言中看到什么? 你有没有找到新的和令人兴奋的东西,这里没有涵盖? 让我们在下面的评论中知道!

    本文由陈云峰翻译,转载请注明。原文地址

    展开全文
  • Swift 4.0 Codable 序列化

    2018-09-21 14:39:35
    如果要将一个对象持久化,需要...Swift 4中引入了Codable协议,可以大大减轻了我们的工作量。我们只需要让需要序列化的对象符合Codable协议即可,不用再写任何其他的代码。 struct Language: Codable { var name...

    如果要将一个对象持久化,需要把这个对象序列化。过去的做法是实现NSCoding协议,但实现NSCoding协议的代码写起来很繁琐,尤其是当属性非常多的时候。

    Swift 4中引入了Codable协议,可以大大减轻了我们的工作量。我们只需要让需要序列化的对象符合Codable协议即可,不用再写任何其他的代码。

    struct Language: Codable  {
          var name: String
          var version:Int
    }

    1,Encode操作

    我们可以直接把符合了Codable协议的对象encode成JSON或者PropertyList

    let swift = Labguage(name:"Swift",version:4)
    
    //encode对象
    let encodedData = try JSONEncoder().encode(swift)
    
    //从encoded对象获取String
    let jsonString = String(data:encodedData,encoding: .utf8)
    print(jsonString)
    
    //打印结果为:
    Optional("{\"name\":\"Swift\",\"version\":4}")

    2,Decode操作

    let decodedData = try JSONDecoder().decode(Language.self,from:encodeData)
    print(decodedData.name,decodedData.version)

     

    展开全文
  • 免费下载地址:https://itunes.apple.com/cn/app/id1320746678◈ 不看视频不看书,手把手带您学习Swift语言◈ 利用手指来互动式学习Swift 4.0◈ 无痛上手,比观看视频、阅读书籍更加有趣、更加有效的学习方式 ◈ 变...
  • NSCoding 这种方式是OC中就有的,比较老的方式,并且使用限制是只能是calss,然后实现NSCoding,对于struct是不能使用的。 internal func encode(with aCoder: NSCoder) { var count :UInt32 = 0 ...
  • Swift 4.0 描述: 使用 NSCoding 进行 archive 和 unarchive 归档。旧的工程名叫 A, 新的工程名叫 B。A 曾经在设备上运行过,并使用 NSUserDefault 针对序列化后的Data进行持久化保存。 当更换工程名后,B 在运行...
  • swift数据持久化--归档

    2019-06-17 18:13:30
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 在OC中,以及Swift4.0之前,系统一直没有一套数据解析的方法。在Swift4.0后,终于推出了Codable协议,可实现json数据和数据模型的相互转换。 首先来下 Codable ,它其实是一个组合协议,有 Decodable 和 Encodable ...
  • Swift之沙盒与数据存储 应用沙盒结构分析 1、应用程序包:包含了所有的资源文件和可执行文件 2、Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录 3、tmp:保存应用运行时所...
  • //转载:http://www.helloswift.com.cn/swiftmanual/2015/0208/3486.html 应用沙盒结构分析 1、应用程序包:包含了所有的资源文件和可执行文件 2、Documents:保存应用运行时生成的需要持久化的数据,...
  • HandyJSON是swift开发中常用的SON解析框架。该库由阿里巴巴技术团队研发,已经过了大量的实战积累。不再赘述。 地址:https://github.com/alibaba/HandyJSON 版本参考 针对不同的IDE环境和Swift版本,HandyJSON的...
  • Swift访问Foundation框架

    2016-01-21 22:51:50
    Foundation框架提供了大量的界面无关的api,为 Core Foundation 框架的许多功能提供了 Objective-C和Swift 的封装。 下面的代码,基于Swift,对Foundation常用的api进行了简单的访问。
  • 97 Things Every Programmer Should Know Gitee 下载 Github 下载 SourceForge 下载 A Java Reference (UCB CS61b Textbook) Gitee 下载 Github 下载 SourceForge 下载 AI Cheat Sheet ......
  • 蓝牙4.0蓝牙4.0是2012年最新蓝牙版本,是3.0的升级版本;较3.0版本更省电、成本低、3毫秒低延迟、超长有效连接距离、AES-128加密等;通常用在蓝牙耳机、蓝牙音箱等设备上。蓝牙技术联盟(Bluetooth SIG)2010年7月7日...
1 2 3 4 5 ... 13
收藏数 251
精华内容 100
关键字:

4.0归档解档 swift