Tag: json

运行时中的动态TabBar项-iOS(Swift)

假设您有一个同时提供免费和高级内容的应用程序。 显然,您不希望免费用户访问针对高级用户的内容。 例如,我们正在向用户提供在线视频课程。 免费用户可以访问和流媒体免费视频。 高级用户可以流式传输所有视频,下载视频,访问社区论坛并提出问题与解答。 根据用户的计划,我们有一个API可以提供该用户可用的功能列表。 例如,考虑API的JSON响应如下所示。 JSON响应(免费用户): { “计划”:“免费”, “功能”:[“视频”,“个人资料”] } JSON响应(高级用户): { “ plan”:“ PAID”, “功能”:[“视频”,“论坛”, “下载”, “轮廓” ] } 解析完上述JSON响应后,我们将获得功能列表。 然后,我们将迭代并将不同的TabBar项目添加到UITabBarController。 让我们创建一个枚举来定义一组功能。 这提供了当前版本应用程序的所有可用功能。 枚举功能:字符串{ 案例视频=“视频” 案例下载=“下载” 案例论坛=“ FORUMS” 案例档案=“ PROFILE” } 现在,我们从JSON响应中获得了免费用户和付费用户的功能列表。 让我们开始迭代视图控制器以显示在UITabBarController中。 为所有功能选项卡加载视图控制器 上面的代码似乎有很多字符串和重复的代码。 我们可以通过涉及一种新类型来重构它。 让我们创建一个TabItem类型来封装所有信息,并使它看起来更干净。 提取常用属性以显示“选项卡项目” 使用TabItem类型,我们将所有字符串提取到一个类型中,并创建了静态TabItem以定义不同的选项卡。 另外,我包括了order属性,以使选项卡项保持我们想要的顺序。 我还在TabItem中添加了一个辅助方法,以从相应的故事板上加载视图控制器。 加载“功能”选项卡的视图控制器的助手方法 使用上述方法,我们可以将TabItem类型转换为要加载的ViewController。 这将有助于消除重复的代码。 加载用于运行时功能列表的所有视图控制器的超级简单方法。 将所有TabItem添加到数组中之后,我使用顺序对其进行了排序,还将它们转换为ViewController。 而已。 我们完了。 多田!! 🎉 改进之处: 无需对ViewControllers名称进行硬编码,我们可以按照我在此处说明的方式从类型中提取:https://medium.com/@dinaraja/load-view-controllers-effortless-swift-dd49f11f1d99 […]

带有Encoder和Encodable的JSON

Swift 4带来了一种更加原生的方式来编码和解码实例,并内置了对每个人最喜欢的基于文本的格式的支持:JSON! 我们不使用所有的编码和解码源代码,而是采用一种不同的方法,并逐步通过一个简单的示例:单个Int实例如何通过JSONEncoder变成JSON数据? 从那里,我们应该能够更进一步,了解其他原始类型,数组,字典等是如何编码的。 封存 NSCoding作为Cocoa的一部分已经存储和检索数据很长时间了。 令人振奋的消息是,由于NSKeyedArchiver已有15年的历史了,Apple终于宣布弃用NSArchiver 。 😜 一个好主意是,如果可以对诸如字符串和数字之类的单个实例进行编码和解码 ,则可以存档和取消存档整个对象图。 编码所有事物 在Swift标准库中,除了编码 器之外,还有一些可编码的东西。 可编码是一种协议。 符合类型可以将自身编码为其他表示形式。 编码器也是一种协议。 编码器负责将可Encodable内容转换为其他格式,例如JSON或XML。 Encodable类似于NSCoding但作为Swift协议,您的Swift结构和枚举也可以加入聚会。 类似地,尽管Encoder还是协议而不是抽象类,但它与NSCoder对应。 一个简单的整数 您不能使用JSONEncoder编码裸标量,而是需要顶级数组或字典。 为简单起见,让我们从编码包含单个整数[42]的数组开始。 let encoder = JSONEncoder() let jsonData = try! encoder.encode([42]) 首先,我们实例化JSONEncoder ,然后使用数组在其上调用encode() 。 那里发生了什么事? // JSONEncoder.swift open func encode(_ value: T) throws -> Data { let encoder = _JSONEncoder(options: self.options) encode()方法采用一些Encodable值,并返回原始JSON Data 。 […]

