Tag: xcode

如何保持您的iOS本地化文件整洁-Swift脚本版本

与bash脚本类似,我们首先通过create()从根目录中递归搜索本地化的字符串文件。 Apple的FileManager通过枚举对象使文件搜索变得容易。 注意,由于我们通常将打包在本地化文件中的Pod本地化文件打包,因此我们将忽略它们。在parse(_ path: String)方法中的本地化文件并存储时,我们将在此处搜索键重复来优化脚本。 Set的键。 该方法将为所有重复的密钥以及找到的文件路径打印error 。 ( 注意:任何 print(“error:”) 或 print(“warning:”) 格式都会通知Xcode在工具栏上显示相应的消息以及其他构建失败和警告 ) 接下来,我们将验证validateMatchKeys方法中所有可本地化的字符串文件中的键是否匹配。 我们将使用symmetricDifference编织出任何与基本文件都不匹配的额外键。 如果任何可本地化的文件不包含相同的键,则此方法将引发错误并中止脚本。 这使您有机会在下一次执行cleanWrite()之前清理可本地化的文件,它会使用已排序的键并删除多余的空格和换行符来重写可本地化的文件。 下一步是搜索代码库,存储这些文件中使用的密钥,并根据我们的基本密钥进行验证。 有了一点正则表达式,我们就可以成功找到密钥并将它们和文件的路径存储在LocalizationCodeFile结构中,同时还可以通过紧凑地映射出没有密钥的任何文件来优化脚本。 一旦有了我们的结构,我们将点击validateMissingKeys() -将遍历我们的LocalizationCodeFile集合,并减去基本键的每组键。 此结果中的任何其他键都不是我们基本键的子集,因此会给我们丢失的键。 如果找到任何丢失的键,则会引发错误。 我们的最后一个策略是搜索任何死键,这些死键是在可本地化文件中定义但未在我们的代码库中使用的键。 我们可以通过从flatization从LocalizationCodeFile集合中收集的所有键减去基本键来检索死键。 此处找到的所有键均显示为警告,因为此步骤更多是建议清除技术债务,而不是影响问题的用户。 对具有600多个可执行文件和估计800多个密钥的企业代码库执行bash脚本平均要花费81秒 。 在相同的代码库上运行此swift脚本平均要花3秒 ! 🚀🙌 保持干净 ,可读的代码库应该是每个工程师的目标。 通过将此Swift脚本注入到您的后期构建中,清理和维护可本地化的文件应有助于实现该目标并感到自动化。 您可以阅读我以前的博客,以了解如何将脚本注入到Xcode构建后编译中( https://buildingvts.com/clean-ios-localizable-files-8b910413b985 )。 我还在其中包括了一个包含整个脚本的GitHub项目以及此处的示例项目:https://github.com/ginowu7/CleanSwiftLocalizableExample。 随时发表任何意见或建议,您可以在Twitter @ ginowu07上关注我! 编码愉快! 🙏

Cara integrasi React Native Dengan Swift Dan CodePush(Panduan lengkap)-包。 2

Seteleh lama gak nulis di beberapa minggu terakhir karena aktivitas yang padat😌,akhirnya kali ini gua sempetin lanjutan dari artikel sebelumnya。 Ini bakalan singkat dan ga bertele-tele,cukup singkat karna sisanya cuma cara积分密码推送文件Swift kita。 安装Codepush Kita Pakai react-native-code-push yarn add react-native-code-push 喀麦店林克项目计划,印度塞拉利昂共和国 react-native link react-native-code-push Perintah tersebut akan menambahkan文件文件yang dibutuhkan secara otomatis。 dani untuk memastikan lagi,bisa kita […]

深入了解Swiftify

复杂转换 正如我们前面提到的,Swiftify执行的转换不是对Objective-C语法的愚蠢搜索和替换操作,而是该工具更像是一个编译器,该编译器具有: 一次扫描一个字符。 通过标记扫描的字符,对代码执行词法分析 。 然后执行语法分析以确保从词法分析中产生的标记顺序正确。 可以产生期望结果的一组关键字的正确顺序称为语法。 然后, 语义分析会生成一种中间语言或结构,以便可以将其转换为等效的Swift。 这个复杂的过程为Swiftify提供了令人印象深刻的优势,即数据类型感知能力。 例如: 转换为: 如果Swiftify不知道i’的数据类型,并且将加法转换为仅var g = i + f ,它将产生一个编译器错误,表明Binary operator ‘+’ cannot be applied to operands of type ‘Int’ and ‘Float’ ; 您可以在此处探索免费的在线代码转换器。 仅此一项就可以向您展示该工具的真正智能程度。 再以下面的代码段为例,该代码段将持久性存储添加到NSPersistentStoreCoordinator中: 转换为: 在这里,您可以看到Swiftify能够try包装该调用,因为此函数throws ,并且,此外,它还可以推断persistentStoreCoordinator是一个可选属性,并为该属性添加了可选的展开功能 ! 您还可以在这里找到许多其他这样的示例。 包起来 我希望这可以帮助您了解为什么我将Swiftify用于所有转换。 从Xcode扩展到离线转换器,Swiftify可以帮助您! 使用Swiftify,您还可以: 生成Swift文档。 增加您的图书馆的用户群。 迁移您的旧代码。 如有任何疑问,请随时在下面的评论部分中提问。

苹果收购BuddyBuild。 哦,我的Xcode服务器!

最初发布于XCBlog。 在这里阅读 我没想到这将是我2018年的第一篇博客文章。在假期里,我读了“ Apple Buys BuddyBuild”的推文,使我大为震惊,我眨了眨眼,再次阅读了这条推文。 我迅速检查了BuddyBuild的Twitter句柄,没有任何鸣叫,在Google上进行了搜索,发现Tech Crunch,CNBC和BuddyBuild博客确认了此消息。 考虑到我在iOS DevOps和CI / CD上所做的工作,对于我来说,这个消息无疑是令人振奋的消息。 我拿起电话并在Twitter上向丹尼斯表示祝贺。 不久之后,我亲自认识了BuddyBuild团队,并把一包T恤交付给我,以参加我在iOS CI Olympics 2017上的工作。 2017年10月的聚会。 我在运行iOS CI Olympics 2017时与BuddyBuild联系。我对iOS持续集成和持续交付充满热情,我用20种不同的标准对基于云的iOS 5前5名服务进行了Olympics,BuddyBuild成为了赢家。 您可以在此处阅读系列博客文章 介绍性博客文章中提到了iOS CI奥运会的目的和规则。 玩家表现之一:BuddyBuild 玩家表现二:Bitrise 玩家表现三:TravisCI 玩家表现四:Nevercode 玩家表现五:CircleCI iOS CI奥运会获胜者公告 最终的奖牌如下所示: BB = BuddyBuild BR = Bitrise TC = TravisCI NC = NeverCode CC = CircleCI 在评估过程中,我得到了BuddyBuild团队的大力支持,以了解BuddyBuild的关键概念和工作方式。 随着BuddyBuild成为获胜者,他们将奥运会的结果发布在BuddyBuild博客上iOS持续集成与部署比较 BuddyBuild给我寄了一些T恤,我把它们分发给Yoox Net-A-Porter的同事。 尽管我非常喜欢BuddyBuild,但由于我们使用TravisCI,所以我从未尝试将其用于正在处理的项目,并且我已经建立了完全自动化的端到端管道,以使用Fastlane将iOS应用程序直接部署到iTunes Connect。 […]

我爱Swift,我讨厌使用Swift

最近,我被问了很多以下问题:“为什么还要使用Objective-C?” 或“为什么不使用Swift?” 在Slack频道,Twitter,Podcasts上,所以我决定在我的Medium帐户上开设一个更详尽的答案,说明为什么我仍在使用Objective-C。 免责声明:我不是在这里说什么是对还是错,应该做什么和不应该做什么,我只是在阐述为什么Swift不适用于我 。 简介 最近,我们迎来了iPhone SDK诞生10周年的纪念日,这实际上使我意识到我已经使用iOS已有10年了。 在发布SDK的那一刻,我下载了它并开始使用Xcode,发布了一些应用程序,并在一两年后获得了我的iOS开发人员正式职位。 这就是说我对Objective-C感到很自在,而且当新技术问世时我也大肆宣传,并面临这样做的后果,这使我在开始使用新技术之前至少思考了3倍。科技火车。 迅捷的自己 首先要考虑的是Swift本身,它是一种语言。 好不好吗? 比Objective-C好还是坏? 这些都是复杂的问题,由于涉及很多个人喜好,因此很难客观地回答。 我喜欢它,我认为语法是好的,它用途广泛,并且易于阅读(这通常对开发人员本身造成的负担比对语言的负担更大)。 总的来说,我认为这是一种不错的语言,我真的很想更频繁地使用它,这是我将开始列出不这样做的原因的部分。 可怕的更新 这变得越来越不成问题了,但是Swift是一种新语言(2014年),与它初次出现的Objective-C相比,更新自然会很快(而且非常生气),并且会出现重大变化,新语法等,因此非常迅速。 1984年。每年,Swift更新都会破坏以前的代码,有时需要大量工作,有时需要简单的快速修复,但几乎像我的消遣方式一样,阅读有关Slack / Twitter的评论,人们对其项目未编译感到焦虑/紧张。使用某些库已更新到最新的Swift版本的库,而另一些则没有,必须管理所有这些库。 在Objective-C世界中不存在的问题。 几周前,我在Mac(iOS 4/5)上发现了一些非常老的项目,为了娱乐,我决定打开并尝试运行。 令我惊讶的是,一切正常。 讨厌的纹理和UI不能很好地老化,但是可以正常运行。 当然,获得一个有6年历史的项目并运行它不是一个非常常见的用例,但是,另一方面,我最近帮助了一位继承了Swift项目的朋友,除了项目本身,该项目在大约2年内没有更新。如果不进行编译,则所有依赖项也都已过时,其中一些依赖项从未见过新的Swift版本支持。 但是正如我之前写的那样,Swift越来越稳定,并且很快将不再是问题,但是直到今天,我仍然看到Slack上的人们由于Swift版本的迁移而遇到了问题。 尽管如此,如果这是我考虑在新项目中使用Swift的唯一问题,不幸的是,并非如此。 迅捷工具包 这就是我为什么不使用Swift的最大原因所在。 当我说“工具包”时,我指的是与Swift一起使用的所有东西,以拥有一个不错的开发环境:Xcode,LLDB,LLVM,Instruments等。 Xcode对Swift的支持几乎是可笑的,语法突出显示不起作用,编译时间非常长,缺少Swift重构,最重要的是,LLDB根本不起作用。 LLDB是我工作流程的重要组成部分,不仅用于调试,而且还用于实际编写代码,自动化流程,编写日志等。我写了一篇关于葡萄牙语使用LLDB的事情的帖子(葡萄牙语),但它们并没有在Swift中无法使用。 使用Objective-C,我可以使用调试器命令执行很多断点操作,有时我会使用LLDB表达式编写整个方法,然后对结果感到满意时,甚至对某些我喜欢使用的日志,都会对实际代码进行转录LLDB +断点操作,而不是NSLog。 现在您可能正在考虑“但是您可以在Swift中做所有事情”,我说“您不能”,这不是因为该功能不存在,不是因为LLDB在Swift中不存在,而是因为它们是超级越野车 。 一个简单的po命令几乎立即在Objective-C项目上运行,在Swift上,它最多可能需要4秒钟才能返回(在最大容量的2015 MacBook Pro上),而当它很幸运时,它就会变慢,因为更多通常,调试器连接只会丢失,而我知道解决此问题的唯一方法是重新启动Xcode 和模拟器。 我相信,这通常是许多对Xcode的抱怨的源头,我看到人们抱怨Xcode有错误,这种方法不起作用,我只是不能与此相关,而不是在我使用Objective-C时。 去斯威夫特还是不去斯威夫特? 总之,我认为Swift是一种很棒的语言,我可以在macGist这样的业余项目中自己使用它,这是一个很棒的示例,如果您想看到一个不熟悉Swift的人开发的Swift项目以及一个AppKit项目一个不了解AppKit的人,但是每次我打开一个Swift项目时,都要花几分钟的时间,直到我想念Objective-C世界。 不是因为语言,不是因为我的语言效率更高,而是因为该工具包可以正常工作。 有些人可能会发现过去,为了利用Swift的出色优势和性感的语法,我做不到。 我提到的所有这些问题,语言更新和工具包都不是Objective-C的问题,这对我来说很难证明更改的合理性。 我真的希望今年可以为Swift改进和优化新的开发工具,希望我可以使用Xcode而不会使代码完成或语法突出显示崩溃,我可以在LLDB上运行表达式而不必等待音高下降的等效时间。 在那之前,我将对所有我认为“关键任务”的东西都使用Objective-C。 我真的很喜欢Swift作为一种语言,但是Swift作为开发解决方案仍然不是我的节奏。

Swift入侵:专案1

欢迎回到我的Swift开发日记的另一个条目。 如果您关注我以前的记录,您可能已经注意到我不再关注每日报告。 这既是因为不可能一次完成多个任务,而是因为我认为这种内容毫无意义。 然后,我决定切换到“里程碑”模型-也就是说,每当我完成一个项目或取得一些突破时,我都会在这里报告。 如前所述,我正在学习Paul Hudson的Hacking with Swift系列文章,今天,我完成了第一个名为Storm Viewer的项目。 来自带有Swift的App Development课程的非常顺畅和渐进的路径,这令人震惊,因为同时展示了多少功能。 与做事相比,理解似乎排在第二位! 作为古典音乐家,我完全同意! 我在镜子前度过了几个小时,练习打开的琴弦,改变位置等等,而不必了解正在发生的事情。 我的老师曾经说过: «重复并重复一次,直到发现一些东西! » 。 现在我坐在完成的项目前面,感觉是成就的一种,也是困惑的一种。 根据我在最初的几个月的代码学习中了解到的,似乎需要多次遍历该项目的文件,以便一步一步地解决问题。 这当然很合理,但我感到有些迷茫,无法追溯自己的脚步。 因此,我将在此处概述项目建设的进展情况,以便对我进行回顾,并为您提供可能有趣的阅读材料。 通常在这些“简单”项目中会发生这种情况,默认模板是iOS的Single View App 。 解决了Xcode中的初始步骤和Simulator的选择之后,就可以将一些图片导入项目了。 我曾经通过asset.xcassets目录来执行此操作,但是显然这将在以后的课程中进行介绍。 到目前为止,我只是将整个文件夹拖到Xcode项目中,注意选择“如果需要复制项目”复选框,并选择“创建组”而不是“创建文件夹引用” 。 到目前为止,这对我来说还很模糊,但我决定继续。 那里的图像本身几乎没有任何作用,因此是时候了解ViewController.swift文件了。 它包含ViewController类以及其内部的viewDidLoad()和didReceiveMemoryWarning()方法。 在viewDidLoad()内部,我们需要添加一些代码以使应用能够获取图像,使用hasPrefix(:)方法对其进行过滤,然后迭代结果,将其添加到由这些图像名称组成的字符串数组中。 在viewDidLoad()方法中编写一些步骤,然后返回并在其上面编写数组,这有点奇怪,但这似乎是正确的做法。 因此,此设置的第一部分看起来像这样(我已隐藏了以后将添加的部分)。 现在,我们需要使自己熟悉Interface Builder , Auto Layout等。 默认场景被删除,我们代替它绘制了TableViewController 。 当然,仅将其拖动并不会带来很多好处。 需要一些额外的步骤: 告诉Xcode这个新场景将由ViewController.swift文件控制(这是通过将声音更改为Identity Inspector的Class下拉菜单来完成的)。 更改入口优先级(我们希望此View Controller成为应用程序启动时第一个出现)。 在TableView中更改单元格的标识符(以便我们以后可以重新使用它以连接一些代码)+将Style选项更改为Basic。 将整个表视图控制器嵌入到导航控制器中。 默认情况下,TableViewController具有0(零)行,因此我们需要通过实现一些方法( tableView函数的所有子级)来更改该行: numberOfRowsInSection告诉Xcode我们将要显示多少行(该行等于图像数组的.count属性)-区段的数量为1使我们现在跳过该区段。 当我们滚动浏览可能无限数量的行时, […]

为iOS应用程序打造反光工厂– Vincent Pradeilles –中

非常感谢 BenoîtCaron 引起了我的注意,并提出了我将在下面描述的技术的相当一部分。 iOS应用程序是复杂的软件。 如今,不太可能运行到聚合了一百多个视图控制器的应用程序中。 当您考虑到其中的某些可能只能通过特定的业务场景访问的事实时,通常会遇到这样的情况:在屏幕上显示特定的控制器非常困难。 这种情况可能会威胁到应用程序的质量,尤其是在要求开发人员检查每个屏幕(例如,确保它们在iPhone X上能正常工作)的时候。 一个非常方便的工具是调试视图,从中可以实例化任何控制器并将其显示在屏幕上。 那么我们如何实现这样的工具呢? 一个好的起点 第一步是弄清楚如何实例化任意控制器。 幸运的是,这将成为简单的部分,因为该功能已经通过Foundation的public func NSClassFromString(_ aClassName: String) -> Swift.AnyClass? 基本上,再加上一些代码,开发人员可以从其类的名称实例化一个对象。 所以现在我们只需要在我们的应用程序中列出所有视图控制器。 如果没有其他选择,我们可以将它们手动存储在.plist文件中,但是这种方法的缺点是每次创建,删除或重命名类时都需要手动更新,这很繁琐且极易出错。 利用Objective-C运行时 您可能没有意识到这一点,但是每个iOS应用程序都在轻量级运行时环境上运行。 关于此运行时,可以说很多话,如果您想详细了解它,请随时查看Apple提供的文档。 就本文而言,我将解释限于以下事实:iOS应用程序启动时,其所有与Objective-C兼容的类都在运行时加载,并且只要应用程序处于活动状态,它们就会一直存储在该位置。使此运行时成为从中检索所有视图控制器列表的绝佳来源。 我们如何在实践中实现这一目标? 首先,我们从导入与运行时交互的API开始: 处理更高级的用例 我们所取得的成就非常好,但是在大多数情况下,使其真正有用仍然很简单。 当您考虑它时,我们能够实例化视图控制器,但是我们无法为它提供任何类型的初始数据。 在一个现实世界的项目中,这个问题很可能会导致交易中断,因为许多视图控制器可能依赖于先前屏幕传递的一些初始数据。 那么我们如何改善呢? 首先,我们需要一种让控制器提供其用例列表并处理其中一个用例的方法。 为此,我们声明一个协议: 结论 自反编程是一个功能强大的工具,使用它的这个特定实例也不例外:只需几行代码,我们就可以组建一个易于包含在现有应用程序中的工厂,并允许其开发人员实例化任何从一个好的调试视图中查看控制器。 当确保旧版应用程序在iPhone X上流畅运行时,无疑会令人欢迎的工具是这样的工具,但是当您想要对该应用程序的一部分进行非回归测试时,它也很方便。令人讨厌的复杂。 如果您想在项目中使用以上代码,请随时在我的GitHub上使用。

iOS UI实施方法如何帮助我们获得简洁的代码。

“当我们使用容器视图时,视图控制器的层次结构” iOS UI实施如何帮助我们获得简洁的代码。 考虑XCode项目中的容器控件,即使没有任何专业知识,也可以帮助您减少代码中的行数。

iOS中的GIF终极指南。

动画内容的另一面。 GIF大约在1980年代后期。 只是在最近,它们才被虚拟吹灭。 从博客到meme网站,您可以在任何地方看到它们。 在图片上使用GIF的原因很多,例如,它们通常不像视频那样沉重,可以恰当地显示您的观点并且可以在任何地方兼容。 如果一张图片可以说一千个单词,请想象一个GIF可以有多少个。 存在对在iOS中播放GIF的本机支持,但乏味。 您需要使用Apple的ImageIO框架加载GIF的每个图像,并自定义theAnimatedImages , animationDuration和animationRepeatCount API。 Flipboard实现了一种在其应用程序内播放GIF的解决方案。 我们将使用他们的图书馆,名为 FLAnimatedImage在我们漂亮的小应用程序中复制相同内容。 按着这些次序: 安装Cocoapods。 如果尚未安装,请按照此处的步骤操作。 创建一个新的Xcode项目。 我将其命名为GIFTest。 FLAnimatedImage有一个cocoapod可用。 如果您不知道什么是Cocoapods或它如何工作,请查看此链接。 3.现在,打开终端。 将目录更改为保存iOS项目的位置。 通过键入pod init初始化我们项目的Cocoapods。 接下来,通过键入open podfile 。 我们将添加吊舱。 添加线pod ‘FLAnimatedImage’ 4.现在,我们将进行pod install以将pod install到我们的项目中。 我们将关闭Xcode的所有会话并打开GIFTest.xcworkspace项目。 那是带有白色图标的Xcode项目。 xcworkspace项目有我们的原始项目,还有一个带有pod的xcode项目。 5.太好了! 完成所有设置后,我们将三个UIImageViews添加到我们的项目中。 我们将其类更改为FLAnimatedView。 6.导入FLAnimatedImageView并为所有三个图像创建出口。 7.现在,我们将在本地加载两个GIF,并从互联网加载一个GIF。 要在本地加载GIF,请将它们移到您的项目中,然后选中“如果需要,复制项目”。 8.现在要在本地加载GIF,请按照以下步骤操作。 因此,只要提供了GIF,就将帧解压缩为位图格式(CPU密集型),并将其填充到缓存中。 编码的位图将一直保留到对象的生存期。 它试图有效地选择缓存大小,即,如果GIF太小,它将帧保留在缓存中,否则,它仅缓冲足够的帧以进行实时回放。 当系统发出内存警告时,所有帧都将丢失,并且过程将退回到按需解码。 因此,今天,我们学习了如何使用Cocoapods,如何在项目中对其进行初始化,安装了Flipboard的开源库FLAnimatedImage并将其用于显示项目内的GIF和来自互联网的GIF。 有关更多参考,请在此处查看库。 有关完整的源代码,请参阅 我的Github存储库。 如有任何问题和建议,请在下面发表评论!

在构建iOS应用程序时优化电池电量

使用精美的应用程式never…耗电量,这是我们永远不喜欢的一件事。 最漂亮的应用程序会迅速释放电话。 就像现在我在构建应用程序一样,我希望它消耗的电池最少,这就是我要确保的方法。 要记住的要点- 由于结果必然会有所不同,请尝试在各种设备上运行和测试。 会有一个饱和点,然后您将无法进一步优化应用程序,但是在达到该点之前,会有很多地方需要优化。 整体性能和消耗将取决于 显示📱 CPU📲 网络📡 位置📍 背景⚙️