Tag: 软件开发

在iOS上使用MVVM进行路由

我在多个项目中使用MVVM已有一段时间了,我非常喜欢它的简单性。 特别是,如果您像许多人一样从MVC移出,则只需要在体系结构中增加一层即可; 查看模型。 如果您发现太多复杂的图层,这确实使事情变得容易。 这是一个好的开始,但是这种简单性并不总是很好。 在MVVM中,将业务逻辑移出视图控制器(VC),然后意识到它仍然很胖。 视图模型(VM)现在具有业务逻辑,但是表示数据(格式)或路由又如何呢? 它们仍然停留在VC中,我们需要将它们移出。 样品流量 假设我们正在实现一个登录屏幕,如下所示。 路线清单: 登录>主屏幕 注册>注册屏幕 忘记密码(?)>忘记密码屏幕 这似乎是一个简单的屏幕,可以使用带有3个脚本的情节提要实现。 但是请相信我,事实并非如此。 例如,您通常会在登录时打开主屏幕。 但是在这种情况下,用户的密码可能已过期,您需要实现重定向以更改密码屏幕。 因此,登录路径变为: 登录>主屏幕或更改密码屏幕 这是情节提要路由失败的地方。 它只是无法应付这种动力。 因此,通常要做的就是让VC处理它: func loginButtonTapped(){ //开始网络请求… //回应后: 如果viewModel.shouldChangePassword { performSegue(id:“ ChangePasswordScreen”,发送者:nil) }其他{ performSegue(id:“ HomeScreen”,发送者:nil) } } 这是路由逻辑,不应在VC中使用。 如果要使用轻量级VC,请在编写if语句之前三思。 他们是决定,不属于那里。 以我的理解,VC仅应具有与视图相关的代码和粘合代码。 永远没有决定。 让我们定义一个路由器协议,并将这些if语句从VC中删除。 我们会需要: 路由ID :字符串标识符,例如segue ID。 上下文 :要从其路由的当前视图控制器。 可选参数 :过渡所需的临时数据。 (点击的行索引等) 协议路由器{ 功能路线( 到routeID:字符串, 来自上下文:UIViewController, […]

开放封闭原则和规范模式的重要性。

Lehlohonolo Isaac,iOS开发人员,DVT 您是否曾经不得不一遍又一遍地重写相同的功能? 举例来说, 您想按类型,颜色和价格过滤车辆列表。 尽管有不同的规范,但我将通过编写三个过滤函数来实现此目的。 因此,即使这三个功能执行相同的操作(正在过滤车辆列表),这三个功能也仅因其规格不同而不同。 解决此问题的简单方法是将规范插入过滤器中。 在这种情况下,我们将只有一个过滤器。 为了使我们能够按颜色进行过滤,我们将注入颜色说明。 要按类型过滤,我们将插入“车辆类型规范”,依此类推。 现在,我们的应用程序只有一个过滤器。 让我们看一下如果在上面的示例中不使用“规范”模式,将会发生什么。 让我们首先创建一个Vehicle对象。 现在,假设您具有以下定义的车辆清单。 让我们创建一个Filter类: 下面的代码段演示了过滤车辆列表的方式: 仅当您知道Vehicle具有一个属性大小时,这才足够好。 但是,它足以应付车辆规格的变化,即当我们现在要按颜色或车辆类型过滤车辆列表时,它将无法正常工作。 取而代之的是,我们必须在VehicleFilter中添加另一个函数,该函数不可行,因为它不遵循开放式封闭原则(OCP)。 我们如何克服这一弊端? 好吧,我要实现的解决方案之一是按规范过滤,而不是明确说明过滤标准。 通过这样做,您可以使VehicleFilter具有足够的灵活性,以适应各种过滤条件。 让我们定义车辆规格。 因此,我们可以指定以下过滤条件: 让我们创建一个过滤器协议。 让我们看看上述变化将如何帮助我们遵守开放式封闭原则。 从上面的代码片段可以看到,我们现在可以过滤颜色和大小,而无需创建两个过滤器。 这使我们的过滤器类别遵循SRP(单一责任原则)和OCP(开放-封闭原则)。 规范模式还可以做很多事情。 例如,您可以创建一个具体的规范来处理要同时按大小和颜色过滤列表的情况。 这称为And规范。 但是,AND有一个缺点。 它没有严格遵循单一责任原则。 我希望您对规范模式学到了很多。 我还要感谢Kennedy Sigauke对创建此博客所做的贡献。

iOS Developer首席财务分析师🚀

从Lead Finance Analyst过渡到iOS Developer的18个月过渡的简短见解。 2015年12月 🏦 我是26岁的结构化财务分析师。 我正在开发和使用高级现金流量模型来领导对亿万结构性金融交易的分析。 听起来很酷,但事实并非如此。 2016年一月 由于对技术领域的好奇心,我开始了一个副项目Boolerang.co.uk-一个 伦敦科技工作平台。 很有趣。 我正在学习新的编程语言,开发新技术,并通过在线平台将软件工程师与雇主联系起来。 我一直很喜欢编程,但是从没有如此接近这个领域的机会。 2016年4月 🚀 全职。 Finance 0,Boolerang1。我离开了首席结构财务分析师的职位,全职从事Boolerang的工作。 自从大学期间在洛杉矶工作以来,这是我与工作相关的工作中获得的最大乐趣。 这也是我去过的最“失业”的时期,这真是令人恐惧。 👻 话虽这么说,伦敦的技术人才需求/供应差距令人难以置信地令人难以理解,这为我的决定提供了支持。 到本月底,Boolerang已有200多名雇主发布工作,并且软件工程师似乎很容易找到并吸引该平台-尤其是当我在“没有招聘人员的地方”下线时。 😆 iOS工程师并非如此。 2016年五月 生活是美好的。 Boolerang很好。 关于越来越难以捉摸的“ iOS工程师”,我与雇主之间的对话越来越多。 他们表面上的稀缺使我想起了异国情调的阿凡达(Avatar)风格的“ unobtainium”。 因此,我下载了Xcode,这是Apple的iOS驱动的IDE。 没什么… 2016年9月 我在9–9工作。 Boolerang上为9–6,iOS开发上为6–9。 Boolerang正在连接600位雇主和8’000位软件工程师。 我绝对非常喜欢iOS开发。 技术,集成等等,还有一些CocoaPods…👌 2016年12月 🙏 Boolerang需要专职人员,而且获得帮助比我想象的要容易。 现在,我可以花更多的时间在“ iOS’ing”上,同时知道Boolerang具有继续增长所需的一切。 全力以赴。 2017年三月 到这个时候,我已经构建了34个未发布的iOS应用程序,并观看了来自斯坦福大学,苹果大学,乌迪米和树上小屋的数百次演讲。 我的三个金融学前同事离开这个行业,通过Makers Academy /大会寻求软件相关的工作(我认为我对财务和专业技术的不断评论最终通过🙈获得了)。 iOS开发方面的职业? 此时的重返金融的想法令人发笑,没有吸引力,而且Boolerang绝对不如18个月前那么性感。 […]

如何编写踢屁股拉请求

适量亵渎的Git入门指南 通过Akash Shah 对于新手开发人员(至少,那些想与其他人一起从事项目工作的人),编写提交和请求请求是必不可少的。 如果有效完成,它们最终将节省时间和精力,不仅对您有利,对您团队中的其他开发人员,项目经理和客户也是如此。 在进入美好的提交和拉取请求世界之前,退后一步来了解应用程序实际上是有帮助的 。 无需再费周折: 应用程序是功能的集合,这些功能可以共同帮助用户实现目标,无论是寻找新的住宿地点,与朋友联系还是浪费时间。 功能虽然差异很大,但具有一些特征: 每个功能都有一个单独的功能。 每个功能可以独立运行,也可以相互依赖。 每个功能都包括帮助其接收信息,解析信息然后进行传递的代码。 在大多数情况下,该代码仍然是单独的,其他功能无法访问。 文档作者,我们可以快点了吗? 我想做个很烂的狗屎! –你 嘘,年轻的Padewan。 我们到了那里。 现在,为什么我们要经历有关功能的整个讨论? 好吧,无论何时使用新功能或修复现有功能,都可以创建一个单独的分支,并将相关代码提交到该分支。 完成后,您将提交拉取请求 。 注意不要在一个分支中使用多个功能或修复。 提交 开发功能时,无需从一开始就构建其最终迭代。 您逐步构建它。 您可以从简单地激活功能开始,然后提供信息,依此类推,直到功能完成。 但是,您如何决定提交什么和何时提交? 这很简单。 提交步骤! 提交这些步骤可以使不熟悉您的代码的人轻松了解您的操作以及操作方式。 您可以做一些其他的事情来使您的提交变得更好: 说明 应该用一句话形容您的所作所为。 如果您需要更多,也许您应该拆分提交。 摘要应该描述提交的目标。 你想做什么? 将数据转换成字符串? 重构什么? 修复您之前弄糟的东西? (嘿,狗屎发生了。我没有判断!) 不要害怕经常犯错! 您做得越多,您就会学到更多。 确保您没有对Master做出任何承诺,除非您的项目负责人给予了此荣誉。 温馨提示:除非您喜欢使项目负责人的头部爆炸,否则请尽量不要使用空格。 哇,文档作者,您刚刚在使用gif时获得了一些严肃的信誉! –你 谢谢读者。 我努力 现在开始请求。 拉取请求 拉取请求用于准备好审查代码的情况。 如果一切正常,您的项目负责人会将其合并到Master Branch中 […]

iOS应用内购买和订阅

真的很简单。 看一下下面的代码。 让我们来看看它。 一些关键概念是: SKPaymentQueue : 保留所有事务以进行进一步处理的队列 SKProduct :在Itunes中声明的产品与所有可用信息联系在一起 SKPayment :购买产品的意图 SKPaymentTransaction :有关SKProduct的事件 SKProductRequest :请求获取有关提供产品ID的SKProducts的信息 SKProductResponse :包含所需产品的响应。 它由两个列表组成:产品和invalidProductIdentifiers。 第一个将包含成功获取的SKProducts,第二个将包含未能与SKProduct相关的所有标识符。 如果您获得无效的标识符,这是一个故障排除列表,可以帮助您。 确保合同,税务和银行信息已完成 确保正确拼写ProductID 确保AppID是显式的(没有通配符(*)) 确保配置文件是正确的配置文件 确保在产品说明中启用了待售清算选项 确保产品处于批准状态 确保不拒绝对App Store的最后一次App评论 现在,首先,通过以下几行,您可以轻松地创建一个SKProductRequest。 let request = SKProductsRequest(productIdentifiers:productIDs) request.delegate =自我 request.start() 由于以下方法是回调,因此请确保实现SKProductsRequestDelegate。 func productsRequest(_请求:SKProductsRequest,did接收响应:SKProductsResponse) 在那里,您将获得适用于您的应用程序的所有SKProducts。 要进行购买并创建SKPayment。 让付款= SKPayment(产品:产品) SKPaymentQueue.default()。add(付款) 确保在允许用户进行购买之前,始终要获取产品。 这些SKProducts将在其中局部化价格,因此您应该显示它。 这样可以确保您始终将应用程序中的数据始终保持最新,因为应用程序中的价格错误可能会导致Apple将其从App Store中删除。 您可能还会在流程中注意到“ 外部事件”部分。 交易可以在您的应用程序外部发生。 假设您的用户在系统设置中更改了其订阅类型,或者您的延期交易获得了用户父母的批准,那么除非您期望它们,否则您将无法告知。 因此,始终在AppDelegate中,在您的应用程序开始时,将该应用程序订阅到PaymentQueue。 这样,您将确保您不会错过任何事件。 现在,有时该帐户将无法使用。 […]

Bundler是iOS开发人员的好朋友

这是“ 一切都与工具有关 ”周期 的第2条 。 所以, 抽象 Bundler是一个简单而强大的Ruby gem依赖管理器。 等等,为什么标题为“ iOS developer”的Ruby? 答案很简单-两种最流行的iOS开发工具(cocoapods和fastlane)几乎完全用红宝石编写,并以Ruby gem的形式分发。 尽管您可能尚未使用fastlane,但您肯定已经听说过cocoapods,并且我99.99%的人肯定在开发过程中使用了cocoapods(或使用了它,但停止使用Carthage)。 所以,让我告诉您一些有关上述宝石的故事… 故事1 最近,我意识到我的机器上确实堆满了XCode游乐场: 其中一些是Swift独立的,另外一些则必须嵌入XCode项目中,因为它们应该与Alamofire,ReactiveSwift等3d方库一起使用。 我决定为此目的创建一个XCode项目“ PlaygroundsHost”,用我正在使用的最广泛使用的Pod填充它,然后将所有Playground缓慢移入该项目以将它们保持在单个位置。 将3d-party库集成到游乐场的流程很简单: 创建一个新项目。 关闭它。 在根文件夹中创建一个Podfile。 装上必要的豆荚(例如Alamofire) 运行pod install 运行open *.xcworkspace打开新创建的工作区 创建一个新的Playground,将其放置在项目文件夹中的某个位置(在我的情况下为$PROJECT_DIR/Playgrounds/MyPlayground.playground ) 将创建的Playground拖到XCode中。您将看到类似以下内容: Cmd + B构建所有Pod和项目 完成后,您现在可以在操场上使用import Alamofire了。 您的XCode Project Navigator选项卡如下所示: 好吧,我做到了…… 错误:无法查找符号: __T09Alamofire7requestAA11DataRequestCAA14URLConvertible_p_AA10HTTPMethodO6methods10DictionaryVySSypGSg10parametersAA17ParameterEncoding_p8encodingAJyS2SGSg7headerstFfA3_ 我很困惑,尝试使用Google问题,结果发现可可足类1.4.0和1.5.0之间的游乐场集成出现了问题。 我的本地版本是1.5.2。 一个人可以将可可豆的版本降级到某个版本吗? 绝对可以。 在项目之间进行切换时,是否值得一直上下使用版本? 绝对不… 故事2 我的开发人员几天前曾问我,我是否现在正面临一个奇怪的问题,即他正在CI配置上,而在导出存档时却遇到了“ Lottie.framework不支持配置文件”的构建失败。 我们聊了一会儿,猜测该问题可能与cocoapods更新及其Copy Frameworks构建阶段有关。 […]

CocoaTouch:框架和边界

用户界面是应用程序开发中最重要的部分之一。 我们的工作是创造出色的用户体验,以与其他应用程序脱颖而出。 但是,让我们先深入基础知识。 对于UI组件,我们必须考虑两件事: 我的元素有多大? 应该放在哪里? 我的元素有多大? 您必须考虑UI元素的宽度和高度 。 Core Graphics为该用例提供了一个结构。 CGSize结构{ CGFloat宽度; CGFloat高度; }; 应该放在哪里? UI元素使用坐标系定位。 这开始于(在iOS中)屏幕的左上角。 用CGPoint结构指定位置。 CGPoint结构体{ CGFloat x; CGFloat y; }; 两者在一起 现在我们有了大小和位置。 两者结合形成一个“矩形”。 还有一个同时包含信息的结构,称为CGRect 。 struct CGRect { CGPoint起源; CGSize大小; }; 仔细研究源代码,我们将看到矩形是一个包含已知结构(CGSize和CGPoint)的结构 。 帧 让我们创建一个新的UIView。 将矩形(大小和位置)指定为CGRect并将其作为参数传递给构造函数。 let rect = CGRect(x: 70, y: 70, width: 160, height: 100) let myView = […]

自学成才的软件开发人员:为什么开源对我们很重要

这是一个关于我对开源的看法如何随时间变化以及如何对我的职业生涯产生帮助的故事。 开源简介 大约13年前(在高中时),一个朋友(Netcyrax)向我介绍了开源社区。 他向我介绍了有关开放源代码及其运行方式的所有内容。 然后,他给了我一张Ubuntu CD,并告诉我Ubuntu正在通过发送免费副本来推广其操作系统。 第二天,我使用56k连接访问了www.ubuntu.com,并订购了50份Ubuntu。 我的意图是将它们出售给其他人,而不是免费提供。 那是15岁的我,我不了解开放源代码的目的。 无法理解目的 然后我开始编程。 我已经知道了开源,但实际上我不明白为什么我必须共享我的宝贵代码行。 为什么免费共享我花了几个月时间开发的程序源代码? 如果有人偷了怎么办? 如果我的“竞争对手”使用我的源代码来改进他们的产品怎么办? 当时我不明白的是,我不是一名杰出的软件开发人员,我的程序可以由经验丰富的软件开发人员在几天之内(而不是几个月)从头开始开发。 使用开源库很方便 是2008年,我有了第一部iPhone(3G)。 苹果宣布推出iOS 2和iOS SDK。 我决定(在业余时间)成为一名iOS开发人员。 由于还没有人使用过iOS SDK,因此我不得不自己学习开发应用程序。 我使用WebView创建了一个简单的应用程序,并且业务逻辑在使用JavaScript构建的Web应用程序内部。 我对iOS SDK感到非常失望(菜鸟开发人员+ Objective-C +手动引用计数=灾难),因此我暂停了本机iOS开发两年。 同时,我正在试验混合的SDK,例如Titanium,Adobe Air-ActionScript。 当我回到iOS 5(回到本机)时,一切都不同了。 在大约一个月的时间里,我设法构建了第一个真实的应用程序并将其上传到App Store。 但是发生了什么变化(自动引用计数除外)? 答 :iOS开发的开源社区。 ASIHTTPRequest(用于网络请求)和SDWebImage(用于下载和缓存图像)帮助我构建了第一个应用程序。 版本控制和GitHub 大多数开源项目和库都托管在Github上。 所以我当时使用Github下载我的库,但是由于我是在业余时间编程的,并且没有商业环境的经验,所以我不能说Git和Github之间的区别。 在构建了一些iOS应用之后,我对自己的技能充满信心,因此我决定申请iOS机会。 在第一次面试中的某个时刻: -访者:您使用什么版本控制? 我是什么意思版本控制? -访者:我的意思是您如何保留代码库的版本? SVN? 吉特? -Me:时间机器(OS X的备份软件)! 因此,在与访问者进行了交谈之后,我决定我想了解更多有关Git(以及一般而言的版本控制)的知识,并希望在自己的项目中使用它。 我阅读了很多有关Git的文章,以及如何在团队中使用它。 我学会了在BitBucket存储库中使用“提交”和“推送”。 我将其用作代码的备份和版本控制,但不用作协作工具。 […]

CocoaPods的本地开发

CocoaPods使您的应用程序模块化和集成外部库或框架变得非常容易。 但是,对于更特定的应用程序,该工具会很快达到其极限。 问题如下:我的库是通过我的回购的master分支克隆的。 要测试更改,必须将它们合并到master分支中,并提供一个version标记。 解决方案:本地podfile,该文件不吸引版本,但直接从目录获取源。 创建本地Podfile 首先,您必须创建一个名为“ Podfile.local”的新文件。 现在,您可以在此处覆盖依赖关系。 内部Pod的定义应在Podfile中覆盖。 我们可以通过简单添加以下红宝石线来做到这一点: 修改后的podfile现在应该看起来像这样: 忽略本地文件 在.gitignore中包含本地文件很重要。 否则可能会意外检查文件。 如果应用是通过Jenkins和/或Fastlane构建的,则本地文件也会被吸引,而不是master分支的文件。 我总是在.gitignore上有Podfile.lock和Podfile.local 。

TED 3.0:有效使用旧版iOS代码

我不会经常谈论我为保持家中照明效果所做的工作,但是过去四年来,我花了很大一部分时间在TED for iOS应用程序上工作。 就发布的范围和更改量而言,3.0版本是我们在TED上进行的最大发布。 字幕功能是该应用程序现已以20种新语言本地化。 现在,全世界的用户都可以使用其母语从阿拉伯语到土耳其语来体验TED。 在后台,我们计划将应用程序本地化超过一年。 花了这么长时间? 历史课 适用于iOS的TED于2010年10月首次登陆App Store,并专门针对原始iPad发行。 TED for iOS 1.0旨在在iOS 3.2上运行。 在过去的六年中,随着苹果平台设备和功能的变化,我们一直在此基础上不断发展。 在TED期间(2012年9月至今),我看到了: 视网膜图形,3x图形以及最终的矢量。 AVFoundation使我们轻松制作自己的自定义视频播放器(这是我的第一个TED项目!)。 引入ARC替代了手动保留/释放。 XCTest替代OCTest。 更大或更小的设备,例如iPad mini,iPad Pro,iPhone 5,iPhone 6和iPhone 6 Plus。 Auto Layout和size类可为管理所有这些新设备尺寸带来一些理智。 小部件和自定义共享操作之类的应用程序扩展。 哦,还有个叫Swift的小东西。 TED于2010年交付时,它完全是用Objective-C编写的,旨在在两种设备尺寸上工作:iPhone 3GS和原始iPad。 现在,我们支持从iPhone 4s到12.9“ iPad Pro等iPad的手机。在整个过程中,我们一直在更新相同的应用程序代码库。从未对iOS项目进行过全面的重写,有时可能很诱人。 装修您居住的房子 去年年初,我接任TED的首席开发人员,开始为TED投入更多的时间(TED一直最多是2个兼职开发人员,有时只有1个)。 这样一来,我们就可以将思维方式从维护现有应用程序以保持运转状态(偶尔添加功能)转变为尝试对移动目标更加雄心勃勃。 唯一的问题是我们的许多代码都在显示其年龄。 我列出了高水平的目标,以小规模的方式对应用进行现代化升级,以便我们仍然可以继续发布更新以使TED HQ开心,同时我消除了许多使我彻夜难眠的事情。 这些项目的第一个是对应用程序进行模块化。 由于我们的团队很小,并且有一群相当敬业的用户,他们可以快速升级,因此我们比大多数公司更快地使用最新版本的iOS SDK。 我将最低SDK设置为iOS 8,并开始将应用分解为单独的组件。 我们将其分为单独的动态框架,而不是其中包含所有代码的单个Xcode项目: TED:主要的iOS应用 TEDData:与数据层和业务逻辑相关的类 TEDVideo:我们的自定义视频播放器 TEDCore:在所有不同框架之间使用的共享代码 […]