Swift4中自动解码的性能

在很多情况下,您将面临通过网络发送或接收数据(或仅保存/加载文件中的自定义对象)的问题。 而且,当然,有几种不同的技术可以对JSON进行序列化/反序列化-您可以自己完成操作,也可以使用第三方框架。 最后,Apple提供了新的编码和解码自定义类型。 到目前为止,您的数据类型变得可编码和可解码,以与JSON等外部表示兼容。 它提出了极其简单明了的方法,减少了代码并节省了时间。 是不是很酷? 好… 测量解码自定义类型 不幸的是,我们没有生活在一个完美的世界中。 有时需要处理带有很多胖对象的胖JSON,而我们对此无能为力。 让我们比较一下通过新的API自动解码自定义类型和手动解码(意味着完全手动解码,而不是“ init(来自解码器:解码器)”)。 我已经创建了简单的结构`Writer`。 它符合`Codable`,并且可以用`JSONDecoder`解码。 也可以使用执行手动解码的init(dictionary :[String:Any] ) `对该对象进行解码。 测试环境和配置: iPhone 7,iOS 11.2 构建配置:发布 优化级别:[-Ofast] struct作者:可编码{ var名称:字符串? var email:字符串? var contact:字符串? var years:整数? var isPublic:布尔? } 苹果还为支持“可编码”的对象提供了自己的“手动编码和解码”实现。 如文档中所述: 如果您的Swift类型的结构与其编码形式的结构不同,则可以提供Encodable和Decodable的自定义实现,以定义自己的编码和解码逻辑。 因此,为了测试结构,添加了扩展名`init(from解码器:Decoder)`。 扩展作家:可解码{ 枚举CodingKeys:字符串,CodingKey { 案例名称 案例电子邮件 案例联系 案例年 案例是公开的 } init(来自解码器:解码器)抛出{ 让值=尝试解码器。容器(keyedBy:CodingKeys.self) 名称=尝试? values.decode(String.self,forKey:.name) 电子邮件=尝试? values.decode(String.self,forKey:.email) 联系人=试试? […]

使用TDD构建JSON解析器

最近,一个朋友需要解析具有自定义格式的文件,并问我如何实现该文件。 我的脑海立刻被我上大学的记忆所淹没。 因此,我回答了他,我首先将制作一个词法分析器,该词法分析器将使用文本文件并生成令牌,然后创建一个状态机,该状态机会将令牌作为状态转换的事件,并且每个转换都会建立一点点解析的结果,直到达到终端状态为止。 我对TDD感兴趣已经有一段时间了,但是没有机会尝试一下,因此这看起来像是一个制作东西的好机会。 在本系列文章中,我将尝试使用TDD创建JSON解析器,并尝试在每个步骤中共享我的尽管流程。 让我们一起学习🙂 在我们开始之前,有一些想法: 我将生产代码和测试代码都写在一个文件中,以便于在它们之间进行切换。 我们将从仅解析没有空格和换行符的JSON文件开始。 我们稍后会处理。 我知道Foundation库有一个非常优化的JSON解析库,我们在Swift 4中添加了Codable协议,涵盖了JSON解析,但是我主要是作为练习来做的。 对于那些不熟悉的人,我将尝试遵循TDD的三个规则: 除非要通过失败的单元测试,否则不允许编写任何生产代码。 您不能编写任何足以使单元测试失败的单元测试。 而编译失败就是失败。 您不能编写任何足以通过一项失败的单元测试的生产代码。 我们首先创建带有单元测试的可可触摸框架项目,然后删除默认测试 对于最退化的情况,第一个测试应该始终是。 因为我们没有在任何地方传递可选参数,所以我们可以创建的最简陋的字符串是空字符串。 现在,我们只说如果解析失败,则返回nil。 现在我们处于红色阶段,我们必须通过此测试通过以使其再次变为绿色。 第一个错误是JSONParser不存在。 因此,我们创建了它。 让我们上一堂课。 现在,对parse方法的调用不存在。 我们可以通过创建一个接受字符串并返回Any的方法解析来解决此问题。 。 空字符串应该失败,因为它不是有效的JSON,因此我们只返回nil 。 在JSON RFC中,它表示JSON可以是以下之一: Boolean , Number , String , Array , Object 。 让我们从最简单的解析器开始:一个布尔值。 首先,我们将解决真实情况: TDD通过最简单的方式产生更好的结果,因此让我们尝试最简单的方法来验证值是否为true 。 这次我们有机会在测试代码中进行一些重构 。 解析器分配开始重复,并且可能会在每个测试中重复。 将其移至设置功能似乎是个不错的机会。 然后我们有: 列表上的下一个是处理错误的布尔值。 我们以与真实案例相同的方式进行测试: 我们做了一个if来检查是否正确 。 […]

迅捷4 –可腐化和可编码💼

大家好🤚🏼 我已经几个月没写新文章了,原因有很多(第一个是WWDC’18),但是我现在不谈论这个。 去吧去吧🤟🏼 编码和解码自定义类型 使您的数据类型可编码和可解码,以与JSON等外部表示兼容。 Swift标准库定义了一种用于数据编码和解码的标准化方法。 您通过在自定义类型上实现可Encodable和可Decodable协议来采用这种方法。 采用这些协议可以使Encoder和Decoder协议的实现获取您的数据,并在外部表示形式(例如JSON或属性列表)中对数据进行编码或解码。 为了同时支持编码和解码,请声明对Codable符合Codable ,后者将Encodable和Decodable协议结合在一起。 此过程称为使您的类型可编码 。 来源:点击这里 如您所见,这些是处理原始JSON片段最重要的事情。 在某些情况下, 一些人认为对于复杂的JSON结构很难。 在我这方面,这是不可接受的。 特别是,在Apple推出Encodable和Decodable之后,使用JSON粒子播放变得非常简单。 有两种编码和解码协议 。 如; 可编码和可分解 。 可编码的只是代表这两个协议的类型别名。 typealias Codable = Decodable & Encodable 显然,您可以使用此类型别名来编码和解码 。 CodingKeys允许您使用特定的变量名称来表示JSON密钥。 可以根据外部表示进行解码的类型。 我们的JSON片段如下。 JSON片段 让我们发现盒子里发生的事🎉 可解码协议的示例 可以将自身编码为外部表示形式的类型。 可编码协议的示例 如果您有任何具体问题,请不要犹豫与我联系。 推特:@ strawb3rryx7 传播这个词

Swift 4中的可编码和可解码

在iOS的日常开发中,许多任务涉及调用API和Web服务,将数据保存到磁盘以及使用自定义类型对对象进行建模,这些对象代表应用程序的用例和功能。 这样做时,我们必须将数据与中间格式(JSON,属性列表)之间进行转换。 对于数据编码和解码任务,Swift提供了可编码和可解码协议。 通过确认这些协议,可以将自定义类型编码到外部表示形式(例如JSON和Property List(pList))并从中解码。 在本文中,我将介绍如何使用Encodable和Decodable在JSON和JSON之间转换自定义类型实例,以及使用这两种协议进行编码和解码任务的许多方面。 编码方式 将您的自定义类型实例转换为其他表示形式(例如JSON和pList)的过程称为编码或序列化。 对于编码,自定义类型符合Encodable协议。 解码 将诸如JSON或pList之类的表示形式的数据转换为自定义类型的实例的过程称为解码或反序列化。 对于解码,自定义类型符合可解码协议。 可编码 为了同时支持编码和解码,自定义类型可以符合Codable协议,而后者又符合Encodable和Decodable 。 typealias可编码=可编码和可解码 自动编码和解码 默认情况下,Swift Standard Library和Foundation Framework中的许多类型(例如Int,String,Data,URL,Date等)都是可编码的。 若要使任何自定义类型自动变为可编码,它应符合可编码协议,并且其所有存储的属性都应是可编码的。 例如,这是一个表示Movie的结构。 struct Movie { var movieId:Int? 变量名称:字符串?} 只需遵循Codable,即可对Movie类型进行编码和解码。 struct Movie:可编码{ var movieId:Int? 变量名称:字符串?} 同样,具有自定义类型属性的自定义类型是可编码的,只要其所有属性都是可编码的即可。 例如,假设我们有MovieDetail结构来表示电影细节​​。 struct MovieDetail:可编码{ var语言:字符串? var genre:字符串? var releaseDate:字符串? var bannerImageUrl:字符串?}结构电影:可编码{ var movieId:整数? var名称:字符串? var movieDetails:MovieDetail?} 由于MovieDetail也符合Codable,因此Movie也可编码。 Swift集合类型(例如Array , Dictionary和Optional只要包含Codable类型,就变为Codable。 […]

Swift中的对象映射

大家好, 在本文中,我们将学习什么是对象映射及其重要性。 然后,我们将比较在Swift中映射对象的不同方式。 将给定集合(域)的每个元素与第二个集合(范围)的一个或多个元素相关联的操作。 ”中的术语。 在现实生活中应该在哪里使用地图? 通常,完成请求后,我们会收到各种格式的数据。 我在下面的示例中选择JSON。 这些数据格式应在我们的应用程序中转换为我们的模型。 这样我们就可以根据需要并根据OOP使用它们。 这些自定义类将使您可以在自定义类中对模型业务进行编码。 是否需要将JSON转换为自定义对象? 对! 否则,您需要将它们用作字典或其他某种数据类型。 这将使您的应用程序无法正常运行🙂 有很多方法可以映射对象。 让我们从最差的方式开始,即非映射方式 Swift的基本映射方式(Swift 3): 上面的示例中有一个人员结构。 首先,我们将向其添加一个init方法。 init(带字典:[String:Any]?){ 警卫队让字典=字典其他{返回} 名称= dictionary [“名称”]为? 串 姓=字典[“姓”]为? 串 age = dictionary [“ age”]如? 整数 } 然后像这样映射您的对象: var数据:Data = JSON.data(使用:.utf8)! 让anyObj =尝试! JSONSerialization.jsonObject(with:data,options:.allowFragments) let person = Person(with:anyObj!)//在这里映射 label.text = person.name 如果需要安全保护,请更改模型的可选参数并设置默认值: var名称:字符串? ==> var名称:字符串! var姓:字符串? […]

Swift 4:桥接可编码,JSON和[String:Any]

如果您像大多数Swift开发人员一样,您会欣喜若狂,我们最终对如何在Swift中处理JSON有了明确的答案。 Codable实际上为您免费提供了自定义数据结构的序列化/反序列化。 它开箱即用地支持JSON和Plist,并且它易于扩展的体系结构意味着在接下来的几个月中,我们将在GitHub上看到很多其他选择-我在为您提供YAML。 但是,尽管Swift需要花一些时间为我们提供标准,但社区的其他成员仍然必须与基于JSON的API进行交互。 这导致了各种各样的库和策略。 在大多数情况下, Codable现在提供了这些其他解决方案的批发替代品。 进行切换应尽量避免麻烦,并减少代码行和依赖性。 那是双赢。 想要让我们通过处理JSON序列化/反序列化来提供更多帮助的库的情况有点令人h目结舌。 PubNub是这种方法的一个示例。 这些库希望与Any (通常表示[String: Any]或[Any] )进行交互。 我敢肯定,随着时间的Codable ,这些库中的大部分将包含Codable ,但是现在应该如何与它们集成? Codable为我们提供了一种将自定义对象映射到Data ,因此,如果我们有一种将Data映射到[String: Any]或[Any]那么我们就可以了! 幸运的是, JSONSerialization做到这一点。 因此,一个简单的解决方案是使用JSONSerializtion进行额外的编码/解码,以生成这些库期望的数据类型。 对JSONEcoder和JSONDecoder的扩展很自然地放置了此逻辑,因为您仍然可以访问诸如dateEncodingStrategy类的dateEncodingStrategy 。 结果看起来像这样: 尽管这种方法肯定不会获得任何效率方面的奖励,但它为我们现在需要与之交互的API和光荣的Codable未来之间架起了一座简单的桥梁。

使用Swift Codable进行无痛JSON解析

最近,JSON已成为最广泛使用的格式,可以在整个Internet上传输数据。 在iOS开发领域,开发人员通常会在Swift中使用JSON数据并将其用于构建iOS应用。 有一些很酷的库,例如SwiftyJSON已经可以在Swift中使用JSON数据了,这些库之所以流行,是因为开发人员不需要使用JSONSerialization处理不可读的混乱来解析JSON。 幸运的是,Swift 4作为Foundation框架的一部分引入了令人惊叹的Codable协议,并且JSON解析成为一行或两行代码。 这是Apple完全支持的解决方案,可以轻松采用。 它提供了定制功能,可以对复杂的场景进行编码和解码。 在本文中,我们将通过构建Github Information应用程序来了解如何使用Swift 4 Codable解析JSON。 在WWDC 2017上,Apple引入了Swift中的新功能,可以使用Swift Codable协议轻松解析JSON。 有关Foundation的新增功能,可以观看谈话,您可以从23分钟开始观看此新功能。 基本上,此协议具有Encodable和Decodable协议的组合,可用于双向使用JSON数据。 总而言之,Swift Codable协议为我们提供了以下内容。 使用Codable,我们可以通过编写很少的代码行将JSONObject或PropertyList文件建模为等效的Struct或Classs。 我们不必为对象中的属性编写构造函数。 全部由Codable处理。 我们只需要扩展我们的模型以符合Codable,Decodable或Encodable协议即可。 Swift的强数据类型与JSON的丢失数据类型之间的不匹配已由Swift编译器内部处理。 现在,我们可以处理Swift Data类型,例如Date,URL,Float等 复杂的JSON可以使用嵌套结构轻松建模,以提高可读性。 使用JSONDecoder解析实际JSON成为一线人 已经有许多关于该主题的文章,涵盖了Codable协议的端到端介绍。 但是在这篇简短的文章中,我们将使用GitHub API并构建一个示例应用程序来简要演示此功能。 我们将使用非常著名的GitHub API来演示此功能。 我们将构建一个简单的应用程序,该应用程序使用GitHub用户名,并在单击“显示”按钮时显示一些信息。 有一个API可显示GitHub用户的公共信息,例如,我可以使用此API端点找到GitHub帐户的详细信息 https://api.github.com/users/shashikant86 这将以JSON格式返回信息,该信息目前看起来像这样。 { “登录”:“ Shashikant86”, “ id”:683799, “ avatar_url”:“ https://avatars0.githubusercontent.com/u/683799?v=4”, “ gravatar_id”:“”, “ url”:“ https://api.github.com/users/Shashikant86”, “ html_url”:“ https://github.com/Shashikant86”, “ followers_url”:“ https://api.github.com/users/Shashikant86/followers”, […]

Objective-C到Swift:使用NSJSONSerialisation的NSData

以下是我在ObjC中的代码片断 NSDictionary *json; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"realstories" ofType:@"json"]; NSData *data = [NSData dataWithContentsOfFile:filePath]; json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 我尝试过使用它的Siwft等价物: var json = [AnyHashable:Any]() let filePath: String? = Bundle.main.path(forResource: "realstories", ofType: "json") let data = NSData(contentsOfFile:filePath!) json = ((NSKeyedUnarchiver.unarchiveObject(with: data as! Data) as! NSDictionary) as! [AnyHashable:Any]) 但是我陷入了错误: unexpectedly found nil while unwrapping an […]