Tag: swift

建立具有依赖关系的封闭源Swift框架的食谱

除了ABI兼容性问题外,有时您可能希望分发Swift框架的二进制版本。 该框架应为“胖”框架(同时支持模拟器和iOS设备架构),并且可能依赖于其他第三方框架。 没有为此的Xcode项目模板,但是您会在Internet上找到有用的信息。 基本上可以归结为使用xcodebuild创建框架的两个版本,一个用于模拟器,一个用于真实的iOS设备,然后使用lipo命令将它们组合为一个胖框架。 这似乎很简单,但是在网上找到以下说明(此处,此处和此处的示例)之后,当在应用程序中使用框架的二进制版本时,我们遇到了运行时崩溃。 当我们的框架在以下示例中称为MyFramework尝试使用来自任何第三方框架依赖项的符号时,将发生崩溃。 当MyFramework尝试使用RxSwift的ObservableType时,崩溃看起来像这样: dyld:懒惰的符号绑定失败:找不到符号:__TIFE7RxSwiftPS_14ObservableType9subscribeFT6onNextGSqFwx1ET__7onErrorGSqFPs5Error_T__11onCompletedGSqFT_T__10onDisposedGSqFT_T___PS_10Disposable_A0_ 引用自:/Users/aaron/Library/Developer/CoreSimulator/Devices/335F6B8A-0CBC-406D-9559–5718D4910F5A/data/Containers/Bundle/Application/47AA11E3-C2E5–4FCB-A86C-36092990EF0E/Consumer.app/Frameworks MyFramework.framework / MyFramework 预期位于:/Users/aaron/Library/Developer/CoreSimulator/Devices/335F6B8A-0CBC-406D-9559–5718D4910F5A/data/Containers/Bundle/Application/47AA11E3-C2E5–4FCB-A86C-36092990EF0E/Consumer.app/Frameworks RxSwift.framework / RxSwift 经过大量的调查和试验,我们发现了一个过程,该过程可以生成胖框架,当引用其他第三方框架的符号时,该框架不会崩溃。 这是我无法完全解释问题或原因的原因之一,但我想在这里分享: 创建你的框架 使用Cocoa Touch Framework Xcode模板,随意选择其他框架(Cocoapods,Carthage,拖放)等。 创建目标以构建胖框架 在“跨平台”部分中使用“聚合”目标类型。 这创建了一个最小目标,我们可以向其中添加一个运行脚本构建阶段。 我将这个目标BuildFatFramework 。 将胖框架构建外壳脚本添加到目标 将运行脚本构建阶段添加到BuildFatFramework目标,然后向其中添加以下shell脚本: #1 #设置bash脚本在任何命令失败时立即退出。 设置-e #2 #设置一些常量供以后使用。 FRAMEWORK_NAME =“ MyFramework” OUTPUT_DIR =“ $ {SRCROOT} / build” #3 #如果存在先前版本的残余,请将其删除。 如果[-d“ $ {OUTPUT_DIR}”]; 然后 rm -rf“ $ {OUTPUT_DIR}” 科幻 […]

改善Xcode工作流程的提示

