Tag: macos

Swift中面向框架的编程

我受到Justin Spahr-Summers在2015年Pragma会议上的演讲的启发,他为设计可用和赋予用户权限的库提供了知识和动力。 面向库的编程 创建一个简单的,可封装的,可维护的库似乎是个白日梦,但实际上是可以实现的…… academy.realm.io 因此,我开始应用这些创建框架的原则来分离关注点,并在应用程序中创建了大约8–9个框架,其中一些如下。 RKUIKit RKCoreData RKNetworking RK基金会 …。 更多 当这些框架都是从Apple Xcode模板提供的初始结构开始时,创建它们就很困难。 因此,我在互联网上寻找解决方案并找到了cookiecutter。 一个命令行实用程序,可从cookiecutter(项目模板)创建项目。 例如Python封装项目,jQuery插件项目。 我创建了一个FrameworkTemplate,以使所有框架均可用于开源,包管理器,iOS / macOS / tvOS / watchOS,travis-ci,README,github模板等。 JetpackSwift /框架模板 FrameworkTemplate —一个新的Swift iOS / macOS / tvOS / watchOS框架项目的模板,已准备好travis-ci… github.com

在Swift中选择正确的失败方法

Swift的一个主要重点是编译时安全性-使我们(作为开发人员)可以轻松地专注于编写可预测性更高,更不易出现运行时错误的代码。 但是,有时事情确实由于各种原因而失败-因此,本周,让我们看一下如何适当地处理此类失败,以及我们可以使用哪些工具来做到这一点。 几周前,我们在“在Swift中处理非可选的可选内容”中介绍了如何处理不是真正可选的可选内容 。 在那篇文章中,我介绍了将preconditionFailure()与guard结合使用的情况,而不是强制展开,并介绍了微框架Require,它提供了方便的API。 从那篇文章开始,许多人问到preconditionFailure()和assert()之间有什么区别,以及它与Swift的throwing功能之间的关系。 因此,在这篇文章中,让我们仔细研究一下所有这些语言功能以及何时使用它们。 让我们从清单开始 据我所知,这是所有可以处理Swift中错误的方法: 返回 nil 或错误枚举值。 错误处理的最简单形式是从遇到错误的函数中简单地返回nil (如果使用Result枚举作为返回类型,则返回.error情况)。 尽管这在许多情况下确实很有用,但将其过度用于所有错误处理会迅速导致使用API​​麻烦,并且还存在隐藏错误逻辑的风险。 引发错误 (使用throw MyError ),这要求调用者使用do, try, catch模式处理潜在的错误。 另外,可以使用try?忽略错误try? 在呼叫站点。 使用 assert() 和 assertionFailure()来验证某个条件为真。 默认情况下,这会在调试版本中导致致命错误,而在发行版本中会被忽略。 因此, 不能保证触发断言后执行就会停止,因此有点像严重的运行时警告。 使用 precondition() 和 preconditionFailure()代替断言。 关键区别在于,即使在发行版中,也总是*对它们进行评估。 这意味着您可以保证,如果不满足条件,执行将永远不会继续。 调用 fatalError() -在子类化符合NSCoding系统类(例如UIViewController fatalError() ,您可能已经在Xcode生成的init(coder:)实现中看到了此NSCoding 。 直接调用它会杀死您的进程。 调用 exit() ,使用代码将其存在于您的进程中。 当您可能想退出全局范围时(例如在main.swift ),这在命令行工具和脚本中非常有用。 *除非您使用 Ounchecked 优化模式 进行编译 。 可恢复与不可恢复 选择正确的失败方法时,要考虑的关键是确定所发生的错误是否可恢复 […]

用嵌套类型命名Swift代码

– ⚠️已弃用 有关本文的最新版本, 请在Sundell的Swift上阅读 ,而您也可以在其中找到100多种有关Swift的文章。 中型版本尚未针对Swift的最新版本进行更新,也未进行其他改进(例如语法突出显示)进行了更新。 – 尽管Swift尚未提供专用的namespace关键字,但它确实支持其他类型的嵌套类型。 让我们看一下如何使用此类嵌套类型可以帮助我们改善代码的结构。 许多Swift开发人员习惯于通过在类型的实际名称中包括结构级别来进行命名PostTextFormatterOption -使用诸如PostTextFormatterOption (用于Text Formatter PostTextFormatterOption的Text Formatter的Option )之类的名称。 这可能是因为,这几乎是在Objective-C和C中进行“穷人命名”的唯一方法,并且像许多其他约定一样,它已经延续到Swift中。 让我们以上述类型为例,看看Post , PostTextFormatter和PostTextFormatterOption : 现在让我们看一下如果我们将它们构造为Post内部的嵌套类型,则上述类型将如何变化: 嵌套类型方法的一大优势是,我们现在可以通过快速查看代码来清楚地看到类型之间的结构和关系。 我们还减少了初始化程序中的冗长性,使其更短Set易于阅读(现在options参数只是Set类型而不是Set )。 现在,我们在呼叫站点也有了清晰的层次感-与Post相关的所有内容现在都在Post.下结构整齐Post. 命名空间。 以下是格式化帖子文本的格式: 但是,使用上述嵌套类型也有很大的弊端。 该代码在垂直方向上是“向后”的,其中父类型的实际内容一直向下推送到底部。 因此,让我们尝试通过翻转结构来解决此问题-将嵌套类型向下移动到底部,而不是将它们放在顶部(为方便MARK ,我们还会添加一些MARK )。 到底是将嵌套类型放在顶部还是底部,这绝对是个人喜好。 我有点喜欢它如何使父类型的实际内容保持在顶部,同时仍为代码提供嵌套类型的层次结构好处。 但是,就像Swift中的许多其他功能一样,事实证明,还有很多其他方法可以实现命名空间和嵌套类型。 扩展中的嵌套类型 一种选择是使用扩展来实现您的嵌套类型。 这使您可以更清楚地区分类型,同时在实现和调用站点中仍保留层次结构。 这是我们的类型的外观: 使用类型别名 您还可以在原始代码(不使用嵌套类型)中添加类型别名,以实现嵌套的类型化行为。 尽管这不能为您提供实现中相同的层次结构,但是它确实有助于减少冗长性,并且在调用站点上也提供与使用嵌套类型时相同的好处。 该选项如下所示: 结论 使用嵌套类型可以帮助您在代码中创建一个非常漂亮的结构和层次结构,以使您更加清楚各种类型之间的关系-在实现中和在调用站点中。 但是,根据您选择实施这些技术的方式,您可能还会面临其他挑战和副作用-因此,我认为根据情况选择技术真的很重要,这样才能最终赢得胜利。 你怎么看? 您更喜欢使用以上哪种技术来命名代码? 还是找到了另一个? 在Twitter @johnsundell上让我知道,以及任何问题或评论。 (哦,顺便说一句,从Swift 3.1开始,嵌套类型也可以在泛型内部使用!🎉…但有关更多信息,请参见即将发表的文章😉) 谢谢阅读! […]

具有工具栏的macOS简单自定义窗口-第2部分

我希望工具栏中有一个小的图像,以指示“浅”或“暗”外观。 我将使用在第1部分中创建的项目。 步骤1.我使用Figma放下了两个图标,并对它们进行了着色,并使用@ 2x作为名称将它们保存为64×64大小。 步骤3.打开情节提要,然后将“工具栏”拖放到窗口中。 从工具栏中删除所有元素,然后添加ImageView。 步骤4.将ImageView连接到CustomWindow.swift。 如下更新代码。 如果我想以编程方式添加NSImage会怎样? 我最喜欢的开发工具之一是PaintCode。 使用此工具,我可以轻松地从.svg创建Swift(或Obj-C)代码。 第1步。让我们转到Storyboard,然后将ImageView添加到View Controller。 然后将其作为IBOutlet连接: @IBOutlet var imageView:NSImageView! 我们将再次需要两个图像用于“亮”和“暗”状态。 重复深色版本,然后保存。 最后,将其添加到Xcode中的项目中。 步骤3.到目前为止一切顺利,但是我们的应用程序将如何得知外观变化? 幸运的是,有一种简单的KVO方法。 如下更新我们的ViewController: 资料来源: Mohammad Asgharneya:涂成黑色:macOS Mojave中的黑暗模式 您可以在此处找到源代码。

配置MacOS进行iOS开发

您需要什么来开始在全新Mac上首次开发iOS应用程序? 在这篇简短的文章中,我将尝试描述我所做的事情,以确保不必因某些配置丢失而中断我的开发原因。 Xcode 当然,我们不能忘记Xcode。 某些人可能更喜欢使用JetBrains的AppCode,但是迟早要使用Apple的IDE及其随附的工具。 您可以从AppStore中获取它,但是根据您所开发的内容(或应用程序的发布距离),您可能希望从此处下载Xcode的较早版本-您不需要付费的开发人员帐户😉。 当您的应用程序处于稳定阶段时,通常需要较早版本的Xcode,此时切换到最新版本的Xcode可能会导致某些问题,因此最好坚持使用已经测试过的应用程序版本(除非您编写了不错的测试那么您可以更轻松地切换到新的Xcode)。 Visual Studio程式码 我最喜欢的编辑应用程序是我不使用Xcode进行编辑的任何应用程序,例如格式化JSON / XML,编写bash脚本等。我也将其用于Flutter开发-为此,您只需要Flutter的“入门”中提到的F​​lutter插件即可。指南。 源树 对于git相关的东西,我通常使用命令行工具或SourceTree。 真的不能再多说了,您要么喜欢,要么不喜欢。 家酿 它是一个程序包管理器,很可能需要在某个时候安装一些程序包/应用程序。 不过,您可以在开始iOS开发的过程中跳过此步骤。 邦德勒 什么是捆扎机? Bundler通过跟踪和安装所需的确切gem和版本,为Ruby项目提供了一致的环境。 对于使用CI / CD(连续集成/交付系统)的项目而言,这是非常重要的,因为所有(宝石)依赖项都将同步,并且您可以确保,如果您的构建在您的计算机上可以运行,则(应该)在其他计算机上也可以运行。机器也是如此。 同样,当一个新手加入项目时,只需用一个简单的命令下载所有项目(宝石)依赖项,而不是“一个接一个”地安装所有……而不是忘记正确的版本,会更容易。 我强烈建议安装和使用它 。 虽然,一旦尝试使用gem install bundler命令安装它,它可能会因权限错误而失败。 如果您用google搜索,将有一些有关如何解决该问题的建议(例如简单地使用sudo,但我们真的要这样做吗?)。 我更喜欢另一种方式,修改您的.bash_profile文件并添加以下行: 关于如何解决该问题的方法(就像简单地使用sudo一样,但是我们真的要这样做吗?)。 我更喜欢另一种方式,修改您的.bash_profile文件并添加以下行: export GEM_HOME=”$HOME/.gem” export PATH=”$GEM_HOME/bin:$PATH” 并且权限问题应该消失了。 它只是修改了gem的home路径,并将其设置到HOME文件夹中的一个文件夹中,因此您对此具有权限,并且不会与其他mac的用户覆盖gems。 可可豆 可能是iOS / MacOS开发中最受欢迎的依赖项(pod)管理器。 豆荚的基础非常广泛,这使得它真的很容易使用。 唯一的缺点是它的发布周期很慢,并且可能并不总是与Xcode的最新更改保持同步。 无论如何,通常开放源代码项目都使用它(以及很多商业广告也很有可能),因此您迟早会需要它。 快车道 如果您在一个项目中以更大的团队工作和/或使用CI / CD,则对同步应用程序测试及其发布过程将大有帮助。 尽管最近苹果公司开放了他们的App Store Connect API,所以很快就会出现一些更简单的应用程序/脚本来完成这项工作。 […]

用于多平台开发的模块化体系结构:第2部分

这是3部分系列的第二部分。 您可以在这里找到其他部分: 第1部分:简介和设置 第3部分:演示和UI 配套项目: Github 接口 正如我们一开始提到的,该项目的目标之一就是创建一个模块化的体系结构。 模块必须能够与他人对话,而且必须松散耦合,以使体系结构保持软性,灵活性和适应变化的能力。 例如,如果我们决定将ShowEngine实现更改为依赖于其他图像提供程序,则它不应影响任何其他模块。 我们可以通过协议或闭包来实现。 对于这个项目,我想要一个更具描述性的解决方案,因此我选择了协议。 让我们在ShowEngine类中实现协议接口。 考虑创建接口的简单方法是输入/输出。 ShowEngineInput协议定义了模块与ShowEngineOutput进行对话的所有方式, ShowEngineOutput协议定义了与其他模块进行对话的所有方式。 我们希望其他人能够start和stop ShowEngine 。 我们希望其他人被告知imageLoadSuccess和imageLoadFailure : 注意,我们通过:AnyObject关键字将协议采用仅限于类。 从Swift.org文档中: 当该协议的要求定义的行为假定或要求符合类型具有引用语义而不是值语义时,请使用仅类协议。 定义好接口后,让ViewControllers和InterfaceController符合它。 请注意,我们将ShowEngine属性声明为weak以解析强引用。 工厂和作曲家 我们不能简单地在每个ViewController和InterfaceController组成ShowEngine ,因为那样会创建强大的参考。 解决方案是使用Factory和Composite模式。 这些将成为我们Main模块的一部分: 工厂组成 我们在AppDelegate实例化ShowEngineUseCaseFactory ,将ViewController的实例作为输出,并使用属性注入分配ShowEngine用例实例。 界面已完成。 使用定义明确的模块,我们现在可以分手工作。 我们可以有一个团队在框架实现上工作,而一个或几个团队可以在SlideShow实现上工作。 该工作可以并行进行。 只要每个人都遵守已定义的界面,就可以全力以赴!

探索NSTextField

最近,我正在一个简单的待办事项列表应用程序中玩NSTextField。 我想在每个待办事项中包含一个可编辑的文本字符串。 我写这篇文章是为了谈论我一直在申请的东西。 建立项目 这是一个待办事项列表,我将使用NSCollectionView构建基本的UI。 该布局是一个简单的基于行的垂直布局。 我可以使用NSCollectionViewFlowLayout轻松实现这一点。 显示待办事项 由于我要显示的待办事项内容非常简单,因此我选择一个NSTextField作为容器。 我还将默认textField变量链接到放置在该项目中的NSTextField组件。 现在,我可以通过设置“ textField?.stringValue ”轻松显示待办事项。 NSTextFieldDelegate中的回调 该协议实际上是NSControlTextEditingDelegate的扩展,其中提供了一些基于NSControl的委托方法,这些方法仅适用于文本编辑功能。 默认协议方法提供了在编辑文本内容之前和之后的挂钩。 通过编辑,这意味着在更改内容时在键盘上键入。 实际上,我想在单击该项目时收到通知。 然后,我可以修改内容,然后按“ Return ”以保存更改。 子类化NSTextField 为了通过单击该项目获得通知,我将在NSTextField中重写成为firstFirstResponder() 。 我还创建了相应的委托方法,以便可以在单击项目的基础上进行更改,例如显示插入符号或将应用程序更改为编辑模式等。 拦截返回键 这是通过实现有关命令选择器的委托方法来完成的。 每个键盘命令键都会生成此方法的回调。 通过比较当前的命令选择器,当按下“ Return ”键时,我会收到通知,命令选择器为“ insertNewline(_ 🙂 ”。 然后,我可以保存待办事项,然后更改回查看模式,等等。 摘要 NSTextField的工作逻辑与iOS的UITextField完全不同。 NSTextField委托的文档非常含糊。 在实现您的欲望逻辑之前,应该更谨慎一些,并回避这些回调。

自定义MacOS App图标-多个Xcode版本

作为iOS开发人员,我经常处理多个Xcode实例,并且总是感到困惑,哪个图标代表哪个版本。 例: 1. Xcode 9.4.1 2. Xcode 10.0 3. Xcode 10.1 那时我意识到我们实际上可以添加自己的自定义图标。 好吧,我很高兴你问! 步骤1:建立您的自订图示 作为一个好的手势,我将在此处提供一个PSD File以便您还可以编辑Xcode实例的图标(如果您也是iOS开发人员:)。 您也可以将上面的图像另存为PNG File ,并在下一步中使用它。 步骤2:套用自订图示 转到“ Applications -> Xcode -> Right Click -> Get Info在“信息”屏幕中,找到左上角的当前图标,单击一次,您应该看到它带有蓝色边框突出显示。 在预览中打开自定义图标图像文件 。 复制图像内容并返回到“ 获取信息”页面,并且蓝色突出显示仍处于活动状态, 粘贴。Tadaa! 您已经应用了自己的自定义应用程序图标 ! 您可以对任何应用程序执行此操作(我相信,除非有阻止它的方法),您将能够拥有自己的外观和感觉!

故事集:升级到macOS 10.12

上周,苹果宣布了其台式机操作系统macOS 10.12的下一个迭代版本,放弃了OS X主题,加入了tvOS,iOS和watchOS。 因此,经过深思熟虑,我决定在备用计算机上进行旋转,看看它如何运行,我不得不说我很惊讶。 进行升级 首先, 您需要一个Apple开发者帐户才能访问开发者版本。 一旦获得,它将下载内容添加到您的App Store“购买”中,整个下载量约为5.2gb,因此请等待。 下载后(建议您确保您拥有最新的Time Machine备份),让它开始运转…… 整个过程大约需要25-30分钟,但不要中断它,而且初始登录可能看起来像被锁定了,但是离开它,它将完成。 您会注意到一些新情况,首先,您将Siri放在扩展坞上,iCloud会询问您是否要优化存储,这是您是否想将Documents&Desktop目录同步到以下位置的一种奇特方法:云这是非常有帮助的。 现在起初我发现它很慢,但是在事情解决之后,这种情况就消失了,但是我确实不得不删除了一些启动项( backblaze似乎使事情变慢了, lima和seil证明是不兼容的)。 设置自制软件和XCode 8.0 要清理自制程序,您需要返回至developer.apple.com 并下载XCode 8.0。 与其他下载不同,这是一个xip文件,需要花费一些时间才能取消注释和验证,我估计此过程需要45-90分钟,因为最终过程将需要一些时间。 现在打开Terminal或iTerm并使用xcode-select切换工具链目录 sudo xcode-select –switch /应用程序/Xcode-beta.app/Contents/Developer 然后通常通过以下方式安装命令行工具 xcode-select-安装 之后,您应该没事。 我注意到的一件事是,node.js花费了很长时间进行编译,因此您可能需要转到https://nodejs.org下载预编译的二进制文件。 应用程式相容性 不相容: 调酒师2,在接下来的2-3周内将进行修复 Seil,键盘映射应用 利马,个人云存储 兼容: Arq 5 iTerm 2 自制 更新资料 1天后,一切似乎运行顺利,Documents&Desktop的iCloud备份花了一些时间才能开始,但是开始运行良好。 我还注意到我需要重建Spotlight缓存,因为它找不到我的应用程序,我通过完全破坏缓存并通过以下方式强制重建来解决此问题: 停止索引 sudo launchctl卸载-w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist 删除索引 须藤rm -rf /.Spotlight-V100 开始索引 sudo […]

为NSView设置背景色

macOS(以前称为OS X)开发一直是我的一个充满激情的项目。 首先就是要进入应用程序开发。 我从未真正想为iPhone制作应用程序,我想为macOS设计出色的应用程序,从而帮助了我。 就我而言,不幸的是,据我所知,奥斯陆的macOS开发人员市场并不存在。 不要误会我的意思,我非常喜欢为iPhone,iPad和AppleTV制作应用程序,但是我从未忘记自己的根源以及一切的开始方式。 我一直试图使其通过爱好项目,并在可行的情况下为我贡献的所有框架添加支持macOS。 您可能想知道当谣言指向Apple统一API时使我花时间的原因,从而使macOS更类似于iOS / tvOS的对应部分。 好吧,我们还没有活在那个未来,我很享受。 就这么简单。 在经过较长的iOS / tvOS开发后回到macOS之后,我可以看到它是如何“变质”的。移动开发人员很方便。 iOS起源于macOS,但是Apple做出了巨大的贡献,为我们的开发人员简化了日常操作。 因为我感觉到macOS的开发正逐渐成为一种迷失的艺术形式,所以我将开始分享一些技巧,窍门和说明,这些内容是我为Mac编程时偶然发现的。 我们将从简单的内容开始,将背景色设置为常规视图。 即使这对于许多人来说似乎很明显,但对于某些人来说可能并不是那么简单,尤其是如果您已经被便利所困扰。 首先,让我们看一下这是如何在iOS和tvOS上完成的。 这是非常简单的方法,我们创建带有框架的UIView并使用UIColor设置背景色。 因此,让我们为macOS做等效的事情。 创建视图是“相同但不同”,而不是UIView而是创建NSView ,但是您可能已经知道这一点。 因此,让我们进一步看一下这两个视图的偏离位置。 UIView是用于设置背景颜色的属性,而NSView缺少一种。 相反,您必须在视图层上设置背景色。 为了使事情更不方便,默认情况下, NSView没有附加图层。 要获得一个,必须将wantLayer设置为true 。 这将创建一个图层并将其分配给视图上的可选layer属性。 这将使您的视图层化。 最后但并非最不重要的一点是,因为我们将背景色设置为图层,所以我们不能直接使用NSColor而是必须使用CGColor ,这当然很容易做到,但与iOS相比却不是那么方便。 那么,为什么NSView上的layer是可选的,文档有助于对此有所了解: 将此属性的值设置为true会将视图转换为层支持的视图-即,该视图使用CALayer对象管理其呈现的内容。 创建隐含层的视图会隐式地导致该视图下的整个视图层次结构成为隐层的。 因此,该视图及其所有子视图(包括子视图的子视图)将成为层支持的。 此属性的默认值为false。 https://developer.apple.com/documentation/appkit/nsview/1483695-wantslayer 就是这样,这就是我们为NSView设置背景色的方式。 我的目标是分享更多的琐碎和非琐碎的任务,力求使它简短而有趣。