Belajar dari tutupnya Parse.com其他Facebook Parse.com sudah tidak asing lagi di kalangan开发人员,khususnya移动开发人员。 Sejak diakuisi oleh facebook,解析gencar sekali melakukan penetrasi市场。 Lebih dari setengah juta开发人员aktif menggunakan layanan解析yang mencakup云数据库,pushnotif,geoLocation,用户身份验证和存储。 TRAGEDI解析bukanlah cerita baru。 Faktanya,banyak,layanan,cloud yang,“ dibekingi”等字词IT公司harus berakhir dengan kisah suram。 Mungkin kita masih ingat dengan tragedi theplanet.com在塔洪2011年,atau stackmob(Paypal)在塔洪2014年。 Secara bisnis,Mungkin kesalahan utama yang dilakukan Parse.comadalah terlalu lengah dengan模型bisnis Freemium nya。 […]
我一直喜欢Cucumber风格在iOS上进行UI测试。 但是我真的不喜欢在计算机上管理15000个红宝石版本,更不用说确保团队运行相同的版本,gem(我在看着你calabash-ios )等等。 我也希望它简单:只需读取代码,然后按“运行测试”即可。 因此,我决定在Swift中编写一个简单的Gherkin解析器。 我希望测试的结构如下: 方案:导入按钮起作用 鉴于我在主屏幕上 当我点击“导入”时 然后打开导入屏幕 func I_am_on_the_home_screen(){ … } func the_import_screen_opens(){ … } 该方案位于最上方,执行功能位于其下方。 请注意,没有“ I_tap_Import”功能,我希望tap和type具有足够的通用性,以使我的框架能够理解它。 解析中 POC版本基本上是在进行字符串比较和模式匹配,但是您可以想象,这不是非常有效和灵活。 对于“真实”版本,我使用了解析器组合器。 观看Swift讨论解析数学表达式的视频时,解析器组合器引起了我极大的兴趣。 联机有一些解析器组合器的介绍,因此在这里我不会做太多详细介绍,但是它的大致工作原理是这样的:基本解析器(例如,字符)使用…悬念…组合器组合在一起! 创建更复杂的解析器( 字符串解析器= n × 字符解析器),并且可以应用一些逻辑来创建语法(字符串是直到行尾的每个字符) 我花了几天的时间来“获取”它,但是一旦我将所有内容放到白板上,一切都变得有意义。 简而言之,它解析场景时忽略了前导和尾随空格。 当有一个“ tap ”关键字时,它将使用加引号的字符串作为参数来调用预建的tap函数(例如, Given I tap on “continue”调用app.buttons[“continue”].tap() 当有’ type ‘关键字时,它将使用加引号的字符串作为参数来调用预构建类型函数(例如, Given I type “hello” in field “id”调用app.textFields[“id”].typeText(“hello”) )) 如果没有关键字,它将调用带下划线的分隔线命名函数(例如, Then I […]
现在是时候迁移了,不仅Xcode 8和Swift 3已经发布,而且我的应用程序也无法通过iOS10正常工作! 迁移前 1.首先Git 分支,并标记您必须! 因此,您可以进行时间旅行,以防迁移造成麻烦! 您应该先从旧版本iOS <10开始,然后再从iOS 10开始 2.让Xcode完成它。 它可以帮助您很好地进行迁移,大约90%的覆盖率取决于您对Modular和DRY的满意程度 。 3.我是否说过让Xcode发挥作用? 您钟爱的布局会弄乱,但右键单击后放心,让Xcode修复布局,一切都会好起来的。 4.让da pod处理依赖项 可可豆荚也需要迁移! woo! 并且某些库将需要目标分支,看起来像… pod’SwiftTask’,:git =>’https://github.com/ReactKit/SwiftTask.git’,:branch =>’swift / 3.0′ 移民 5.杀死剩余的错误/警告 这不应该太多,本指南应该可以使您了解。 但这是最疯狂的一个! 因此,如果您找不到它的折断方式,请尝试仔细看一下您错过的打字字典。 让viewDict:[String:UIView] = … 6. iOS10默认情况下关闭“推送通知”。 这是陷阱时刻! 不要忘记打开它,否则您将注定失败! 对于旧的Xcode,它将在开发环境中看起来不错,但不会在生产环境中使用! application:didFailToRegisterForRemoteNotificationsWithError :,线程[{number = 1,name = main}]错误[Error Domain = NSCocoaErrorDomain代码= 3000“没有为应用程序找到有效的’aps-environment’授权字符串” UserInfo = {NSLocalizedDescription =无效的’aps-找到适用于应用程序的环境的权利字符串}] 您将找不到用于应用程序警报的有效“ aps-environment”权利字符串 。 […]
对于iOS开发人员而言,解析JSON是一项非常常见的任务。 但是,Foundation框架提供的现成功能非常基础。 有许多可用的开源库可实现更高级别的功能,并有望使此任务更轻松,更安全。 作为个人实验,我尝试实现自己的JSON解析库,该库以我真正喜欢的几种方法为模型。 我的实现旨在实现极简主义,并专注于基于通用协议的方法,该方法应允许解析JSON内容,并以最少的代码将其存储在适当的容器( 类或结构实例)中。 为了使复杂性最小化,将没有特殊的错误处理:在不幸的情况下,解析特定的JSON密钥失败,相应的存储值将为nil 。 开箱即用的解决方案 假设我们需要与Web服务进行交互,该Web服务返回如下所示的JSON内容: { “位置”:[{ “ label”:“首页”, “数据”:{ “ address”:“ 6925 Felicity Coves”, “ city”:“ East Davin”, “ state”:“华盛顿”, “国家”:“美国”, “ zipCode”:“ 22998-1456” } }, { “ label”:“工作”, “数据”:{ “ address”:“ 0506 Gretchen River”, “ city”:“亨廷顿海滩”, “ state”:“ Connecticut”, “国家”:“美国”, “ zipCode”:“ 61182-9561” } }] } Swift通过NSJSONSerialization类提供了一种解析JSON的默认方法。 我们可以将JSONObjectWithData用于此类任务,并在确认返回类型符合我们的预期( […]
最近,我发布了名为Socium的iOS社交网络应用模板。 在这里,我想与您分享我从开发中学到的知识。 功能清单 首先,我们需要写下要在应用程序中看到的功能列表。 例如,Socium与典型的社交网络应用程序一样,具有以下功能: 用户资料 用户帖子和评论 发表喜欢 浏览和搜索其他用户 私人实时聊天 追随者/追随者 推送通知 考虑到此列表,我们可以为项目选择一个后端。 后端 社交网络应用程序是一个复杂的系统,由客户端和服务器端组成。 Socium的服务器端建立在Parse Server之上。 Parse Server有许多优点:它是开源的,具有庞大的社区,并且具有出色的iOS SDK(顺便说一下,还有Android SDK)。 Parse Server需要VPS或Heroku之类的云应用程序平台,对于不熟悉后端内容的用户而言,可能难以设置和维护。 但是,我相信控制后端是一件好事。 即使需要一些其他技能。 毕竟,我从课程中学习。 数据库架构 现在,当我们知道要求时,就该写下所有必要的表及其之间的关系了。 这是我为Socium设计的架构: 让我们来看几个最有趣的实体(或Parse Server术语中的“类”)。 用户 / UserProfile 。 为了保护用户的电子邮件,我为公共用户配置文件创建了另一个类UserProfile,并与User类添加了一对一的关系。 任何人都可以看到UserProfile 。 用户仅对所有者和管理员可见。 UserProfile具有followings , followers和postLikes字段,它们分别是与UserProfile和Post实体的一对多关系。 他们全部 图片 。 我没有将图像直接存储在PFFile字段中,而是为此创建了一个单独的类。 因此,图像可以阵列和多对多关系存储。 如果我们想在照片中添加喜欢/不喜欢的功能,则可以提供更好的灵活性。 Post , PostComment , Conversation和Message实体非常不言自明。 客户端应用架构 定义数据库架构后,该考虑一下我们的iOS应用了。 […]
Codables –是节省大量时间和节省生命的工具。 当我们必须从网络调用中获取数据并保存到对象或结构以在应用程序中显示数据时,我们必须经历很多这样的过程。 与实时应用程序相比,这是一个相对较小的json结构,用于澄清我的意思,让我们看一下我用于解析的json数据: 因此,与实时数据相比,这确实很小,想象一下当您拥有如下数据时进行解析: 我知道它很大,所以Codables作为超级保护者来了。 因此,让我们看一下使用codables而不是常规解析,我向您保证 就是这样,哦,是的,您可能已经注意到只有一行代码可以完成所有工作: 您可能想知道的是,什么是“ WeatherArray”,它不过是经协议确认的结构,如下所示。 WeatherArray包含Weather对象数组,啊哈! 让我们看看天气: 什么!!!,为什么我以这种方式创建对象? 您唯一需要强调的就是创建确认json架构的对象。 正是我所做的,以上结构实际上证实了以下json架构。 因此,请继续尝试制作可编码对象,以确认不同的json体系结构。 发表评论…如果您有任何困难,我可以帮助您😇 注意:我真的很抱歉图像大小,我将在下一篇文章中进行整理。
解析文本的明智方法是使用ANTLR,yacc或解析器组合器甚至Xtext之类的工具。 但是,要聪明就意味着要研究那些工具和框架。 如果您不想学习,该怎么办?如果您只想编写一个解析器而又不花很多时间在学习“ 正确的 ”工具上,该怎么办? 比您应该继续阅读,因为这正是本文的主题。 看起来我可以解析文本!!! 通常,我们不仅仅为了踢球而解析文本。 我们进行分析,因为我们需要从文本表示中提取一些数据。 在本文中,我将使用:https://github.com/mzaks/FlatBuffersSwiftCodeGen 作为如何在Swift中扮演自己的解析器角色的示例。 我的代码不是超级健壮和干净的代码,但是,嘿,它是分析文章的愚蠢方式 。 目的是激发您学习我的错误并做得更好。 另外,如果您有兴趣全面了解文本解析术语和技术,我建议您阅读以下内容: 解析指南:算法和术语 我们已经介绍了一些解析术语,同时列出了用于Java解析的主要工具和库… tomassetti.me 无论如何,让我们从愚蠢的解析方式开始。 首先,我们需要了解文本是一维数字数组。 基于不同的编码,它可以是代表相同文本的不同数字。 因此,为了能够解析文本,我们需要就一种编码达成一致。 我定义了要解析的文本以UTF-8表示。 现在,正确的文本解析方法基于词法分析和词法分析两个阶段(有关更多详细信息,请参阅我之前提到的“分析指南”)。 我说搞砸了,我们处于愚蠢的解析状态 ,所以我们只有一个阶段,我们称之为吃eat 。 请看以下文件: mzaks / FlatBuffersSwiftCodeGen FlatBuffersSwift的代码生成器。 通过在以下位置创建帐户来为mzaks / FlatBuffersSwiftCodeGen开发做出贡献 github.com 在那里,我们有一个eat函数,它具有: 静态字符串-我们要吃的字符串 指向我们要开始进食的记忆的指针 和长度,这告诉我们我们想吃多远 它返回一个可选的指针,这意味着如果我们能够食用该字符串,那么我们将返回停止进食的指针,如果我们无法食用,则将返回nil 。 但是,在我们开始吃弦本身之前,我们先吃了空白。 空格是字符,对人类没有任何语义含义。 如果我们看一下前128个ASCII字符的字符编码表,它等于UTF8: ascii代码表新的优秀ascii家庭设计符号发生器代码表ascii代码tabelle.png 我们看到前0..<33是不可见的字符,可以视为空白。 因此, eatWhiteSpace函数的愚蠢实现: 公共功能eatWhiteSpace( _ p:UnsafePointer , 长度:整数 )-> […]
我正在使用的API返回使用椭圆曲线数字签名算法(ECDSA)签名的敏感数据。 签名本身是一个ASN.1 DER序列-因为我在网上找不到Swift或Objective-C DER解析器,所以我需要自己编写。 ECDSA签名可以分为两个整数。 我们可以使用openssl检查此整数。 $ echo -en“ 3045022100a85e76ff1f18e52d4eccde774aa46e3ec2891068ebef89a7cb6e0653eb0dffb202204cd76e19bcb18d76c13af0ea061117cbd6d3c8fbd1d9fc9aac265266371c3a3f” xxd -pu -r>签名 $ openssl asn1parse-通知der-输入签名 。 0:d = 0。 hl = 2 l =。 69弊:SEQUENCE。 。 2:d = 1。 hl = 2 l =。 33 prim:整数。 :A85E76FF1F18E52D4ECCDE774AA46E3EC2891068EBEF89A7CB6E0653EB0DFFB2 。 37:d = 1。 hl = 2 l =。 32素数:整数。 :4CD76E19BCB18D76C13AF0EA061117CBD6D3C8FBD1D9FC9AAC265266371C3A3F 如您所见,这两个整数在签名的十六进制编码版本中可见,但是我们如何使用Swift将它们取出呢? 维基百科上有一些DER编码数据的很好的例子。 事实证明,整个十六进制字符串都位于类型-长度-值三元组中。 这意味着数据所保存的每个可变长度值都以其类型和长度为开头,每个值都为1个字节。 我发现此页面描述了ASN1解码器应该期望的类型标签。 让我们将其表示为一个enum […]
基础 要解码JSON结构并将应用程序中的模型编码回JSON,您可以使模型符合Swift Codable协议。 这是另外两个协议的组合: Decodable和Encodable 。 这对于简单的JSON数组和字典非常有用,例如: 让json =“”“ [ { “名称”:“年度旅行保险”, “ paymentFrequency”:“每年”, “ description”:“全年安全旅行。” }, { “名称”:“汽车保险”, “ paymentFrequency”:“每月” } ] “”“ .data(使用:.utf8)! 您可以使模型符合Codable (或Decodable )协议: struct BankProduct:可编码 { 变量名称:字符串 var paymentFrequency:付款频率 var说明:字符串? 枚举PaymentFrequency:字符串,可编码{ 每月个案 每年一次 } } 只要JSON数组中没有其他不代表我们模型的元素,所有内容都会自动解码。 否则,解码将失败。 这意味着我们可以在JSON结构的每个元素中添加额外的键,但是键name和category应始终位于该元素中,因为它们在我们的模型中不是可选的。 在此示例中,还添加了一个枚举,因此您可以看到,只要枚举符合(De)Codable协议且枚举的大小写名称与中的字符串相同,它就会自动将JSON转换为正确的大小写。 JSON。 否则,您需要为案例提供一个rawValue 。 我们可以使用以下方法从JSON创建对象: 让解码器= JSONDecoder() 让产品=尝试解码器。解码([BankProduct] .self,来自:json) 当JSON的键名与模型中属性的名称不匹配时,我们需要一个名为CodingKeys的嵌套枚举,其枚举类型应符合CodingKey协议,它的String rawValue类型。 枚举应包含所有键,即使在模型和JSON中具有相同名称的键也是如此。 […]
欢迎! 这是关于“在Swift中实现编程语言”的系列教程的第一部分。 通常,创建新的编程语言不是很实用。 实际上,在大多数情况下,它甚至被认为是浪费时间。 不够务实。 值得庆幸的是,在大多数情况下都是如此,几乎所有利基市场都存在开源语言。 但是尽管如此,当解决众多问题时,了解一两个解释器的实现方法实际上可以派上用场。 了解内部机制甚至可能像我一样改变您的软件开发方法。 当我写第一语言(Zolang)时,驱动因素是工作中的挑战。 对我来说,这是第一次实现一个口译员,这似乎是一个好方法。 我不希望这是最后一个。 当时,我们需要使用多种编程语言分别实现的各种业务逻辑的单一来源。 我们使用了脚本语言(Ruby),然后使用了每种平台的单独语言:iOS(Swift),Android(Kotlin)和服务器(TypeScript)。 通过实现一个简单的解释器,我们能够为所有这些接口创建一个接口,并且比我预期的要容易得多。 德怀特同意! 如您所见,我发现用自己的语言写作绝对是值得的。 一种实现的灵感促使我与大家分享了本教程系列。 在本系列中,我们将从为计算器创建一个简单的解释器开始,然后将该实现扩展为一种简单的编程语言。 这是本系列前六部分的粗略计划: 第1部分:简介 第2部分:语法-设计我们的第一语言(01/28/19) 第3部分:Lexer(02/04/19) 第4部分:解析器(02/11/19) 第5部分:主要功能(02/18/19) 第6部分:解析变量(02/25/19) 第7部分:声明变量(19/04/19) 第8部分:函数(03/11/19) 第9部分:定义函数(03/18/19) 第10部分:If陈述(03/25/19) 我希望你们对此充满期待,我知道。 在接下来的几周中,您将在每个星期一早上看到我发来的帖子。 我想添加比我已经计划好的更多的教程,但这将取决于您的反馈,所以请不要犹豫评论或鼓掌。 反馈的每一点都非常感谢。 接下来:语法! PS随时在Twitter(valdi101)上或在Medium上随时关注我,以获取有关将来教程的通知和讨论。