Tag: 开发

依赖类型(在Swift中)拯救世界!

依赖类型(有时称为约束类型)使代码更安全,更易于使用。 使用从属类型是最有用和鲜为人知的编程概念之一。 我希望阅读完这篇文章后,您会觉得自己像个机械师,刚刚学会了如何加工自己的零件。 我将提供一些背景知识,然后向您展示依赖类型如何拯救世界。 什么是从属类型? 在计算机科学和逻辑中, 从属类型是其定义取决于值的类型。 “整数对”是一种类型。 由于对值的依赖性,“第二对大于第一对的整数对”是从属类型。 —有关相关类型的维基百科文章 由于在Swift中基本类型和用户类型之间几乎没有区别,因此您很有可能已经使用了依赖类型。 考虑无符号整数类型: UInt UInt(正好:1)// 1 UInt(正好:1.0)// 1 UInt(正好:-1)//无 是否能够创建UInt取决于 a)您传递给初始化程序的值为正,并且 b)可解析为整数的值 使用UInt ,是在传达要处理的正整数的信息。 这是有帮助的。 是时候拯救世界了! 假设我们的工作是为核电厂编写软件。² 如果反应堆过热,则可能引发气候事件并导致地球生命的尽头。 我们需要一个函数来冷却它: func addCoolantToNuclearPowerPlant(加仑:整数) 可能您可以用负数来称呼它: func doEmergencyStuff(){ addCoolantToNuclearPowerPlant(加仑:-1000000) } 您已经排干了所有水,并引发了核灾难。 很容易看出为什么UInt类型将是此参数的更安全选择。 func addCoolantToNuclearPowerPlant(加仑:UInt) 现在,假设发电厂过热时至少需要一万加仑的冷却液。 在当前的定义中,我们不能偶然排放冷却剂,但是仍然可以将不足量的填料传递给冷却功能。 让我们通过在函数内添加检查来解决此问题,以免意外导致反应堆开销。 您会从检查中注意到,该参数的值存在隐式依赖性。 我们可以并且应该通过定义新的Dependent Type使隐式显式。 我们称它为Coolant 。 对Coolant此定义使用一个可失效的初始化程序来确保除非存在至少一万个Coolant否则它不会存在。 现在,我们可以重新定义冷却功能,如下所示。 现在,除了所需的最小Coolant剂量外,不可能用其他任何方法调用此功能。

Wat gebeurt er wanneer je werknemers de ultieme vrijheid geeft吗?

Deze maand采访我们,我们的脾气治疗师Yordi(21岁)死于津巴布韦(Kijn Werk)在坎图尔(Kantoor)遇见了维肯(Werken Vanuit)。 我们为我们提供服务。 约迪,坎杰·沃(Je Jeelf Vertellen)上的坎杰·沃(Jan Je wat)? “范纳夫·克莱因斯(Vanaf kleins)曾在计算机领域享有盛誉,德尔斯·梅格格雷根·范·米恩·维德(deels meegekregen van mijn vader),萨梅恩·维耶夫(jaj)遇到了下巴·布瓦德(mi·bouwde ik mijn eerste)。 Mijn参加了groeide电脑展览会,并在het bouwen van网站上进行了采访。 在《苹果传奇》中,伊克·艾伯特(Ipad Kopen)是直接发自内阁的,而伊玛尔·康·德泽(Helar)则是贝塔。 稍后请稍等。Ipad,Ipad2。更多信息,请访问媒体开发和媒体学院。 IOS Development en dus zocht在een baantje als stagiair。 见了阿姆斯特丹的本·格罗特·蒙德·本·伊克,阿尔斯·维杰夫蒂耶那·格里,盖恩·索里希特伦·比昂·莫比根和其他人。 IOS开发人员请教Jaar lang舞台学校。 Een super leuke en leerzame periode。 Ondertussen的ikf mijn studie afgerond en ik op zoek naar een nieuwe uitdaging。 Dat […]

在WKWebView和本机代码之间创建链接

