最好的部分是旅程 在2015年,我开源了一个名为SwiftyStoreKit的小型Swift框架。 目标: 在iOS上简化应用内购买 。 我以前曾写过关于它的经验的文章: 我如何在GitHub Project上获得1000⭐️ 这是关于我的旅程如何继续进行以及该项目如何推动我成为更好的开发人员的后续报告。 首先,我想分享一些很棒的资源,这些资源给了我启发,并提供了许多有关如何发展项目的实用技巧。 GitHub开源指南 开源指南 了解如何启动和发展您的项目。 开源指南 本指南包含一些很棒的材料。 我特别建议本节: 维护者最佳实践 从文档编制流程到利用社区,您都可以轻松地成为开源维护者。 开源指南 扩展开源社区 Felix Krause在他非常详细的“扩展开源社区”文章中谈到了开源项目的四个阶段。 摘要: 阶段1:在GitHub上放置源代码 阶段2:开发人员开始使用您的软件 阶段3:项目很受欢迎,并且是该领域的首选解决方案 阶段4:超大规模开源项目 我不能推荐这个。 去读吧 而这个: Artsy的开源 。 进入下一个层次 当SwiftyStoreKit去年变得流行时,开发人员开始提出问题并提出要求。 压力很大 作为唯一的维护者,由于许多问题,我感到有些压力: 问题列表正在增长。 其中一些强调了项目特定领域的缺陷。 StoreKit不是一个琐碎的框架,我对某些方面不太了解。 我担心在进行更改时会引入回归。 对于IAP多久失败一次以及在什么情况下失败,我没有任何度量标准。 我的用户销量下降了吗? 1%,5%,10%? 更多? 我无法在所有可能的端到端配置(iOS,macOS,tvOS,沙箱,生产,iTunes停机,帐户/ IAP配置问题等)中有效地测试我的媒体库。 保持理智 我意识到我必须做一些事情: 阅读有关StoreKit的更多信息,并确保我的实施符合Apple的准则。 井井有条,对问题和PR做出更及时的响应。 避免蠕变,并学会何时拒绝。 添加单元测试。 标准化和简化贡献,包括我的和其他用户的贡献。 我做了什么 完全以完整的单元测试覆盖范围重写了采购流程。 […]
当您开始一个新的iOS项目时,毫无疑问,您应该完全使用Swift编写它。 Swift已经接管了Objective-C多年了。 https://www.tiobe.com/tiobe-index/使用Swift强大的编译器,我们可以更安全,更快速地构建软件。 但是在现实世界中,我们可能会在Objective-C中面临许多过时的代码。 由于Swift / Objective-C具有出色的互操作性,因此我们可以维护包含它们的项目。 有关如何设置它们的信息,请查看https://medium.com/ios-os-x-development/swift-and-objective-c-interoperability-2add8e6d6887。 处理旧的ObjC的最常见策略是在Swift中编写任何新功能,并修改Objective-C文件以使用它们。 空性抬头 Swift是一种全新的语言,尽管它与Objective-C兼容。 Swift为我们介绍了一些基本类型,例如Date , Data , String。 并且它们可以自动桥接到Objective-C中的对象,即NSDate,NSData,NSString。 但是,由于Swift引入了optional / non-optional ,当Swift代码转换为Objective-C时,事情会有些棘手。 这是一个例子。 我们定义一些Swift函数,并通过添加关键字@objc使它们在Objective-C中可用 @objc func testString(_ string:String){print(string)} @objc func testData(_ data:Data){print(data)} @ objc func testDate(_ date:Date){print(date)} 在Objective-C中,我们会得到。 -(void)testString:(NSString * _Nonnull)string;-(void)testData:(NSData * _Nonnull)data;-(void)testDate:(NSDate * _Nonnull)date; 因为在Objective-C中没有可选/非可选 ,所以我们有_Nonnull。 有关Objective-C中的可空性的更多信息,请参阅 Apple的博客 )。 如果我们使用nil调用此函数,则只会收到警告。 如果我们不将nil显式地传递给这些函数(例如下面的代码),我们可能也不会意识到那些警告。 这些函数中传递的对象不能为nil,因为在Swift中将这些函数的参数定义为非可选的,因此Swift运行时将尝试从nil创建对象。 这是非常危险的,结果也令人惊讶。 [self testString:nil]; […]
我目前正在开发Patreon帐户。 如果您不知道Patreon是什么,那么它就是人们通过每月订阅来支持自己喜欢的创作者的一种方式。 每月订阅将由不同的级别组成,这些级别决定了您将获得的收益级别以及每月的订阅价格。 它的范围从每月1美元到……我不知道每月500美元……甚至更多。 每个创作者通常都会有一个每月要实现的目标。 通常,一个目标是希望获得多少收入,而花药通常是多少希望获得收入的粉丝。 这是一个非常不错的平台,因为它可以帮助各种创作者:1获得他们可能需要继续创造的经济支持,以及2培养忠实的粉丝群,他们可能不知道创作者在做什么。 我目前正在开发我的Patreon页面,希望在11月1日启动它。现在,我正在尝试弄清楚我的每个层将带来什么好处。 我所知道的是,只要是我的Patreon帐户的订户,任何人都可以参与帮助我创建我的每个应用程序,这让我感到非常兴奋。 至于定价,我将以很小的规模开始我的等级,主要是因为我是Patreon平台的新手。 我的主要目标是建立一群粉丝,一旦我能够发布我的应用程序,他们就会对下载我的应用程序感兴趣。 我的第二个目标是拥有一个收入来源,专门用于满足我的发展需求。 由于我不在理想的财务状况中,因此我需要更加专注于自己的发展,我希望这能够给我更多的创作自由。 我真的希望在未来五年内可以成为我的全职工作,或者至少是我的主要工作。 我真的认为这将是使我能够做到的真正伟大的垫脚石。
使用Travis CI for iOS应用程序构建持续集成管道。 meguid / travis-ci-pipeline 使用Travis CI for iOS应用程序构建持续集成管道。 – meguid / travis-ci-pipeline github.com GitHub帐户。 GitHub上托管的项目的所有者权限。 转到Travis并使用GitHub注册 接受Travis CI的授权。 您将被重定向到GitHub。 单击绿色的激活按钮,然后选择要用于Travis CI的存储库。 将一个.travis.yml文件添加到您的存储库中,以告诉Travis CI该怎么做。 将.travis.yml文件添加到git中,提交并推送,以触发Travis CI构建。 检查构建状态页面以查看构建是否通过。 你做到了!! 您已经建立了第一个婴儿CI管道 笔记: 用您的值替换WORKSPACEPATH , SCHEME和BUILDPATH 。 最好将osx_image设置为本地计算机上安装的相同xcode版本,以实现兼容性。 我更喜欢设置自定义derivedDataPath以便以后可以访问它以获取覆盖率。 使用osx_image值设置模拟器OS版本的数学设置(例如xcode10和12.0) 您可以将Swift更改为objective-c 。 通过选择产品→方案→管理方案…菜单选项,打开“管理方案”表。 在列表中找到要用于测试的目标。 确保已选中工作表最右边一栏中的“共享”复选框。 如果您的目标包括跨项目依赖项(例如CocoaPods),则需要确保已将它们配置为显式依赖项。 为此: 突出显示您的应用程序目标,然后单击“编辑…”按钮以打开“方案”编辑表。 单击方案编辑器左侧面板中的“构建”选项卡。 单击+按钮,然后将每个依赖项添加到项目中。 CocoaPods将显示为名为Pods的静态库。 将依赖项拖到测试目标上方,以便首先构建它。 现在,您的Xcode项目下面的xcshareddata / xcschemes目录中将有一个新文件。 这是您刚配置的共享方案。 […]
2015年,在著名的iOS会议NSSpain’15上,Soroush Khanlou作了介绍性演讲“ Presenting Coordinators”。 在这次演讲中,他描述了协调员的整个想法,并展示了一些用Objective-C编写的示例。 总体思想来自《企业应用程序体系结构模式》一书,该书解释了应用程序控制器模式,并被Soroush采纳用于移动开发。 您可以在此处查看演讲视频。 我一年前喜欢这个视频,整个想法给我留下了深刻的印象。 在二月的一个寒冷的夜晚,我用这种架构方法的第一次迭代编写了一个示例项目。 当然,我使用Swift作为主要语言。 之后,我一步一步改进了这种方法,并涵盖了越来越多的用例。 两个月后,我开始将协调器集成到生产应用程序中。 最初,协调员只驱动了少数功能,但最后,应用程序的框架却完全由它们驱动。 后来,我添加了深层链接支持,推送通知,强制触摸功能以及灵活的流程,所有这些都由协调员处理。 我现在想与您分享的是这种经历。 如果您想跳过我的解释并查看代码,请访问以下链接。 让我们从一堆问题开始。 什么是移动应用程序中的流程? 流是逻辑上链接的屏幕队列。 我们所有的屏幕都可以按流程划分:身份验证流程,电话验证流程,预订流程,个人资料编辑流程等。 我们通常如何管理流中的屏幕? 假设我们有一个身份验证流程,并且在流程中我们需要验证用户的电话。 让我们以这样的方案为例: 我们通常如何处理此流程中的导航? 在最常见的情况下,控制器告诉路由器推送新的控制器。 它在代码中的外观如下: 下一个常见情况是在控制器之间发送数据。 想象一下,我们有一堆控制器,我们需要在它们之间共享数据。 我们如何做到这一点? 使流独立的另一个常见原因是它们可以在不同地方重用的能力。 例如,假设您有一个电话验证流程,然后成功将其用作身份验证流程的一部分。 现在,如果您需要在配置文件中使用相同的流程,则可以。 引言摘要 直接处理流程的方法通常非常糟糕: 控制器很难重用 每个控制器都知道其他控制器 很难改变流量 很难测试 协调员 模组 首先,让我们介绍一下模块。 模块是MVC,MVP,MVVM和Viper架构方法的一种架构元素。 在最简单的情况下,对于MVC,模块是控制器,对于Viper,模块是Interactor-Presenter-View。 我们需要做的是编排模块。 什么是协调员? 协调器是一个对象,该对象处理导航流并在打开下一个链后共享下一个协调器的流处理。 这意味着协调员应仅在屏幕之间保持导航逻辑。 协调器可以保留对存储的引用,该存储包含工厂用于创建模块的数据,但是它们永远不能处理模块的业务逻辑,也不能驱动单元的行为。 只有在点击一个单元格后按下下一个屏幕时,才发生单元格交互。 我们为什么要使用它? 主要目标是承担模块之间的未链接责任,并彼此完全独立地构建模块。 迭代之后,我们可以轻松地以不同的流程重用它们。 回到前面的示例,让我们看一下如何改进身份验证流程。 首先,我们需要分离两个不同的流程:身份验证和电话验证。 拆分后,我们可以在所需的任何地方重复使用它们。 […]
对于我们在Makers Academy的最终项目,我们的团队提出了一个想法,即创建一个用于检测空气污染水平的增强现实应用程序。 基本思想是学习一种新语言和新技术,这促使我们在第一天进行探索,看看是否更适合开发增强现实应用程序的Android Studio或Xcode。 由于Cindy和我都是Android Phone的忠实用户,因此我们在Android Studio上开发了一个演示Android App。 作为iOS用户的Noelle和Somayeh使用Xcode开发了演示iOS应用程序。 事实证明,Xcode拥有ARKit,可将数字对象和信息与您周围的环境融合在一起,使应用程序远远超出屏幕范围,并释放它们以全新的方式与现实世界进行交互。 第2天,我非常兴奋能在Xcode中对ARKit进行更多的探索,并开始在Xcode中构建我的第一个AR App,它看起来像这样。 我对第一个AR演示应用程序感到非常满意,然后用3D Globe替换了它,为此我基本上在项目中更新了View Controller文件以显示Globe。 当我们进入第3天时,我们对MVP有了一个更好的了解,并且对Xcode中的ARKit有深入的了解。 当我们遵循Makers的测试驱动开发(TDD)时,第3天更多地是要弄清楚Xcode中的单元测试和UI测试。 经过一些研究发现,Xcode具有内置的测试框架XCTest。 我在Xcode上找到了一个有关FizzBuzz测试的非常有用的博客,然后继续为iOS构建FizzBuzz游戏,以便在Swift中练习TDD。 Swift 3中的TDD入门 已针对SWIFT 3和XCODE 8更新 通过上面的博客可以帮助我理解XCTest框架的基础。 我们的MVP包括拥有AR iOS应用程序,该应用程序可以检测给定GPS坐标下的空气污染水平。 基本上,我们计划通过添加不同的表情符号以显示不同程度的污染,将有趣的元素引入我们的应用程序。 我将在我即将发布的博客中向您发布有关我们项目进度的信息。
导航窗格使我们可以在项目的各个部分之间移动。 在导航窗格中,我们有8种类型的导航器。 我们可以通过将鼠标悬停在每个图标上来找到每种类型的导航器。 这将是一个小技巧,例如“ Show project navigator”等。 按顺序有不同的导航器: 项目浏览器 源代码管理导航器 符号导航器 查找导航器 问题导航器 测试导航器 调试导航器 断点导航器 报表浏览器 在开始阶段,我们最常用的导航器是项目导航器和问题导航器。 项目导航器将我们的程序文件组织到各个部分中。 我们将把大部分时间都花在项目导航器上。 问题导航器将显示无法构建我们的应用程序时遇到的所有问题。 问题导航器会将我们带到问题所在的正确位置,以便我们进行修复。 项目浏览器 项目导航器是最常用的部分。 在项目导航器中,我们有多个下拉文件夹,从项目文件夹开始,然后是3个子文件夹。 如果我们通过单击三角形进一步扩展文件夹,它将显示每个文件夹下的所有文件,如下所示。 要构建一个应用程序,我们需要利用多个文件。 项目配置 要浏览项目配置,我们必须在项目导航器中选择项目标题,如下所示: 选择项目标题后,中间的部分将显示详细信息,如下所示: 这是项目配置页面。 本部分允许我们设置构建属性或更改那些设置。 项目配置页面非常复杂。 我们将仅覆盖“常规”标签下的前3个部分。 第1部分:身份-本部分显示基本信息,例如项目名称及其版本。 第2部分:签名-当我们需要部署应用程序时,本部分很重要。 否则,我们可以忽略错误消息。 第3部分:部署信息-本部分说明如何部署我们的应用。 请参考以下详细信息: 部署目标是指当前版本的iOS 设备使我们能够为iPhone或iPad或两者构建应用程序。 如果设备设置为“通用”,则可以在iPhone或iPad上运行应用程序。 我们通常不调整主界面。 我们将其保留为原样。 设备方向允许我们为应用设置方向。 我们可以删除横向复选框,以便我们的应用仅在纵向模式下运行。 我们将其余设置保持不变。 我们将更改的常见设置是“设备”和“设备方向”。 主项目文件夹 大部分程序文件位于主项目文件夹中,如下所示 我们将触摸AppDelegate.swift,ViewController.swift,Main.storyboard,Assets.xcassets和info.plist AppDelegate 选择文件AppDelegate.swift,如下所示。 中间部分将显示此文件的详细信息。 AppDelegate.swift是应用程序的主文件。 […]
弹出窗口很重要。 有时,它们很烦人(是的,我说的是网页上的随机弹出窗口)。 当它们很重要时,它们可以显示有关应用程序执行,状态管理,要求用户提供输入或某些访问权限等信息。 那么,如何在iOS应用中显示有意义的弹出窗口? 让我们找出答案! 启动Xcode 首先,让我们在Xcode上打开一个项目。 我们还要如何开始? .__。 创建一个单视图iOS应用程序 。 接下来,在启用了助手编辑器的情况下打开Main.storyboard 。 现在,让我们凝视空白的UIView一会儿,然后迷失在应该做什么上。 好吧,没那么多。 我们需要显示一个弹出窗口。 但是弹出窗口需要由某种东西触发,或者用一些事件/动作来触发。 那么我们如何触发事件/动作 ? 考虑可以触发或向ViewController发送某些动作的控件。 最简单的方法:添加按钮! 好的,让我们向视图添加一个按钮。 但是,仅添加按钮就能完成我们的工作吗? 不。 这不是魔术! 首先,为按钮创建一个插座,因为按钮无法创建自身。 ( 按住Ctrl键并单击鼠标左键,然后将其拖放到ViewController.swift文件中)。让我们将其命名为popButton 。 现在,您的ViewController.swift文件应如下所示。 那个小按钮? 继续前进,按钮看起来很小,但吸引力不大。 让我们添加一些样式。 就我们而言,仅更改Font和Font大小就可以了。 还让我们给它一个有意义的标题,而不只是“ Button ”。 根据图像设置字体和标题。 现在,我们正在进行样式设计,现在,我们的按钮如下所示– 我知道你会问这个问题。 稍安毋躁。 我们到了那里。 是时候添加一些动作了! 好的,现在让我们为按钮插座创建一个动作。 将其命名为showPopUp。 应该是这样的 现在已经定义了动作,让我们开始显示弹出窗口。 UIAlertController:那是什么? UIAlertController负责在我们今天看到和使用的iOS应用程序中创建弹出窗口。 因此,按照Apple Documentation的术语,我们需要创建一个UIAlertController实例并呈现 (显示)它。 首先创建UIAlertController 。 actionSheet弹出窗口从底部显示,可以容纳多个动作。 […]
本篇文章没有要讨论安全区域是什么,只有单纯纪录如何使用界面生成器来更改原始导航栏或工具栏 会有这个需求是因为画面客制化的关系,没办法直接使用原生的导航栏/工具栏,得自己刻出类似的画面。 如果直接把灰色视图的顶部,前导,尾随约束指向安全区域,会变成上图右边的状况,status bar的部分会空着,没办法像左图那样的效果 把view的顶部约束指向指向superview,结果赋予view跑到status bar底下 回到上一个状态(顶部约束指向安全区域),在视图中间加入一个标签,执行结果如下图,但我想要达成的效果应该是标签在相同的位置,视图的高度不变,然后状态栏跟随标签所在的视图是一样的颜色 以下的view指的是灰色长条状,用作考虑的标签的superview 将标签的顶部约束重新指向视图控制器>视图>安全区域 2.将视图的顶部约束改为指向超级视图,常量设为0,高度设为≥44 3.重新执行后,画面就会如预期想要的那样 4.要特别注意的,标签一定要加上底部约束指向视图,不然就会出现下图的状况 等等,还没结束 以上的作法都是在storyboard完成的,但在xib上会遇到什么事? 一样的autolayout配置,使用在xib上,在iOS12上看是正常的,但iOS10就跑版了,有一部分跑到status bar底下去(如下图) label增加一个约束(要查看的顶部空间),常量设置≥32,优先级设置为1000,原本指向视图控制器>视图>安全区域的约束(将顶部对齐至安全区域)优先级设为750,再执行一次就可以看到正常的画面 我把范例档案放在这边,有兴趣的话可以载来看看! iOS –安全区域布局在iOS 9和iOS 10上不起作用 感谢您为Stack Overflow提供答案! 您过去的一些答案尚未得到很好的接受,您正在… stackoverflow.com
快速说明-我将来所有的帖子都将发布在我的专用网站上,并且此出版物不再更新。 谢谢阅读! 令人惊讶的是,我们不久之前就生活在一个“自动布局”世界中。 自动调整遮罩大小和CGRectMake()统治了相当长一段时间的用户界面开发领域。 但是随着苹果设备开始堆积各种点大小,很明显,开发人员要么陷入痛苦,要么因过多的框架计算而陷入困境,要么接受描述关系的力量。 后者显然胜出。 因此,自此以来,Auto Layout就一直被使用,DSL和批评。 但是,随着它的兴起,另一种布局范例也应运而生。 “间隔”视图。 或虚拟视图。 容器视图。 无论您怎么说,我们都使用过它们。 但是苹果公司说,有一种更好的方法。 本周,让我们聊天UILayoutGuide 。 但是,虚拟景色岩石(…并且我同意) 虚拟视图非常好地解决了一些布局问题。 这就是为什么我们都使用它们。 表达视图间的关系,创建用户界面的模块块或定义约束以表达视图之间的空白空间的坐标或大小,所有这些都称为虚拟视图。 实际上,即使只是希望将一组控件放在特定坐标空间的中心,也常常使用虚拟视图来包含它们。 这样,许多重要的工作都被委托给了一个从来没有真正去做任何事情的结构。 如果您反对这种想法,请问自己一个视图在iOS应用程序中的实际作用。 或者更好的是,让文档讲故事: 视图对象在其边界矩形内呈现内容,并处理与该内容的任何交互。 视图是UIResponder的子类,可以响应触摸和其他类型的事件。 因此,几乎无可辩驳的是,视图的重要组成部分是视图,即渲染事物和处理事件。 虚拟视图,尽管它们是视图,但最好不要参与其中的任何活动,最坏情况下不要参与其中的一些活动。 使用虚拟视图,我们已经 产生仅有助于定义布局的视图的成本。 添加了视图层次结构的第一类成员,加入了可能与之相关的任何任务相关的所有开销。 并且作为响应者链的一部分,它可以拦截一些原本不想处理的消息。 😬。 在那里,但不是真的 但是,布局指南既不是这些东西,也不会遭受任何这些问题的困扰。 这是一个非渲染视图,非常类似于其更强大的表亲UIStackView 。 与真实视图不同,布局指南实际上并未定义视图。 取而代之的是,它仅代表其拥有的视图的坐标系中的矩形区域。 而已。 这就是它与自动版式进行交互的原因。 该API紧密地(有意地)镜像视图的镜像: 让scrollView = UIScrollView()//代替这个… 让containerView = UIView() scrollView.addSubview(containerView)containerView.widthAnchor.constraint(equalTo:scrollView.widthAnchor).isActive = true containerView.heightAnchor.constraint(equalTo:scrollView.heightAnchor).isActive = true containerView.leftAnchor.constraint(equalTo:scrollView.leftAnchor).isActive […]