Xcode是创建iOS应用的绝佳工具,但有时可能会有些笨拙,并会拖慢您的工作流程。 这里有一些技巧可以改善您的工作流程,希望可以节省您的时间和麻烦。 1.跟踪构建时间 构建时间是Xcode最糟糕的事情。 要改善任何东西,您首先需要某种衡量它的方法。 要以秒为单位在Xcode中测量构建时间,请打开终端并输入以下命令: defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES 之后,您可能需要重新启动Xcode才能看到更改。 您应该看到每次构建后,构建时间就会显示在顶部工具栏中。 现在您知道构建时间有多长,请按照本文进行操作以减少构建时间。 2.跟踪应用启动时间 应用启动速度是创建应用时最重要的因素之一。 用户希望应用程序立即启动。 寻找缓慢发射的来源可能很困难。 除了使用事件探查器(我打算很快写另一篇文章)之外,很难评估应用程序的启动时间以及改进的位置。 一种可以通过在调用applicationDidFinishLaunching之前跟踪所有内容来缩短启动时间的方法。 这是应用程序初始化库,设置ObjC和加载dylib的时候。 使用此方法,Xcode将打印加载时间,并且在每次运行应用程序时,导致加载速度变慢。 打开产品>方案>编辑方案,然后在运行操作下添加以下环境变量DYLD_PRINT_STATISTICS并将其值设置为1 。 现在,在每次构建之后,您应该会看到如下所示的打印输出: 要了解有关如何使用此信息的更多信息,请参阅Use Your Loaf的Slow Startup Times文章。 3.快速重命名 寻找替换变量来重命名总是很麻烦。 不再。 在单击要重命名的变量或函数的同时,按住CMD 。 然后从弹出窗口中选择重命名。 它会在项目中甚至在情节提要中找到并重命名每个副本。 编辑:根据BłażejWdowikowski和James Pamplona的建议,您可以使用键盘快捷键cmd + ctrl + e快速重命名相同范围内的内容。 与上述内容不同,但仍然有用。 4.使用断点 我知道似乎只使用print语句似乎更容易,但是在许多情况下,仅使用断点就容易得多,并且可以节省您的时间。 要设置断点,请在要停止的代码一侧按行号,然后运行项目。 代码在该行上暂停执行后,您只需将鼠标悬停在它们上方,即可查看所有周围的变量值。 或者,您可以使用lldb通过print object命令在控制台中打印它们,例如po yourVariable 。 断点可能看起来更复杂,但是一旦您了解了一些lldb命令和其他Xcode调试器工具,它实际上为您节省了很多时间,因为您可以在断点处停止,而不必完全重新运行应用程序。 一旦完成对值的评估,就可以按恢复按钮并禁用断点以防止其再次停止执行。 […]

使用Swift对Info.plist文件进行强类型访问