在过去的一个月中,我一直在为对产品有一些特定要求的客户工作; 他们想要一个使用特定地图组件的应用程序,就像他们在网络应用程序中使用的组件一样。 这意味着两件事:javascript🙈并试图找出如何在本机代码和将包含地图的Web视图之间进行通信。 让我们花一些时间来概述问题。 我们在这里处理两个主要组件:用于容纳地图的WKWebView和本机用户界面。 我们希望在这些组件之间双向发送消息。 当用户与地图上的某些对象进行交互时,我们需要在本机代码中触发事件以执行操作,例如显示界面元素,或触发对新视图的选择。 我们还需要从本机代码向Webview发送消息,因此我们可以将所有繁重的工作委托给本机应用程序,以最大程度地减少javascript必须进行的计算。 对我们来说很幸运,WKWebView提供了我们需要的一切。 稍作修改,我们就可以对其进行配置,使其完全满足我们的需求! 设置Web视图是很简单的,而且有据可查,因此这里不再赘述。 您可以通过代码实例化它,也可以在Interface Builder中的视图中拖动一个并为其创建出口。 我选择了后者。 让我们使ViewController符合WKScripMessageHandler和WKNavigationDelegate: 不要忘记在viewDidLoad中将网络视图的na vigationDelegate设置为self! 好了,现在我们已经拥有了Webview设置的一部分。 稍后我们将再次讨论,但是首先,我们将深入研究一些javascript。 快速免责声明:我不是Web开发人员。 如果您是经验丰富的javascript专业人士,请避开下面的代码。 我们需要在javascript中做的就是创建一些函数来处理传入的响应,并将响应发送回Webview。 我希望您对设置index.html文件感到满意,所以我不会向您展示如何做到这一点。 现在,我们可能想做其他事情,而不仅仅是记录接收到的值,但是为了解释这个概念,这样做就可以了。 假设我们要在Web视图中保留一个人员列表,那么将从本地上下文中调用addPerson函数以将其添加到Web视图中。 可以调用sendNameToNative函数将消息发送回本机代码。 让我们添加最后一个构建块,以使一切正常工作! 我们需要在loadView函数中做一些事情,所以我们将重写它。 在这里,我们将为Web视图设置一些属性,以在调用sendNameToNative函数时侦听来自javascript的回调。 您可能需要根据设置视图的方式来摆弄这个。 您可能要做的一件事是将框架更改为等于view.frame,而另一处可能解决问题的方法是在最后一行之后添加view = webview 。 这可能会带来其他问题。 这里只剩下一件事要做,实际上是在向Webview发送消息。 这是我们难题的最后一部分; 实际将消息发送到Webview。 调用此函数使我们可以在Web视图中执行javascript。 在示例中可以看到,当我们要发送字符串时,需要在其周围添加”。 现在,我们可以在webView(_:didFinish 🙂函数中调用类似的函数来设置加载时的Webview,并在与本机用户界面交互后调用它以发送更多消息。 请记住,当您处理用户输入的属性时,您可能需要对其进行验证,以免在Web视图中执行恶意的javascript。 现在您已经确定了结构,可以开始疯狂了: 实际处理响应以触发本机代码中的某些动作,例如动画或segue。 添加更多处理程序以处理来自Web视图的不同响应,从而在两者之间创建紧密连接 恭喜你! 如果您正在阅读本文,那么您已经在WKWebView和应用程序的本机上下文之间创建了连接。 这提供了很多可能性,您可以根据需要进行扩展。 如果您为此创造了一些很棒的东西,请与我分享! 如果您喜欢这篇文章,请查看 我写 的 其他文章 ! […]

在服务器和iPhone应用程序之间共享Swift代码

在这个简短的练习中,我创建了一个使用Swift,Xcode和Kitura与服务器组件共享代码的应用程序。 此练习的目标如下: 创建一个环境,其中Xcode是唯一的IDE 创建三个Xcode项目:移动应用程序,服务器端应用程序和共享业务逻辑 移动应用程序和服务器项目必须共享相同的业务逻辑 该设置必须与Cocoapods和Swift包一起使用 我通过创建一个小的“记录笔记”应用程序来实现上述目标,该应用程序将文本笔记存储在客户端的设备上,并在客户端选择保存或删除笔记时将数据同步到服务器。 客户端和服务器使用内存存储,仅完成最少的工作即可完成目标。 此练习主要是为了了解建立这样一个环境的可行性。 最终项目可以在这里找到:https://github.com/dimitryz/Notes 背景 对服务器/客户端应用程序进行编程存在一个共同的挑战,那就是跨多种平台和语言共享业务逻辑。 在撰写本文时,分布最广泛的语言也恰好是最不可能的:Javascript。 它曾经由Netscape在几周内开发出来,用于浏览器端编程,但是近年来,随着React Native和Node.js的引入,它可以在本机应用程序和服务器上找到。 JavaScript缺乏的东西是大多数非类型化语言所共有的: 它不如其他语言表现出色 可以说,阅读他人的代码更加困难 它提供较少的漏洞防护措施 对于希望提供服务器端逻辑来卸载其应用程序中嵌入的某些功能的iOS开发人员,还有另一种选择,而所有这些都使学习和技术负担降至最低。 迅速 随着Swift的推出,Apple使得iPhone和Mac开发人员可以使用与Apple硬件相同的语言在服务器上进行开发。 使用C和C ++总是可以做到这一点,但是以这两种语言中的任何一种开发服务器端代码的困难都阻止了它的采用。 编写后,Swift服务器代码可以部署在Mac或Linux硬件上。 在撰写本文时,有许多Swift框架可促进应用程序服务器端组件的开发。 IBM的Kitura 完善 汽 泽沃 我为此实验选择的是Kitura。 我最熟悉Kitura,在此练习中,它没有比其他框架明显的缺点。 初始设置 计划的文件/项目结构如下: Xcode工作区 > iPhone App项目 >服务器应用程序项目 >共享业务逻辑项目 >豆荚项目 我们通过创建顶层目录并向其中添加Xcode工作区来启动项目。 mkdir注意 cd笔记 接下来,我们创建一个新的NotesApp项目并将其添加到工作区中 我们不需要CoreData,从单个NotesApp项目中删除Git很重要。 我将根工作区目录初始化为git项目。 添加可可足 我还希望将Cocoapods附加到NotesApp项目(而不是其他项目)。 Podfile我们将Podfile文件添加到具有以下内容的根目录中。 工作区“ Notes.xcworkspace” 目标“ NotesApp” use_frameworks! […]

如何在Swift中制作Web爬虫

如果您想要更深入的解释,请跳至注释部分👇🏻,在其中我将详细分析脚本的每个组件。 总而言之,我想说,根据您想做的事情以及使用正确的工具,Swift当然是脚本编写的非常可行的选择之一! 有关信号量的注释 如果您想知道上面的脚本中为什么有DispatchSemaphore ,那是因为任何Swift脚本只要其控制流到达末尾就退出。 如果必须处理异步性(例如,由于加载了网页,就我而言),则需要使脚本保持生命的东西。 无耻的插件:如果想了解更多有关信号量的信息,请确保在此处阅读我的上一篇文章。 脚本和Xcode游乐场 如果您的脚本允许,我建议您在脚本开发过程中使用Xcode Playgrounds: 这样,无需在终端和代码编辑器之间进行切换就可以更快地进行测试。 准备就绪后,您可以快速将其变成真实的脚本。 代码段 对于这篇文章,我做了一个小仓库, Selenops🕷 (一只飞翔的蜘蛛,是的! 😱),在GitHub上: 在其中,您会找到与Xcode Playground,Marathon脚本和标准“ Command Line Tool ”脚本完全相同的脚本。 祝脚本编写愉快!

iOS背景模式

이Background스에리에서는iOS后台模式설명해보겠습니다。 iOS应用程序UIKit应用程序已添加4个结果。 没有运行 前景(不活动,活动) 背景 暂停 1.不运行 App실행하지상태로서,App이실행되기전실행되었지만System에다。 2.前景 App이용자에게사여보여지고상태입니다。 应用程序前景中的Inactive应用程序Active中的应用程序。 InActive:Ineground InActive的应用程序。 活跃的:不活跃的。 3.背景 前景상태에서HomeScreen으로이동한다。 背景호출된기任务列表背景경우다。 背景任务는应用程序前景실행됩니다。 4.暂停 App이背景않으면상상수행하지수행하System에서App을Suspend상태로됩니다。 App메모존재하며sp暂停있지만지만,CPU나리를지를다。 挂起App应用程序的前景色,然后挂起App系统的应用程序。 이후App않고전전나오지않고App이재시작됩니다。 Xcode功能에서后台模式는后台시App시​​다시이벤트를리지다。 音频,位置,报亭,基于iOS的媒体,蓝牙,PushNotification,BackgroundFetch和背景音乐。 。기몇에가지에하겠습니다。 1.音频,AirPlay和画中画 音频를지를로있습니다。 체크하면사항으로Store음악Store Store아닌Store Store Store Store Store Store Store Store Store Store Store Store Store다。 2.位置更新 GPS가변할다事件를리할다。 3.远程通知 FCM有效负载“内容可用”:真正的应用程序事件和事件列表。 4.后台获取 System이사용자의App사익혀서케줄링을스동작의됩니다。 后台获取。 后台抓取应用程序抓取应用程序。 이매일이이이이이이이이이이주주고고고D D D D AppDelegate에 […]

iOS应用程序中的UNNotifications问题

我当时正在开发用于导航和跟踪解决方案的中等规模的iOS。 该应用程序是使用SWIFT 4中的XCode 9针对通用设备开发的。 问题背景: 该应用程序在收到一些远程通知后突然表现异常怪异。 由于此应用程序属于跟踪和导航类别,因此严重依赖于后台更新。 为此,我们使用MQTT,Firebase和APNS来进行通信,如果任何通信机制失败,应用程序将立即以零时间转移到其他更新机制。 当我们的项目进入回归测试阶段时,我们的另一种信息更新机制报告失败。 具有挑战性的解决方案: 经过大量的研发和深入研究该问题,我们认为该问题与远程通知没有直接联系。 苹果在iOS 10 SDK中的UNUserNotificationCenter中进行了一些更改。 Apple确实将远程通知和本地通知合并在一个框架“ UNUserNotificationCenter ”中。 因此,当应用程序运行时,它会处理“远程”通知,我们通过将消息通过本地通知委派给用户来通知用户。 通过广泛使用本地通知,iPhone SDK可以静默停止处理远程和本地通知。 在这一点上,我们的工程师具有多个方面来检测应用程序的故障并引起对实际问题的困惑,并将工程师转移到其他方面,例如后台任务处理,多线程,Web服务问题等。 但是实际的原因是是其文档中所写的违反Apple开发准则的行为 : “可以安排通知请求,以通过时间和位置通知用户。 有关更多信息,请参见UNNotificationTrigger。 调用-addNotificationRequest:将使用相同的标识符替换现有的通知请求。 标识符为现有交付通知的通知请求将为新的通知请求发出警报,并在触发时替换现有交付通知。 应用程序可以在任何时候调度的待处理通知请求的数量受到系统的限制 。” 实际上,这种趋向于权衡的业务逻辑实现是我们最不优先考虑的。 因此,我们必须发明一种不会破坏客户业务的新解决方案。 实施: 通常,我们处理远程通知并将其传输到本地通知以在设备上显示。 //创建远程通知请求 let request = UNNotificationRequest(标识符:requestIdentifier,内容:内容,触发器:触发器) //将远程通知发布到UNUserNotificationCenter框架 UNUserNotificationCenter.current()。add(request,withCompletionHandler:{(错误)在 logsManager.error(“显示本地通知错误”,错误为“任意”) }) } 由于苹果在UNUserNotificationCeneter框架中发生更改, 因此如果我们每分钟调用2-3次以上, 则会多次调用本地通知发布问题。 没有记录实际的脱粒保持力。 APNS提供两种类型的远程通知。 推送通知–用作警报,并显示在通知中心。 静音推送-用于多语言支持。 这是APNS有效负载的示例json: { “ aps”:{ “ […]

从灵感到生产,第1部分

最后但并非最不重要的一点是,我们有时间做我们以前无法做到的事情,适当地讨论事情,而无需感到压力。 我可以继续下去,当您节省的是时间时,可能性无穷无尽。 时间是值得信赖的绝佳货币。 建立iOS Foundation并在选择的框架中添加约定可以帮助我们减少在客户端项目之间进行切换时的上下文切换量。 如果您希望拥有协作文化,那么这至关重要。 由于实现之间的转换很容易,因此提供帮助的动机就越来越大。 它们越相似,上下文切换就越容易。 我们首先担心基金会会引入限制,从而降低团队的整体幸福感。 它确实要付出代价:自由选择或跳跃任何新事物。 就是说,基础并不是一成不变的,它应该像所有实施一样,成为始终应受到质疑,修订和改进的指南。 在选择新技术并引入影响整个团队的新依赖项时,它应该可以帮助您清醒。 建立牢固的基础需要花费时间,并且需要进行大量讨论,您可能会发现您在所有事情上均未达成共识,但是我敢打赌,您和您的团队都会为已经被定义为潜规则的事情感到惊讶。 当然,并不是所有人都会对所有决定感到满意,这就是民主的来龙去脉。我们使用赞成或反对的态度投票,如果多数票通过,那么就应该解决。 话虽如此,仅仅是因为某些东西没有被基金会接受并不意味着它不能被使用。 核心基础只是定义了转到工具的工具,如果该工具达不到标准,请问自己“可以改进吗?”。 如果是,那么这是进行开源开发的绝佳机会。 如果没有,也许我们需要完全不同的东西。 如果工具真的是通用的,并且从长远来看是属于基础的,那么随着时间的流逝,过多的否定也应该成为指导。 基金会最终比我们原先想象的要多得多,不仅仅是问题。 这是我们讨论团队前进方向的论坛。 即使我们基础上的活动放慢了速度,也并不意味着它不起作用。 相反,我认为事实恰恰相反。 随着摩擦的减少和结论的真实性,我们认为我们未来的自我会发现能够查明为什么,如何以及何时到达自己的位置会很有用。 如前所述,回顾过去可能是前进的最佳方式,但请记住,对过去的选择要仁慈,即使最终选择是错误的。 相反,拥抱并祝贺自己做出了选择。 我们仍然将Slack用作沟通的主要工具,但是一旦我们进入涉及做出会影响运营的决策的讨论时,我们就会将其移至基础,以便每个人都有时间参与。 最初,我想在一篇文章中总结所有内容,很快我发现一次开会的内容太多了,因此我决定将其分为四个部分。 这是“ 从灵感到生产” 的第一部分, 不要担心开发人员,即将到来的文章中将有一些代码片段。 您可以在Twitter @ zenangst和GitHub @zenangst上找到我 。

初级iOS开发人员6个月后获得的8个关键知识

我于2017年7月开始在臭名昭著的猫鼬(comparethemarket.com)背后的公司工作。我刚刚结束了为期3个月的编码课程,专注于Ruby和Javascript全栈Web开发,在完成我的最终项目后,我结束了加入流行的Meerkat电影应用程序背后的团队。 我很高兴有机会开始使用我以前没有经验的技术,并且从头开始学习如何成为移动开发人员。 我不仅要向自己证明,而且要向我的团队证明,尽管我缺乏相关技能,但确实有可能。 因此,我白天进行了视频课程,晚上则阅读了编程书籍,在同事的帮助和支持下,我很快就会发现自己为我们应用程序的代码库做出了贡献,并每天都在捡票。 但是,达到这一能力水平绝对是一路颠簸,途中遇到了许多主要障碍。 在许多领域,我仍然是一个完整的新手,需要学习更多知识。 但是,到目前为止,我所面临的挑战以及克服这些挑战的经验证明是宝贵的经验。 因此,我希望通过分享这份建议清单,我可以启发甚至帮助其他有抱负的(移动)开发人员,他们发现自己处于与六个月前相似的状况。 请享用! 1.开始使用该应用 如果您已经接受工作或开始工作,这无庸置疑。 但是,如果您正在公司面试,那么了解可能要使用的应用程序同样重要。 尝试像用户一样使用它,并进行一些案例分析-也许您会想到一些有关如何改进应用程序的想法。 就我而言,我将研究要看的电影,看一些预告片,通过搜索或使用当前位置找出在哪里看电影,兑换我的优惠券代码,最后购买我的打折电影票并去电影院。 这不仅帮助我更好地理解了产品(尤其是从用户的角度),而且还帮助了我要开发的代码库。 2. 找一位导师 …如果可能的话。 我没有被任命为正式的导师,但是从一开始我就很自然地开始受到我们团队中一名高级人员的监督。 关于我的发展和重点领域,我们经常进行代码审查和每月召开的会议,并且有人在跟踪我的进展并向我提供反馈。 这在开始时至关重要,因为要评估自己的进度并决定要专注于什么可能会非常困难,尤其是在刚开始的时候! 3. 制定计划 –并制定明确的目标。 如果没有计划,学习会变得势不可挡,尤其是当清单和资源似乎无限时。 制定目标和时间表,并要求您提供有关您的进度和正在进行的工作的反馈。 极大地帮助了我的一件事是创建了Trello板,其中包含针对iOS工程的概述技术路线。 4. 了解何时寻求帮助 重要的是要学习如何自己找到答案,而不要依赖他人来完成您的工作。 因此,我建议在寻求帮助之前,总是尝试自己解决所有问题。 但是,如果您尝试查找错误的时间超过30分钟,或者如果某个特定的概念没有被点击,那么向某人寻求帮助当然是相关的-绝对应该这样做。 但是,学习如何以最佳方式找到平衡使用资源的方法,而又不会滥用具有更多经验的人坐在您旁边的事实。 并非总是如此。 5. 交流! 如果您无法在约定的时间内完成分配给您的任务,请让相关人员知道并共同制定新计划。 另外,在冲刺计划会议中保持直言不讳,并参与评估票务,尤其是要处理的票证。 对自己的能力诚实是很重要的,并且有责任让您的团队知道您是否对某项工作的某个时间表存在疑问和忧虑。 但请放心,在您作为开发人员的第一份工作中,至少前3到6个月,您的工作速度会慢得多。 6. 做代码审查 参与他人的代码; 进行代码审查,并请您的同事向您介绍他们的代码。 看到更有经验的开发人员如何解决问题并让他们向我解释他们的工作方式,我学到了很多东西。 确保您有足够的时间与编写该代码的人一起阅读复杂的代码,以便以后理解。 另外,请尝试让年长者与您一起检查您自己的代码,并获得关于您工作的口头反馈,而不仅仅是对Github的评论。 最后,配对程序-这可能并非总是可行,但是我认为这是最好的学习方法之一。 7. 找到自己的学习方法 互联网上充斥着各种各样的学习资源,有时这可能会让人有些不知所措。 各种各样的书籍,博客,播客和视频课程无处不在,并且很难知道该选什么和从哪里开始。 问题是,没有“最佳”道路。 有些人通过阅读学习得更好,其他人则通过学习视频教程来学习。 但是,我将分享三个对我的学习最有帮助的资源,我将向在同一路径上的任何人推荐: […]

使用委托模式在控制器之间进行通信。

降低应用程序复杂性的一种好方法是委托模式。 这个想法非常简单:您无需在当前上下文中包含某些行为的代码,只需向上下文提供一个委托对象,然后由该委托对象的方法执行操作。 这与继承之上的构成保持一致:您的代码避免了超类及其子类之间的紧密耦合。 通过避免继承,您的代码可以更容忍修改。 通过使代码更具模块化,您可以避免处理过多职责的大型对象,从而使维护变得更容易。 这是一个简单的例子: 协议音箱{ 函数speak(); } 猫类{ 共鸣箱人声和弦 函数meow(){ vocalChords.speak() } } KittyVocalChords类实现了Soundbox { 函数speak(){ printToTerminal(“喵”) } } 猫玛丽亚= Cat.new() catVocalChords = KittyVocalChords.new() marya.vocalChords = catVocalChords 猫需要知道如何喵喵叫,但是猫可能还有其他不需要注意的行为。 将它们保持为单独的对象可以使您的声乐班级完成它的声乐事务,而猫则将其完成猫的事务。 您可以将所有这些信息转储到cat类中,但这会使cat类变得更加复杂,因此更加难以阅读和推理。 另一个选择是使用所需的方法定义基类,这将降低复杂性,但是现在您已经与该基类绑定不健康。 对基类所做的任何更改都会影响继承者。 例如,如果您希望狗类也继承定义语音行为的同一基类,该怎么办? 那计算机课呢? 除此之外,更改行为就像更改委托一样简单: 如果environment.dominate_gas ==氦{ marya.vocalChords = sweakyKittyVocalChords } else,如果environment.dominate_gas == NITROGEN { marya.vocalChords = normalKittyVocalChords } 我们唯一需要担心的是代表。 猫类从来不需要为在不同气体中的行为而烦恼。 因此,撇开人为的例子,这在iOS开发中具有价值。 在我正在开发的健身应用中,我使用容器视图。 […]