作为移动开发人员,我们的使命是为最终用户提供最佳的用户体验,通过专用的应用程序使他们的生活更有趣,更轻松。 任务之一是确保用户看到的用户界面外观良好且正确。 大多数时候,我们可以说应用程序是数据的美化手段。 我们通常从后端获取JSON数据,将其解析为模型,然后使用UIView (主要是UITableView或UICollectionView 。 对于iOS,我们需要根据设计不断调整用户界面,使其适合小型手持设备。 该过程涉及我们更改代码,编译,等待,检查,然后更改代码等等。…诸如Flawless App之类的工具有助于轻松比较iOS应用程序和Sketch设计的结果。 但是真正的麻烦在于编译部分,这花费了很多时间,而对于Swift来说更糟。 它使我们进行快速迭代的效率降低。 看起来编译器在假装编译时正在秘密开采比特币mining 如果您使用React,您将知道它只是状态UI = f(state). UI表示UI = f(state). 您将获得一些数据,并构建一个UI来表示它。 React具有热重载器和Storybook,这使得执行UI迭代非常快。 您进行了一些更改,然后立即看到结果。 您还将获得每种状态所有可能的UI的完整概述。 您知道在iOS中想要相同的东西! 除了在WWDC 2014中引入Swift之外,苹果还引入了Playground,据说这是“探索Swift编程语言的一种新颖的创新方式”。 一开始我并不十分相信,而且我看到很多抱怨Playground运行缓慢或反应迟钝的抱怨。 但是看到Kickstarter iOS应用程序使用Playground加快了样式和开发过程的速度后,我印象深刻。 因此,我开始在某些应用程序中成功使用它。 它不会像React Native或Injection App一样立即重新渲染,但希望多年来会更好。 或至少它取决于开发社区。 Playground的场景是我们一次只能设置一个屏幕或组件的样式。 这迫使我们仔细考虑依赖关系,因此我可以导入一个特定的屏幕并在Playground中对其进行迭代。 Xcode 9允许在Playground中导入自定义框架,只要该框架与Playground在同一工作空间中即可。 我们可以使用Carthage获取自定义框架并进行构建。 但是,如果我们使用CocoaPods,那么它也是可行的。 如果将Playground添加为嵌套项目,则Playground无法访问同一工作空间或父项目中的代码。 为此,您需要创建一个框架并添加要在Playground中使用的源文件。 我们称之为应用程序框架。 本文的演示是一个使用CocoaPods管理依赖项的iOS项目。 在撰写本文时,它是Xcode 9.3和Swift 4.1。 让我们逐步完成使Playground与使用CocoaPods的项目一起使用的步骤。 还有一些好的做法。 步骤1:添加广告连播 我主要使用CocoaPods管理依赖项。 在某些屏幕中,肯定会涉及到一些吊舱。 因此,要使我们的应用程序框架正常工作,它需要与一些吊舱链接。 创建一个新项目,我们称它为UsingPlayground 。 该应用程序显示某种纸屑颗粒🎊。 […]
上周,我们和我的兄弟一起发布了我们在Swift中开发的第一个iOS应用程序。 在本文中,我想分享我对过程的看法。 这是从一个人的角度写的,他花了六年的时间在Ruby和JavaScript中构建各种Web应用程序(在规模和领域方面),而最近三个月一直在Swift中工作。 Objective-C死了吗? Swift是由Apple开发的,Apple是世界上最大的公司之一。 这意味着很多事情; 首先,苹果公司不怕对其平台进行重大更改。 所谓重大变更,也是指破坏代码的更新。 您需要注意这一点。 例如,在上一个WWDC期间,他们宣布重命名了API的较大部分。 Swift本身是对iOS开发人员以前的主要语言(Objective-C)的巨大转变。 顺便说一句,对我来说,WWDC像工作一个星期一样,赶上所有有趣的演讲和公告。 即使这样,Swift还是我见过的维护得最好的开源项目之一。 只需检查存储库及其语言建议即可。 这是否意味着Objective-C已经死了,您不需要知道吗? 的种类。 我敢肯定,您可以在Internet上找到的大多数外部库和代码示例都是用Objective-C编写的。 但是,有趣的是,当我在Swift中做更多的事情时,了解Objective-C代码的问题就会减少。 我几乎可以自然地阅读它。 您需要知道的另一个事实是内部API的大小,它很大,开始浏览时可能会感到害怕。 您基本上可以构建任何东西,并且可以访问所有移动专用功能,例如摄像头,麦克风,地理位置,加速度计,触摸屏等,比在网络上容易得多。 工具集 XCode(Apple IDE)是发生魔术的地方。 它包括在iOS应用程序开发过程中需要的所有工具:代码编辑器,界面生成器,数据库管理器,调试器,检测工具等。 不幸的是,这远非完美。 特别是Interface Builder,它提供了最多的“最新动态” 。 当我开始玩它时,我真的很感动- “哇! 我可以在诸如Sketch或Photoshop之类的图形编辑器中构建整个界面”-这不是事实。 Interface Builder更像是抽象层,用于覆盖编写的代码,而不是用于设计UI的工具。 在Interface Builder中选择一个选项并不少见,但这完全不会影响您的应用程序。 那里有很多您无法猜到的东西,您只需要了解它们即可。 这样的错误约束警告,您可以通过直接单击警告描述来解决。 另外,删除插座或动作时,切记要删除情节提要中的引用。 您在编译过程中不会收到任何警告,但是如果不删除它们,您的应用将崩溃。 您需要找到最佳位置。 根据我的经验,Interface Builder可以方便地设计应用程序流程,放置内置UI元素,并在视图控制器之间(而不是在按钮和视图控制器之间)创建序列。 将所有设置存储在代码中,并使用对现有UI对象的继承来创建自定义UI元素。 当您创建iOS应用程序时,计算机图形编程比Web应用程序要多得多。 我的建议是阅读有关向量之类的基础知识或转换的工作方式。 了解这些主题非常有用,因为您将尽快而不是稍后面对它们。 始终在真实设备上测试您的界面。 单击模拟器并用手指点击真实设备的感觉完全不同。 官方的依赖项管理器尚未发布,但是您可以在两种社区驱动的替代方案之间进行选择:CocoaPods或Carthage。 我正在使用第一个,并且没有遇到太多问题。 最后一个小技巧:不要过多地依赖撤消选项。 当您按cmd + z时,XCode不会在文件之间跳转,因此您无法直观地跟踪更改。 […]
您有没有想到过,您尝试使用标识符,并且编译器对此有所抱怨! 就像是。 是的,当我尝试为新的NetworkEngine编写默认配置时发生了,事实证明,这些是保留的标识符,不能原样使用,但是我们可以使用相同的标识符,但要稍作改动。 喜欢 就是这样,只需使用反引号即可 。 另一个用例是,当您尝试在块内自动展开自我时 。 我希望该提示对您有所帮助,并且如果您有任何对您的旅行有所帮助的新提示,我很想听听他们的意见! 如前所述,我正在编写一个新的NetworkEngine,可以在我即将进行的项目中重用。 它目前处于过早状态,但是您可以在我的项目中使用它,因为我正在积极进行重构并为其添加新功能。 https://github.com/fahadHyder/Swift_NetworkEngine 请在您的快乐时光里检查一下,并分享您的想法,甚至您可以创建PR! 🙂
成为咖喱厨师IRL 这是我在Kayako上构建应用程序时经常遇到的一种情况-我必须初始化一个对象(或对象数组),并且涉及并行(或根据情况而定)运行的多个API调用。 现在,这似乎很简单。 等待直到所有数据准备就绪(存储在全局变量或其他变量中),然后初始化对象。 对? 是的, 是的。 但是如果我不想写怎么办 令x = Obj(a:1,b:2,c:3,依此类推…..) 而不是创建全局变量。 如果..我想要更快的解决方案? 好吧,这是一个解决方案 通过使用currying部分地初始化对象,并在获得更多信息后进行完全初始化,它可以帮助您(很棒的Swift🔶Developer),编写清晰简洁的代码并从长远来看节省时间。 代码 因此,假设您有一个Car Object。 我们将使用一个结构,因为“ Viva la值类型!”且不变性=❤ 摩托车(或自行车)可被视为发动机+轮胎 //:为简便起见。 另外,命名元组是🔥🔥🔥 typealias TirePair =(前:轮胎,后:轮胎) //:愚蠢的媒介不会让我正确缩进我的代码😡 结构引擎{ let horsePower:整数 让做:字符串 } struct Tire { 允许直径:浮动 } 还有我们的自行车课 struct Bike { let engine:引擎 让轮胎:TirePair //:这是唯一需要的功能 静态函数generateBike(引擎:引擎,轮胎:TirePair)->自行车{ 返回自行车(发动机:发动机,轮胎:轮胎) } } 如果您使用thoughtbot的很棒的库Curry之类的东西来咖喱 让curriedInit = curry(Bike.generateBike) 我们可以像这样部分初始化它 […]
介绍 今天又是一天。 另一个美好的一天。 另一个迅速行动的好日子。 但不只是其他任何一天。 今天我们要进入丛林。 准备好一些Swift丛林荒野。 我最近在YouTube上观看了一些随机的动物战斗,因此本文发生在丛林中。 保持光线凉爽。 旅行愉快。 我们将讨论的主题是具有map,filter,reduce以及将这三个元素放在一起的高阶函数。 欢迎使用Wild Edition:Lio The Lion 。 前提条件 强烈建议您在开始学习之前对函数和闭包有扎实的了解。如果您确实在本文中遇到任何困扰,希望这些文章对您来说很有价值。 因此,如果您对这些文章还不确定,请务必查阅其中的任何文章。 Swift 3中的主函数 Swift 3中的闭包简介 故事 饥饿的狮子想要食物。 食物枯竭。 他的物种只剩下3个中的1个。 大地,搞砸了。 饥饿的狮子。 o 廖是他的名字。 廖是饥饿的狮子。 他会吃任何东西。 任何人。 躺在一片绿色的丛林中,看上去更像沙漠。 干无叶。 廖闭上双眼冬眠。 左眼睁开……等待中。 等待杀死。 人类也是如此。 Bon来了。 天啊 你在这里做什么? 廖把目标对准了猎物。 肉 他睁开右眼。 看邦。 茎秆 伸展他的背部。 降低他的立场。 向远处左移,落在Bon的视线之后。 廖动。 向前移动。 仍然低而动。 仍然用狙击手的稳定盯着猎物。 […]
这是这篇文章的第1部分。 在第1部分中,我们使用NSURLSession从Web上获取了JSON并将其存储到本地数组tableArray中 。 让我们开始打开Main.storyboard 。 继续并删除默认的ViewController 。 现在,您应该有一个空白的Main.storyboard 。 在右侧平面上,从对象库中拖放UITableViewController 。 在将UITableViewController连接到代码之前,我们需要使ViewController.swift与UITableViewController保持一致 。 为此,请打开ViewController.swift。 更改此: ViewController类:UIViewController 对此: ViewController类:UITableViewController 现在,通过打开main.Storyboard并单击控制器的外部,将UITableViewController连接到我们的代码。 打开Identity Inspector并将类更改为ViewController 。 现在我们需要确保它是Initial View Controller 。 现在让我们回到ViewController.swift中添加一些内容。 在viewDidLoad中添加以下两行代码: self.tableView.dataSource =自我 self.tableView.delegate =自我 为了保持干净整洁,让我们创建ViewController的扩展 。 把这个放在 类大括号外 。 现在,在“ 属性”检查器中 ,将“ 单元格”作为标识符 。 现在,我们要做的就是在parseJSON()函数中添加self.tableView.reload() 。 现在,您可以使用C ommand + R运行您的项目。 您在控制台中看到该阵列的时间可能要延迟到填充表格所需的时间,或者直到您单击屏幕后才会显示。 这是因为未在主线程上调用self.tableView.reload() 。 您应该始终在主线程上更新UI。 我们可以这样简单地包装重载: DispatchQueue.main.async { […]
Swift被开发人员所喜爱,并且显然是Apple生态系统以及通用编程的未来,因为它已被Apple开源,并且全世界的开发人员都为它做出了积极的贡献。 Swift代码更快,更易读,看起来像脚本语言一样自然有趣。 Objective-C非常强大,大量框架和Apple框架的许多部分都用Objective-C编写。 鉴于Swift现在已经在Swift 5中实现ABI稳定性,因此作为一种语言已经达到了一定程度的稳定性和成熟度,因此通过迁移到Swift来开始将来对我们的代码和框架进行验证始终是一个更好的选择。 SVProgressHUD 是一个非常流行的库,被开发人员广泛使用。 它以其使用简单和简洁的设计而优雅。 Swiftify for Xcode是一个非常强大的工具,可以将整个Objective-C项目转换为Swift。 我用它来转换项目,结果非常好而且很快,但是当我简短地研究了项目代码时,我对代码的结构或功能没有深入的了解。 我意识到最好一次转换一个项目类,测试转换后的类,然后继续重复该过程。 我强烈建议您在自己的代码或经过充分研究并有深入理解的代码上使用Swiftify for Xcode。 如果您要转换不是您自己编写的代码或您不了解的代码,我建议一次迁移一个类,使用现有代码进行测试,然后重复该过程,因为以后将调试整个项目很难。 分而治之总是更好。 我的整体方法可以用图形表示为: 查看SVProgressHUD中的代码结构,我转换文件的顺序如下:- 因此,在将Swiftify用于Xcode之后,我又从头开始,转换的第一个类是SVRadialGradientLayer 。 此类用于添加渐变蒙版类型,并且仅在一个位置调用。 转换SVRadialGradientLayer.m并在SVRadialGradientLayer.h中添加属性和函数。 转换很简单,并且很快即可完成。 只需应用一个修复程序,只需一个简单的Google搜索即可完成。 之后,我从目标中删除了这个Objective-C类,添加了新的Swift文件并运行了该项目,该项目按预期进行了编译和运行,因此我继续下一个文件。 下一个要转换的类是SVProgressIndefiniteAnimatedView 。 此类用于显示两种类型的不确定动画视图,即本机设计和平面设计。 在本机设计中,ProgressHud使用和显示动画视图,在平面设计中,显示签名UIActivityIndicatorView 。 我将代码转换为Swift,将属性设为私有,并添加了用于设置和获取属性的函数。 接下来,我从SVProgressAnimatedView类开始,该类负责显示带有进度指示器环的HUD。 它仅支持平面样式,不支持UIActivityIndicatorView 。 现在是项目的主类,该主类与外部代码协调并使用这些类来呈现HUD。 这个课程非常复杂。 我使用了前面提到的技术,例如利用setter和getters函数,将所有类函数放在不同的类扩展中。 该类使用自身的单个实例,即它是一个独立的Singleton类。 所有的类函数最终都使用此Single Instance 。 在最终完成之后,我还花了一些时间清理不推荐使用的功能。 我从类函数开始,一次完成转换。 然后是更大的实例方法,它们是库的内容。 慢慢地,文件被转换,并在助手编辑器中使用Swiftify查找原始源代码。 代码转换花了一些时间,有几个问题让我使用原始SVProgressHUD文件和Swift版本文件运行项目,并通过查看运行时值的差异进行调试。 这就是在上面的流程图中 ,我不会删除原始的Objective-C文件的原因,直到代码转换完成并且Swift代码正在运行并经过测试。 现在,如果我们愿意,可以通过不删除@objc前缀,并在用作代码接口的函数和属性中添加@objc前缀来保持与Objective-C的兼容性。 测试之后,我从函数和self中删除了@objc ,并对库进行了增强以使其成为线程安全的 。 现在,您可以从任何线程使用该库,始终可以从主线程创建并评估单个实例 […]
尽管已经写了有关如何正确使用UITableView ,但新开发人员甚至是经验丰富的开发人员仍然偶尔会遇到一些问题。 关于如何使与UITableView相关的代码更短,更好和更易读的内容,有很多有趣的文章以及方便的示例和最佳实践,但是以某种方式,我还没有看到所有建议的总览。 因此,我决定在这里列出至少在使用UITableView时要遵循的所有原则,但是如果您有任何添加或分享的方式,请在下面的评论部分与我联系🙂 0.分成几节 假设您有一些要使用UITableView实现的Profile屏幕: 第一个建议很简单:将表分成几个部分,以使用不同类型的单元格。 如果 indexPath.section == ProfileSectionIndex { //对个人资料进行处理 } 如果 indexPath.section == InfoSectionIndex { 整数索引= indexPath.row //用info [index]做点什么 } 如果 indexPath.section == FriendsSectionIndex { 整数索引= indexPath.row //与朋友做某事[index] } 比这更有意义,更容易使用: 如果 indexPath.row == 0 { //个人资料 } 如果 indexPath.row> 0 && indexPath.row <info.count + 1 { int index = indexPath.row-1 //我看到了很多次T_T […]
最近,我在NSCoder Night Madrid上发表了有关战略模式的演讲。 人们喜欢它! 我认为我们的社区也将从这些知识中受益。 因此,在本指南中,我将解释iOS的策略模式并提供一些示例。 首先,我们应该定义这种模式。 在Wikipedia中,其定义如下: 在计算机编程中, 策略模式是一种行为软件设计模式 ,可以在运行时选择算法。 代码不是直接实现单个算法,而是接收运行时指令,以说明要使用的算法系列中的哪个。 definition⁉️这个定义非常理论化,所以我认为我们可以更轻松地定义它: 将算法封装在类中,使它们在运行时可重用和互换。 分类 设计模式根据其目标分为三类: 创造力的 结构性 行为的 是的,策略模式是一种行为模式,因为它与对象的行为有关。 容易吧? 在许多情况下,我们可以使用它。 让我们谈谈三个非常具体的场景,在这些场景中我们可以清楚地看到战略模式的价值。 1️⃣用不同的方法做同样的事情 当您需要以不同的方式在代码中执行相同的操作时,可以使用它是一个明显的示例。 2️⃣而不是继承 如果您需要扩展类的功能并执行此操作,则需要创建一个继承自该类的新类。 3️⃣if / else块的替代方法 这是我最喜欢的。 有时,如果您查看一个类,您会发现它的if / else或switch块太多,我是说条件块。 这表明该班级的职责比应有的多。 使用策略模式将有助于您分发它们。 假设我们需要创建一个Logger类,该类在控制台中打印一条消息。 此外,此类还允许您打印样式化的消息: 小写 , 大写和大写 。 因此,可能的实现可能是这样的: 内容: 定义我们要封装的动作的协议。 在我们的示例中,操作将是 记录一条消息 。 谁: 包含符合策略的对象的对象。 在我们的示例中, 使用策略记录消息 的对象可能是对象 。 方法: […]
Spesso un sacco di progetti开放源代码的部分质量合格证书,不适用introdurre piccole soluzioni dirette的lodevoli inciziative,che semplicemente funzionano。 Negli anni passati durante la mia carriera da sviluppatore ho preso talmente tanto dal mondo开放源代码的所有dell an an dell’anno scorso ho deciso che a mia volta age venuto il momento di iniziare utilutilare il mio profilo Github per protribuire a progire aprogétiprog Mi sièaperto un […]