Tag: iOS应用开发

iOS开发的可重用框架入门

编写iOS应用程序时,通常会导入Foundation或UIKit框架,而对此一无所知。 如果要使用字符串,日期,文件系统或线程,则可以“导入Foundation”,而如果要使用UITableViewController或UIAlertController ,则可以import UIKit 。 如果要导入UIKit则可以完全忘记Foundation ,因为UIKit是在后台进行的。 关键是这些框架定义了您可以在代码中访问的所有方法,函数和类。 如果您忘记import CoreBluetooth ,将很难连接到自定义的蓝牙设备。 更重要的是,如果您不import SpriteKit ,那么肯定会让独立SpriteKit游戏import SpriteKit 。 这些框架均由Apple构建。 它们可供开发人员使用,因此我们可以利用使iOS应用程序成功的技术。 但是什么是框架,为什么我们要使用它们呢? 框架是模块化的和可重用的代码集,用作高级软件的组成部分。 使用框架的最好理由是它们可以被构建一次,并且可以无限制地重复使用! 让我们再次看一下UIKit 。 UIKit由Apple开发,并且会不断更新。 这是一个项目,开发人员可以重复使用它来构建新的应用程序。 我们可以使用它在我们的项目中定义出色的功能,例如动画,(UI)按钮,过渡和(UI)颜色。 我们知道苹果已经在iOS平台上广泛开发和使用了框架,但是我们呢? 创建框架是一个相对容易的任务,使用它们就像let greenColor = UIColor.black一样容易。 让我们开始制作自定义的Cocoa Touch框架! 我们将构建一个框架来模仿Apple多年来在iOS上一直使用的自定义状态警报。 我通常在“音乐”应用程序,“播客”应用程序和“新闻”应用程序中注意到它们。 这些自定义状态警报已经开始在各处弹出,但是Apple没有提供公共框架来利用它们! 总体而言,这些警报相对简单。 它们由一个UIVisualEffectView (with a blur) (作为背景),一个UIImage和一些文本组成。 创建一个框架来生成这些框架有多难? 实际上还不错! 入门 让我们打开Xcode并创建一个新项目。 选择iOS选项卡,向下滚动到Framework & Library然后选择Cocoa Touch Framework 。 我将其命名为“ AOModalStatus”,其中“ AO”代表我的姓名缩写。 […]

CoreData基础知识(Xcode 9 + Swift 4)

在那篇文章中,我将向您展示CoreData框架的一些基础知识,该框架是用于iOS,macOS,tvOS和watchOS平台的工具,用于管理对象建模 , 生命周期和持久性 。 但是,我不会尝试总结或涵盖文档中的每个要点。 您可以在这里自己做— https://developer.apple.com/documentation/coredata。 相反,我将向您展示如何对对象建模以及如果要读取或写入某些东西如何运行查询 。 我们将创建的示例项目将使用Xcode 9和Swift 4构建。 让我们弄脏双手吧! 首先,让我们创建一个新项目,然后选择“ Use Core Data” 。 尽管您可以为现有项目添加该框架,但是从该位置添加框架会更容易,因为一切都已经为您完成。 创建项目后,您将看到添加了CoreDataTest.xcdatamodeld之类的文件。 单击它时,您将看到一个工具,可用于配置代表数据模型的实体。 您可以为每个实体定义一些事物,但对我们而言, 属性和关系将是最重要的。 让我们添加一个名为User的新实体(单击“ 添加实体”按钮以更改其名称,在顶部两次单击新添加的实体的名称,然后键入您的名称)。 现在,让我们添加一些属性来定义新实体的架构: email —字符串, 名称 —字符串, date_of_birth —日期, number_of_children —整数16 同样,让我们​​添加一个名为Car的新实体,该实体将包含属性: model-字符串, 年份 -整数16。但是现在让我们在car和用户之间添加关系。 为此,我们将从该点向User实体添加一个由user表示的关系。 比起您必须回到User实体并设置与Car的关系。 之后,您可以在Car上设置与User的逆关系。