作为Apple的开发人员,随着Swift的出现,我们开始在代码中面临类型安全约束。 从我的角度来看,我一直试图完全采用这种方法,即使这通常意味着要处理UIKit的多个部分,这些部分显然是根据不同的(更动态的)范式创建的。 有时候很容易,有些则更少,但是他们仍然是一个很好的练习,可以跳出框框思考,以使我们的代码更安全,更干净。 最近,我重新面对了一个表面上琐碎的任务。 我将读取应用程序的Info.plist文件中保存的应用程序的配置。 我的Info.plist包含一个名为configuration的附加节点,其中包含多个数据: server_url , environment_name和其他一系列键。 值是动态的,并根据您为启动应用程序而设置的当前模式分配(即$(SERVER_URL)是具有值或取决于配置环境(如TESTING/PRODUCTION )的值的url服务器)。 目的是通过保留数据类型来获取这些值。 最直接的方法是使用Codable协议背后的Codable (本文与Codable ,您可以在此处,此处或此处找到大量文章。 代码非常简单,您只需指定一个Codable结构即可处理您感兴趣的数据,然后为该Plist类分配泛型类型。 在我们的示例数据中,我们可以提供以下结构: 然后: 您可以使用该类本身来读取Info.plist以外的所有其他文件; 只需传递.plist(“otherPListFile”)作为init参数并提供您自己的Codable结构即可。

消息以关闭迅速传递。

大家好,希望大家一切都好。 今天,我将向您展示如何使用闭包进行消息传递。 基本上,我将向您展示如何通过Protocols实现执行自定义行为的替代方法。 我不知道您对闭包有多熟悉,下次我将尝试使用闭包。 现在,对闭包不太熟悉的人可以将其作为更简单的方法或将消息传递作为黑手。 我将尝试使用带有自定义单元格的表格视图示例进行说明。 您可以在下方看到我们要实现的目标。 该视图控制器具有一个表视图,该表视图具有一些名称以及它们前面的一个按钮。 表格视图下方也有一个空白区域。 每次按下按钮,我们都会在此区域执行一项活动。 如您在下面看到的,我们在单击按钮时对名称进行了动画处理。 通常,我们在委托和协议的帮助下执行此操作。 为此,我们必须使用按钮操作方法定义协议。 这样,无需创建自定义协议和委托。 我们需要一个类型为闭包的变量。 你们都在想我在说什么😅。 是的,我们需要一个在其中包含闭包的变量。 见下文 这个名为buttonAction的变量将持有一个不带参数的闭包,并返回void。 我们将其作为可选变量,这样,如果任何一个单元格都没有动作,我们也将能够处理这种情况。 与往常一样,我们将在自定义单元格中为按钮创建IBAction 。 见下文 在表视图的类中,我们将闭包分配给每个单元格的闭包类型对象。 见下文 现在我们已经准备就绪,可以执行了。 但是在此之前,让我解释一下我们实际上在做什么。 在这里,我们正在做一个非常简单的活动来完成我们的任务。 我们正在定义一个变量,它将像通常定义的那样保留一个闭包 。 UILable,UIImage等 我们将为tableView_cellFOrRowAt_IndexPath中的每个单元格在此变量中传递一个可执行的闭包 。 同样,我们设置textLabel和detailTextLabel值。 在单元格类中,我们将发现buttonAction是否分配了闭包。 如果它有一个闭包,那么我们只需要执行那个。 我们已经做到了。 伙计们,这是我在关闭时传递的消息。 就像我一直说的那样,我还在学习,我相信学习与分享 。 您也可以从此链接下载演示项目 。 希望对您有所帮助。 我随时欢迎您提出建议,请至少放下其中一个。 非常感谢。

iOS- Swift 4.2 —使用键盘工具栏的箭头按钮,按顺序导航到文本字段。

iOS- Swift 4.2 —使用键盘工具栏的箭头按钮,按顺序导航到文本字段。 下面的TextFieldNavigation类将使用键盘箭头处理文本字段的移动。 2)使用带有六个文本字段的scrollView设计一个视图控制器。 3)在ViewController类中,我们将文本字段链接到TextFieldNavigation类(我们将所有文本字段按顺序存储在数组中,并将其传递给具有数组的TextFieldNavigation类) textFieldNavigator?.textFields = [firstTextfield,secondTextField,thirdTextfield,fourthTextfield,thirdTextfield,thirdTextField] GitHub链接:https://github.com/yugandh/TextFieldNavigationFromKeyboard 结论: 这是帮助您在ViewController中使用多个文本字段的项目中的一种简便方法。

在Swift中避免回调地狱

能够从事最多样化的项目,这使我有机会与几种类型的开发人员和代码库联系。 除了它们的核心差异外,在此过程中对我而言突出的是,成熟度较低的项目将始终面临类似的问题。 也许他们选择了错误的体系结构,或者缺少单元测试导致一个讨厌的bug潜入了生产环境,但是有一个特定的问题总是引起我的注意-回调地狱。 如果不从一开始就进行处理,当在其他回调或条件中链接回调时,这些可怕的花括号金字塔就会使困扰着代码库的问题陷入千篇一律的不可能的代码审阅和遥远的“此方法到底在干什么?”的尖叫。 ”。 私有函数requestNetwork (请求:T,完成时间:(结果->无效)?){ 如果isUserLogged { 做{ 让urlRequest =试试request.toRequest() session.dataTask(with:urlRequest){(数据,响应,错误)在 如果让httpResponse = response为? HTTPURLResponse { 如果acceptedStatuses?.contains(httpResponse.statusCode)!= true { 如果让apiError = errorParser?.possibleError(from:data){ 完成(.failure(错误)) 返回 } } } preprocess(data){(processedData,error)在 如果让错误=错误{ 完成(.failure(错误)) } 如果让加工数据=处理数据{ 做{ 让结果=尝试request.serialize(processedData) 完成(。成功(结果)) } { 完成(.failure(错误)) } }其他{ 完成(.failure(HTTPError.unknown)) } } } } { 完成(.failure(错误)) } }其他{ 完成(.failure(HTTPError.loggedOut)) } } 它们难以阅读,几乎无法审查,但不幸的是,它们非常容易编写,巩固了其作为初级开发人员的祸根的地位。 […]

适用于iOS的My Development Toolset 2019🛠

更新:2018年11月26日 大家好,我想在2019年更新一些我用于iOS开发工具,开源应用程序,网站,存储库,库的工具集,以及我目前仍在使用的其他工具。 本文将全年不断更新。 您可以找到我的2017年工具集到2018年的一些更新以及一些新建议以及其背后的原因。 从我的2019列表中删除了一些工具。 原因是,我不再继续使用此工具Gitscout , Bee , GitKraken , 完美无瑕 。 我在下面对其中一些发表一些评论。 工具类 有一个新的第一名。 它的名字叫夏洛克 。 我们可以实时编辑视图和布局约束,模拟在其他设备上的运行。 他们是RevealApp的完美团队。 FASTLANE我强烈建议您进行扫描,比赛和健身功能。 上周,我发现了一个很棒的工具,可以实时跟踪您的请求请求并列出所有受监视的存储库。 还有iOS和Android版本。 这个程序值得五颗星。 预告片 ModMove ,您可以使用键盘快捷键和鼠标轻松移动/调整窗口大小。 这对于HyperSwitch确实是我的最爱。 Injection ,将Swift / Objective-C代码动态插入正在运行的应用程序中。 它不会对您的项目进行任何更改。 您也可以与AppCode一起使用。 Cacher是专业开发人员的代码片段组织者。 您可以管理要点摘要。 NightOwl Mojave之后,我们在macOS上遇到了DarkMode。 NightOwl进一步扩展了此功能。 您可以自动配置日出/日落,安排个人配置,并可以轻松更改所有配置。 普利姆 是一个了不起的演示工具。 它总是更新的,对于Sprint演示会议非常有帮助。 您可以隐藏桌面项目,禁用通知,使扬声器静音。 救援时间 是跟踪您如何在开发中花费时间或正在使用哪些工具的理想工具。 我推荐了GitKraken 在2017年用于GIT。我有很好的理由,例如GitFlow 可以由GitKraken自动添加。 另外,他们有gitlab支持。 GitKraken走了很长一段路。 但是当启动一个大型项目(例如15分钟的编译时间)并且该项目中总共有142802个代码时, SourceTree自2017年11月以来就是我新喜欢的GIT GUI。 KeepingYouAwake是适用于macOS的小型菜单栏实用程序,可以阻止Mac在预定义的持续时间内或激活后进入睡眠模式。 […]

VIPER 101

Merhaba,buyazıda的她的iOS平台mimilan olan VIPER mimarisini dilimdöndüğünceanlatmayaçalışacağım。 Yazınınhedef kitlesişuşekildedir; OrtamlardaVIPER’ıduymuşama neişeyarar tam emin olamayan,VIPER ile ufak tefek 1-2 projeyapmışamamantığınıtam olarakanlayamamışve yaanladığınıpekiştirmekisteyenkişiler。 Geliştirdiğimiz她的奶奶belirli bir mimariüzerinekurarız。 Seçeceğimizmimarinin kolay entegre edilebilir ve ek ek tigeltitieleelere uyumluolmasınıisteriz。 Aynızamanda kodumuzun okmasbilisolmasınıvearkadaşlarımızagösterdiğimizdehavalıbulmalarınıbekleriz。 Kısacabizyazılımcılarbi mimaridençokşeybekleriz。 在iOS电脑上,您可以下载mimari MVC’dir。 苹果酒,苹果酒,MVC,苹果酒,冰激凌。 ViewController’ınaşırışişmesibuna enbüyükörnektir。

Advanced iOS Developer(Swift)的最佳资源