ISP:接口隔离原理

根据方法组将Fat协议转换为小型协议 接口隔离原则( ISP)指出: 不应强迫客户依赖他们不使用的方法。 在设计应用程序时,我们应该关注包含多个子模块的模块抽象。 在创建另一个仅包含原始系统子模块的模块时,我们被迫实施完整协议并编写一些虚拟方法。 这样的协议被称为胖协议。 ISP帮助我们避免: 胖接口 不要强迫类实现他们无法实现的方法 不要用很多方法污染协议 接口隔离原则主张将“胖接口”隔离为较小的且高度紧密的协议,称为“角色协议”。 每个“角色协议”都声明一种或多种用于特定行为的方法。 因此,客户端只能实施与其方法相关的那些“角色协议”。 违反接口隔离原则: 当客户端依赖于不使用的方法时,这意味着抽象是错误的。 如果ImageMessageView和VideoMessageView实现此协议,则由于图像视图不了解视频播放器,反之亦然,因此将产生开销,因此需要实现虚拟方法来满足编译时错误。 使协议方法为可选的另一种解决方案是在协议扩展中创建虚拟方法,然后覆盖特定类中的必需方法。 遵循接口隔离原则: 通过遵循ISP,我们可以将上述协议分为2部分: 现在, VideoMessageView可以只符合DeepLinkVideoMessage 。 将来如果需要删除视频消息,我们可以简单地删除此协议并查看而无需触及其他代码。 与ImageMessageView相同

Swift第一部分的闭包

如何创建没有名字的功能! 介绍: 闭包是swift最有用的未来之一。在这三部分的文章中,我将以现实生活中的例子从最基本的方面来解释闭包。 什么是闭包: 闭包只不过是没有名字的函数。它意味着闭包是一个没有名字的函数,用不同的语言来调用,就像:匿名函数,回调,lambdas等。 换句话说,闭包是自我包含的功能块,可以在代码中传递和使用。 在深入探讨闭包之前,我们先创建一个函数并将其转换为闭包。这使我们的概念更加清晰。 简单功能: 如果我们考虑功能和闭包,那么我们可以像这张图那样说明闭包和功能。 让我们讨论闭包语法。 基本语法: 关闭以大括号开头,以大括号结束。这是简单的关闭语法: {{argumentName:Type)-> ReturnTypein //声明和其他 // …… // ….. 返回} 这是闭包的基本语法,以大括号开头,而不是参数名称及其类型,比返回类型比关键字中的语句要大,并且比return还要大。 范例一: 闭包的另一个基本示例,参数取两个值并进行计算并将其返回。如果执行此闭包,则可以执行以下操作。 let result = clasureOne(10,50)//结果应为500 示例二: 该闭包采用两个字符串,并将其作为单个字符串返回给字符串。顺便说一句,此闭包也分配给closureTWo变量。 var fullName = closureTWo(“ Mahmudul”,“ Hasan”) // fullName变量现在获得了“ Mahmudul Hasan” 以不同方式创建: 我们知道Swift是一种类型 – 安全的语言,因此在函数或闭包中,我们需要定义每个变量或常量的类型,然后隐式或显式初始化它。对于此功能,我们可以通过多种方式创建闭包Let Start .. 这个addTwoNumber闭包我们在equal =之前定义类型,并从闭包头中删除类型,这样我们可以这样写。 我们可以省略标题的返回类型,也可以变得足够聪明以至于无法理解 现在我们也可以从主体中删除return关键字。 现在我们可以像这样写在一行 现在非常简写,而且非常简短 因此这里是一个有趣的swift闭包,了解它有两个变量并将其添加并返回变量addTwoNumber 。因为我们明确定义了它的类型。而swift的默认参数名称为$ 0,$ 1,$ […]

在iOS Swift中预取UITableView

UITableViewDataSourcePrefetching :iOS 10中的一种协议UITableView,可以异步加载异步数据源。 用户不希望滚动到chhmhoặcđừ滚动s并加载nhữngindexPathtiếptheosắpđượchiệnlên,请确保平滑滚动cho tableviewhoặccollectionview。 Cácbướcthựchiện: TableviewVà数据源 符合协议 tableView 。 prefetchDataSource = 自我 可以通过通讯协议tableView(_:prefetchRowsAt:)加载数据,并可以缓存。 显示数据UI UI tableView(_:cellForRowAt:) 取消加载获取异步任务: tableView(_:cancelPrefetchingForRowsAt:) 生活圈: Khi lnnđầhi hinn单元格,tindex索引路径= 0,hàmprefetchRowsAt索引10索引ti p theotínhtừ索引cuốiđhiệntrênmànhình(内容偏移量)。 Khi用户滚动chậmxuống,hàmprefetchRowsAtsẽtrảvề1索引tiếptheo,tứclà索引thứ11(10 +1)。 Khi用户滚动滚动索引,滚动索引10索引索引滚动索引(内容偏移量)。 Khi用户滚动chậmsauđóđộtngộtđổihướng滚动,hàmprefetchRowsAtsẽtrảvề10 index theohướngđãđổi,đồngthờisẽvàohàmcancelPrefetchingForRowsAttrảvềindexàvđindexà thị。 代码: -Thựchiệnkhaibáo代表 myTable.prefetchDataSource =自我 -实施代表 func tableView(_ tableView:UITableView, prefetchRowsAt indexPaths:[IndexPath]){print(“ Fetching:\(indexPaths)”)//异步加载:数据,图像… func tableView(_ tableView:UITableView, cancelPrefetchingForRowsAt indexPaths:[IndexPath]){print(“ Fetching Cancel:\(indexPaths)”)//取消隐藏các操作异步加载数据 } 您可以跟随đểnhậnnhữngbàiviếtmớinhấtcủamìnhnhé。

在Swift中使用Alamofire进行可扩展的网络

如今,几乎每个应用程序都需要从远程API获取数据或向远程API发送数据。 现代应用程序的网络层是应用程序体系结构的关键部分,因此需要以可扩展和类型安全的方式进行设计。 前不久,objc.io的家伙们提出了一个小型网络库的设计,该库能够执行iOS开发人员在应用程序开发周期中可能面临的最常见任务。 在本文中,我将重新讨论objc.io的方法,并展示该方法的典型应用。 首先,我们需要定义三种核心类型APIAction , Resource和APIClient 。 让我们从APIAction开始。 APIAction实例描述将要发送到服务器的http请求。 这是一个协议,应该被采用。 与往常一样,您可以在GitHub上找到完整的源代码。 请留下您可能有的任何评论,我们很高兴收到任何反馈。 您可以通过LinkedIn或Facebook与我联系。 alexey-savchenko /网络示例-中 通过在GitHub上创建一个帐户,为alexey-savchenko / NetworkingExample-Medium开发做出贡献。 github.co

如何绝对杀死冒名顶替综合症

为什么学习编码如此令人沮丧? 实际上,当您已经知道“如何编码”时,为什么仍然令人沮丧? 最重要的是,为什么如此多的人能够很好地编写代码(被称为冒名顶替综合症),却会感到欺诈? 我想给出我的答案,并希望在您的编码生涯中为您提供帮助。 首先,我是谁? 好吧,我是一名iOS开发人员,而且我喜欢编码,但是我一生也做过很多教学; 无论老少,我都可以肯定地说,困扰着许多学习密集型职业的正是这些问题,而这个问题实际上就是学习。 和我在一起,我保证即使您不是程序员,您也会发现这确实有用。 我们已经将学习风格,学习理论,学习的秘密变得更加复杂,更快,更好,更久……(后现代主义者甚至会问:“什么在学习?”)。 通过做。 您可以观看不计其数的教程,阅读一百万行代码,而不是该死的东西。 在撰写更多文章之前,这是我争论的重点: 作为开发人员,有很多东西要学习。 吨的框架,语言,模式等。然而,在任何职业中(尤其是我来自的音乐领域)都需要学习很多。 为什么为什么对编程如此沮丧? 我一生中从未遇到过冒名顶替综合症的音乐家。 我相信答案是我们将永远学习,但真正的学习却很少。 当您学习一种新语言时,您一定要“用它来运行”。 如果您在编写任何代码之前考虑到语言的方方面面,那么您将一事无成。 当您攻击新的框架,库和其他人的代码时,您可能会边走边学。 语言将不可避免地演变为x版本,框架将发生变化和适应,您仍然只知道该框架的50%,但您已经足够了解。 听起来有点熟? 辛苦了 当我做音乐时,当我能真正被蒙住眼睛弹奏时,我就“知道”它。 我听了数百遍,练习了每一个音符,每个间隙,每个旋律都隐藏在乐曲的深处,直到我几乎可以分别演唱每个部分。 熟悉一些我需要在日常生活中使用的零件和工具,但是有些事情我绝对需要知道。 我知道那是什么,并确保我了解它们。 那我的意思是什么? 如果您不了解某些内容,只需在Google上搜索对不对? 好吧,如果您必须搜索它,那么是的,显然您不知道它。 好的,可以! 实际上,您需要熟悉数百万种内容才能知道如何解决问题。 Google令人称奇,它彻底改变了我们获取信息的方式。 但是Google不会为您的信心做任何事情,冒名顶替综合症肯定在那个角落等待着。 但是,如果您意识到: “我需要熟悉并能够找到这些事情的解决方案,但我要确保我真的了解 这件事的所有内容。” 然后,您意识到一些完全解放的东西: “我实际上不需要了解这些东西。 我不需要是人类的海绵或天才。 我可以随意找到这些信息。 但是我确实知道这些东西,真的很好! 那么,您何时真正从“学习”到“学习”呢? 答案很简单:何时可以随意回忆。 可能是CoreData并可以自由使用它,也可能是C#中的肖邦的Nocturne。 没关系 逐条记录,逐字母回忆。 等等,我对核心数据一无所知(在此处插入所需的内容)。 有些地方我听不懂或记得。 TADA! 您刚刚意识到自己在某些已知事物上存在弱点。 这种弱点需要治愈。 实践。 音乐练习专门针对那些非常弱小的方面,可以说,每种练习都应该是相同的。 这也被称为“故意练习”,您将在非常小的和超特定的事物上进行工作,并专注于它,专注于它,直到您像Lazerbeam杀死独角兽一样粉碎它为止! […]

在Pinterest上开发快速可靠的iOS版本(第一部分)

Rahul Malik | iOS平台技术主管 在Pinterest,我们专注于帮助人们发现启发性的想法,从晚餐食谱到尝试,从家庭和时尚产品到购买,再到旅行的地方。 构建最佳的移动产品是其中的关键部分,所有Pinner的80%通过移动应用访问Pinterest。 特别是在iOS团队中,我们一直在不断努力,以尽可能高效和迅速地改善这种体验,而为我们的团队提供最佳的开发和测试环境是其中的关键一步。 最近,我们研究了简化该过程的方法,并着手提高基于本地和持续集成环境的iOS构建的速度和可靠性。 此外,我们开始将应用程序模块化为独立的框架,并需要一个系统来支持该迁移。 我们回顾了多种工具,包括Xcode,Cocoapods,Buck和Bazel。 我们希望为未来引入更稳定的基础,这对于我们快速迭代并向Pinners发布新功能的能力至关重要。 通过比较Xcode,Cocoapods,Buck和Bazel,我们发现Bazel最适合我们的目标,即为性能提高一个数量级,消除构建环境中的可变性并逐步采用该基础。 因此,我们现在使用Bazel交付我们所有的iOS版本,这些版本已经取得了成功,其中包括: 当地发展 更快的构建:将干净的构建时间从4m 38s减少到3m 38s,提高了21%。 本地磁盘缓存允许即时重建您之前构建的任何内容(其他分支,提交等)。 CI和本地环境之间的环境相同,因此生成问题很容易重现。 自动化程度更高:代码生成等任务已包含在构建图中。 持续集成 每个构建都是增量构建:由于Bazel具有可复制性,因此一年多来我们一直没有在CI上执行任何全新构建。 一次构建,可在任何地方重复使用:引入远程构建缓存后,由于我们不需要重新构建任何机器上已构建的任何内容,因此构建时间减少了不到一分钟且低至30秒 缩短着陆时间:将构建时间从10m 24s减少到7m 34s,提高了27%。 缩短更改Beta测试人员的时间:Beta的构建时间从1400万32秒减少到700万52秒,提高了45%。 更快的测试执行:如果修改后的代码不影响测试,则测试运行是即时的。 更高的构建成功率:使用Bazel运行构建任务时,构建成功率从大约80%提高到97%-100%。 迈向快速可靠构建的未来 由于我们使用的是编译语言(Objective-C / C ++),因此构建速度一直是开发人员的瓶颈。 但是构建速度很难量化。 它包括在不同环境中的构建,例如持续集成或本地开发。 我们还处理各种工作流程方案,例如全新构建,增量构建,分支切换,变基,还原更改等。 您无法改善无法衡量的内容,因此,提高构建速度需要跟踪各种方案,以使我们能够准确地确定回归并集中精力进行性能工作。 我们可以通过减少工作量或提高工作效率来加快构建速度。 这可能涉及使用不同的工具,改善并行化或更新项目的体系结构以需要更少的源文件。 围绕维护模块化体系结构以及清除未引用的代码或与已完成的实验相关的无效代码,采取有力的实践将有助于维护/提高构建速度。 我们使用各种内部工具和脚本来识别无效代码。 对于实验,我们利用自动化功能添加了clang批注以弃用与实验相关的方法和常量,从而允许编译器警告开发人员实验已结束且应删除代码。 开发人员通过定期运行工具来检查未引用的代码,即定期运行工具来检查标头包含我们构建的图形,并递归查找零引用的文件。 我们的构建过程必须既快速又可靠。 如果构建是可复制的,则它们是可靠的。 可重现的构建不仅对于重现错误很重要,而且对于确保我们提供经过开发和测试的应用程序的确切版本也很重要。 只有构建环境(输入和输出)一致,我们才能实现这一目标。 环境的变化会极大地影响最终产品并引入可变性。 一致的环境可确保应用程序的行为相同,而不管它是在开发人员的计算机上构建还是通过持续集成构建而成,并且消除了花时间弄清楚构建为何在一个环境中成功而在其他环境中失败的时间。 尽管这些想法和探索都围绕iOS进行,但快速且可复制的构建目标是我们所有人共同的目标,并将使我们能够扩展客户端工程。 挑战性 专注于改善构建过程的决定植根于它对开发人员生产力的影响。 随着我们团队和产品的增长,投资于开发人员使用一致且快速的构建系统的能力至关重要。 规模:随着我们扩展客户工程的规模,花费在支持开发人员,维护或减少构建时间以及提高可靠性规模上的时间也有所增加。 […]

让我们用React Navigation导航

我们都知道,实施导航很重要,有时会给移动应用程序的开发带来痛苦。 因为它直接或剧烈地影响着用户体验和应用程序性能的好坏。 您需要从多个有趣的导航解决方案中进行选择,并以明智的方式使用它来获得所需的结果。 在React Native世界中,大多数事情仍然充满活力和不成熟。 React社区非常强大且富有成效。 但是,这给所有积极的事情带来了痛苦。 例如,在几次版本更新后,可能会弃用您喜欢的库或所选功能。 以我自己的经验,我开始使用react native的导航器api,然后决定切换到Navigation Experiment以在性能和前向兼容性方面获得更好的结果,它看起来很有希望,当时的嗡嗡声是非常积极的,但是最近突然不推荐使用。 所有这些事情几乎都发生在一年之内。 首先,什么是React Navigation? 在React Native官方文档中,它被描述为: React Navigation提供了一种易于使用的导航解决方案,能够在iOS和Android上呈现常见的堆栈导航和选项卡式导航模式。 由于这是JavaScript实现,因此与状态管理库(例如redux)集成时,它提供了最大的可配置性和灵活性。 是的,它与IOS和Android都兼容,非常灵活,您可以将其与redux,flux或mobx集成。 在开始之前,让我们检查示例导航应用程序的最终版本。 为了简化和提高生产力,我们将在Expo的帮助下对该示例应用进行编码(我不会进入主题,您可以从链接中进行检查),因此您也可以在Expo Client中查看工作示例。 好吧,让我们现在滚动。 如果您想签出并玩代码; 这是 github repo链接和expo链接用于示例应用程序。 开始吧 ! 用expo创建一个新的空白项目,不要让expo为导航布局一些代码,而是选择空白项目。 现在,我们可以将反应导航添加到我们的项目中。 npm install –save react-navigation 或者如果您安装了纱线; yarn add react-navigation 与三种类型的导航器捆绑在一起的React导航; StackNavigator,TabNavigator和DrawerNavigator。 我不想为您提供有关导航器类型的更多详细信息,您可以从文档中进行检查。 我们将在我们的应用程序中使用这三个。 现在,让我们创建一个文件,并像这样在其中添加StackNavigator 。 导入{ StackNavigator, DrawerNavigator, TabNavigator} 来自“反应导航”; 从’./FirstScreen’导入FirstScreen; 从“ ./SecondScreen”导入SecondScreen; 从’react’导入React; […]

iOS到条带化API身份验证(Swift 3 + Node.js + XCode教程)

在过去的几年中,Stripe已成长为在线支付领域的重要平台。 Stripe在开发人员社区中尤其受欢迎-凭借其友好的API,开发人员可以非常快速地将Stripe插入其网站/应用程序。 在本教程中,我们将介绍通过Swift应用程序启动对Stripe帐户的身份验证的过程。 本教程假定您已经有一个Stripe Account设置。 希望这将是许多Swift / Stripe教程中的第一个。 敬请关注! 本教程由2个组件组成; 客户端iOS Swift应用程序和后端Node.js应用程序。 我们将从Node.js应用程序开始依次介绍每一个。 转到此>> Git存储库以访问已为您设置的Node.js应用程序。 提供的自述文件将引导您完成如何克隆存储库,执行必要的编辑并将其部署在Heroku上的说明。 通过设置Node.js应用程序并在Heroku上运行,我们现在将完成一个简单的任务,即创建将与Node.js后端一起使用的客户端Swift应用程序,以对您的Stripe帐户进行身份验证-仅需15个简单步骤! 注意:您可以在此处访问该项目第2部分的存储库>> 步骤1。 创建一个单一视图应用程序,并为其分配一个适当的名称。 我叫我StripeConnectApp 第2步。 删除默认创建的两个文件,即ViewController.swift和LaunchScreen.storyboard 。 我喜欢这样做纯粹是出于整理的目的,尤其是因为我不需要该项目的启动屏幕 第三步 创建2个Cocoa Touch类(它们都是UIViewController的子类),分别命名为MainViewController和StripeConnectViewController 。 步骤4。 下载>>,解压缩3个图像文件并将其拖到Assets.xcassets文件夹中。 在我们进行项目时,将在以后的阶段中引用它们。 第五步 将IDE界面切换到故事板— Main.storyboard 。 选择默认的ViewController场景并将其嵌入到导航控制器中,如下所示。 第六步 在ViewController上选择了Navigation Item的“ Attributes Inspector”部分中,如下所示填充Title和Back Button属性的值。 步骤7 将一个Button UI元素从“对象库”拖到默认的“视图控制器”上。 选中“按钮”后,在“属性”检查器中,转到“图像”属性,然后选择可用的图像,如下所示。 步骤8 调整按钮的宽度以适合其附带的图像。 重新放置Button,将其放置在ViewController的中心并设置其约束,如下所示。 步骤9。 选择默认的ViewController后,在Identity Inspector部分中,从Class属性中选择“ MainViewController ”,如下所示。 […]