以我的拙见,当然(更新10.12.2017) 很长一段时间以来,我的浏览器中都有一个文件夹,其中包含有关iOS开发和Swift的文章和视频,这对我阅读和重新阅读很有帮助。 我很确定大多数开发人员都有自己的具有最佳功能的库。 所以我决定分享我的信息Information 更新 12月10日:添加了调试部分 良好的iOS应用程序体系结构:MVVM与MVC与VIPER MVVM,MVC,VIPER…这么多缩写,哪种架构是最好的? 让我们来谈一谈永远重要的事情…… 学术领域 驯服极大的复杂性:MVVM,协调器和RxSwift 去年,我们的团队开始在生产应用程序中使用协调器和MVVM。 起初看起来很吓人,但是从那以后我们…… blog.uptech.team 汗楼| 协调员Redux 应用程序委托是任何应用程序的入口点。 它的主要职责是往返于……之间传递消息。 khanlou.com iOS架构模式 揭秘MVC,MVP,MVVM和VIPER medium.com MVVM简介·objc.io objc.io出版有关iOS和OS X开发的高级技术和实践的书籍 www.objc.io 汗楼| 8种模式可帮助您摧毁Massive View Controller 视图控制器之所以变得庞大,是因为它们做了太多的事情。 键盘管理,用户输入,数据… khanlou.com 依赖注入,iOS和您 脆弱的对象图之所以不好,是因为您无法轻松替换应用程序的各个部分。 如果是物体… www.bignerdranch.com 适用于Swift的SOLID原理– Marco Santa Dev 可维护的组件。 可重用。 只是个梦? 也许不吧。 SOLID原则可能就是这样。 SOLID是首字母缩写词… marcosantadev.com 依赖注入·objc.io objc.io出版有关iOS和OS X开发的高级技术和实践的书籍 www.objc.io 使用VIPER构建iOS应用程序·objc.io objc.io出版有关iOS和OS X开发的高级技术和实践的书籍 […]

ABI稳定性:Swift 5.0中的功能

Apple Swift 5将于2019年初发布。这是Swift的下一个主要版本。 目前,Swift的首要任务之一是在未来的Swift版本之间实现兼容性。 其中一个主要组件是ABI稳定性,它使应用程序和使用不同版本的Swift编译的库之间具有二进制兼容性。 Swift 5为应用程序提供了二进制兼容性:保证以后,使用一个版本的Swift编译器构建的应用程序将能够与使用另一版本的编译器进行通信。 ABI稳定性 应用程序二进制接口(ABI)是程序调用函数并使用其他编译程序中的数据结构的一种方式。 它是应用程序编程接口(API)的编译版本 。 对于使用外部库的应用程序,ABI非常重要。 如果程序是为使用特定库而构建的,而该库后来又进行了更新,则您不必重新编译该应用程序。 如果更新的库使用相同的ABI,则无需更改程序。 具有相同ABI的两个库版本称为“二进制兼容”,因为它们具有相同的低级接口。 ABI稳定性意味着将ABI锁定到某种程度,以便将来的编译器版本可以生成符合稳定ABI的二进制文件。 Swift的当前版本不稳定,因此每个二进制文件(App)都捆绑了自己的Swift动态库版本。 例如,如果App1使用的是Swift 3.0 ,则它将内部的Swift 3.0动态库 (包含3.0 ABI )捆绑在一起。 如果App2使用的是Swift 3.2 ,它将捆绑Swift 3.2和3.2 ABI 。 在这里,Swift并不存在于iOS操作系统中,而是存在于每个App中。 Swift 5.0中的ABI将使将来的编译器版本能够生成符合稳定ABI的二进制文件。 如果Swift成为ABI Stable,则Swift将被嵌入到iOS操作系统中,并且其ABI将与每个Swift版本兼容。 例如,如果App1使用Swift 5.0 ,但是App2使用Swift 5.3 ,则两者都将使用嵌入在操作系统中的Swift ABI。 在此示例中,使用Swift 5.0构建的应用程序将在安装了Swift 5标准库的系统以及假定的Swift 5.1或Swift 6的系统上运行。 为什么ABI稳定性很重要? 捆绑包大小将减小:您不再需要在Frameworks文件夹中包括Swift标准库。 更少的移植工作:较新的编译器可以编译用较早版本的Swift编写的代码。 这旨在减轻开发人员面临的迁移痛苦。 二进制框架和运行时兼容性:由于无需嵌入Swift,开发人员可以在Swift中创建预编译框架(当前,在编译应用程序时会编译框架)。