Tag: iOS应用程序开发

Swift中面向协议的编程简介

当我几年前开始编码时,它全都与面向对象编程有关。 借助Swift,出现了一种新方法,使代码更易于重用和测试, 面向协议的编程 。 在介绍解决方案之前介绍问题,让我们假设我们拥有这个Vehicle类,并且Car继承了它的速度值。 class Vehicle { var speed : Double = 0.0 } class Vehicle { var speed : Double = 0.0 } class Car : Vehicle { override init() { super.init() self.speed = 90.0 } } class Car : Vehicle { override init() { super.init() self.speed = 90.0 } } 但是,在开车之前,我们使用了其他交通工具,例如马,也有特定的速度。 在没有继承的情况下,该新对象如何表现为其他对象? […]

5个提示:雇用iOS应用开发代理

寻找iOS应用开发机构吗? 在雇用技术合作伙伴之前,您应该了解以下内容。 iOS App Store上每个类别都有数百万个应用程序? 那么,如何使您的应用脱颖而出? 这是一个重要的问题,并且与您的iOS应用程序开发投资密切相关。 好吧,如果您没有内部的iOS开发人员团队,并且希望由代理商来完成开发,那么以下五个技巧可帮助您雇用合适的iPhone应用程序开发代理商 。 1.撰写有效的工作岗位 雇用技术合作伙伴涉及邀请技术合作伙伴提供报价或估算。 但是,如何从相关技术合作伙伴处获得相关报价是一个重要的问题。 因此,该过程始于撰写有效的职位。 工作岗位的三个关键要素是: 结果:您期望什么可交付成果? 2.技能:您正在寻找什么技能,编程语言,API,SDK等? 3.目标:您的截止日期是什么? 您是否将应用程序开发分解为多个阶段? 2.掌握Sound Swift编程知识,押注iOS开发人员 找到想要的编程人才并不难。 借助Internet和移动应用程序等扩展的虚拟感官,可以轻松地将其吸引到更广泛的受众。 利用工作门户,StackOverflow等技术平台,LinkedIn,WishList等专业网络。Swift是Apple最新的编程语言,并且配备了各种资源,以确保敏捷和安全的编码。 3.寻找以业务为中心的iOS应用开发公司 出人意料的是,没有多少人真正了解企业pp的目标或用户对它的期望。 因此,您应该明智地选择iOS应用开发公司。 可以通过以前构建的应用程序了解它们的细致性。 记录他们在iOS App Store等公认的应用程序分发平台上的实时项目。 4.寻找敏捷的iPad或iPhone应用程序开发 基于敏捷的软件开发可将设计人员,开发人员和软件合规性监控人员聚集在同一页面上,从而有助于立即修复错误和增加产品质量。 这样的关联可确保您的应用程序保持最新状态并与用户的期望相关。 5.评估技术合作伙伴的信誉 品牌信誉是重要的方面,与技术公司联系时必须考虑品牌信誉。 当您雇用某个知名品牌时,显然意义不大,因为这将获得可观的市场信任,但是如果您要与一家初创公司合作,则必须权衡利弊。 确定该品牌具有处理业务短期和长期目标的专业知识和能力。

iOS Foundation:什么是NSBundle

存储在磁盘上捆绑目录中的代码和资源的表示。 苹果使用捆绑软件代表应用程序,框架,插件和许多其他特定类型的内容。 捆绑软件将其包含的资源组织到定义明​​确的子目录中,捆绑软件的结构因平台和捆绑软件的类型而异。 通过使用包对象,可以在不知道包结构的情况下访问包的资源。 捆绑对象提供了一个用于查找项目的单一界面,同时考虑了捆绑结构,用户首选项,可用的本地化以及其他相关因素。 任何可执行文件都可以使用包对象在应用程序的包内或其他位置的已知包中查找资源。 您不使用包对象在容器目录或文件系统其他部分中查找文件。 NSBundle包括一些常用功能: class var main: Bundle 返回包含当前可执行文件的捆绑对象。 class var allBundles: [Bundle] 返回所有应用程序非框架捆绑包的数组。 init(for: AnyClass) 返回与指定类关联的NSBundle对象。 init?(identifier: String) 返回具有指定包标识符的NSBundle实例。 func loadNibNamed(String, owner: Any?, options: [AnyHashable : Any]? = nil) 取消存档位于接收者包中的nib文件的内容。 func url(forResource: String?, withExtension: String?) 返回由指定名称和文件扩展名标识的资源的文件URL。 var localizations: [String] 捆绑软件中包含的所有本地化列表。 让我们实现一个功能强大的NSBundle! 捆绑包初始化。 在里面 主捆绑 常规项目中经常使用的组合以获得项目资源。 主捆绑 所有捆绑 如果您需要遍历分发包以查找某些内容或检查其是否存在。 所有捆绑 班级捆绑 […]

世界走向斯威夫特

作者:Tamir Avrahamov公司。创始人 Gini-Apps (linkedin.com/in/tamiraaa) 2014年6月2日,Apple宣布将Swift语言作为Apple操作系统的编程语言,当然,还宣布了IOS的本机语言,IOS是iPhone和iPad的操作系统。 Swift语言是这里取代以前的语言-Objective C的一种 ,它采用更安全的编程模式,添加了现代功能,使编程更轻松,更灵活且同样重要,它更加有趣。 苹果一直致力于开发快速编程语言,直到大约两年前才向开发人员发布。 重要的是要了解语言不会轻易死亡。 目标C仍然存在于Apple代码的许多部分中,并且将始终存在,但是受困并依赖于过去技术的应用程序和开发将变得难以维护并最终消失。 那么我们应该继续使用其他语言吗? 如果是这样,什么时候? 当然,与苹果一起前进总是值得的,并且不建议忽略苹果公司对开发环境带来的任何变化,并且在过去几年中带来了很多变化。 这些更改带来了对新设备中新分辨率的支持,更好的性能,应对图形挑战的工具以及界面,这些操作从一开始就很复杂,现在变得更易于实现。 在某些情况下,目标C功能已被弃用,Apple或任何其他第三方提供了更新和更快的方法/算法以供快速使用。 您可以看到Apple工程师进行的比较,并可以更清楚,更明显地看到性能: 没有简单或魔术的方法可以快速转移到Swift。 您必须投入大量的精力,采用更安全的编程模式,甚至还要考虑新的设计,因为唯一的方法是重写您的应用程序。 是的,是时候了,这也是Swift Ver。的好时机。 3.0被认为是稳定且安全的实施。 除此之外,我认为最重要的原因是程序员。 在过去的两年中,世界各地的大学都在教授Swift,从那时起,新的Objective C开发人员还没有进入工作岗位。 开发者社区非常喜欢swift,以下图表说明了Swift被爱了多少(堆栈溢出): 那你从哪里开始呢? 有很多方法可以实现和重写代码,因此正确地计划,升级应用程序功能,以习得的方式设计代码体系结构非常重要,因为Swift可以在这里保留很多年。

破解核心数据测试

核心数据是一个框架,它隐藏诸如对象生命周期和对象图管理之类的持久层的逻辑,以帮助您以高级方式管理模型层对象。 是的,Core Data对许多开发人员来说都是有争议的。 但是,它仍然是有用的框架:性能良好,并且得到Apple的支持。 关于核心数据的单元测试,有很多不错的文章,但是大多数文章集中在模拟上下文。 由于发布了持久性容器类NSPersistentContainer,因此越来越难以模拟上下文并将测试写入容器。 因此,在本文中,我将探讨一个新主题:为NSPersistentContainer编写测试,增强型核心数据。 我们将一起使用NSPersistentContainer设置核心数据堆栈,并为此编写测试。 TL; DR 我们将学习如何: 使用NSPersistentContainer构建核心数据栈 使用内存永久存储 引入两个测试双打:“假”和“存根” 做一个异步测试 先决条件 迅捷3 Xcode 8 核心数据基础知识 iOS 10(由于我们将使用NSPersistentContainer,因此需要iOS 10)。 以下是一些有关核心数据的好文章: 完整的核心数据应用程序(代码在Objective-C中,但是概念相同) 核心数据入门教程 我们的任务 现在,我们有一个简单的任务:实现待办事项列表系统,在其中我们可以创建,读取,更新和删除待办事项(CRUD)。 而且这个待办事项系统应该永久保存数据,以便即使我们终止应用程序也可以稍后获取它们。 因此,我们需要实现这些方法: 创建待办事项 提取所有待办事项 删除待办事项 提交对永久存储的更改 由于我们只想在需要时执行保存,因此我们不会在创建/编辑/删除方法中将NSManagedObjectContext .save()视为副作用。 相反,我们将其设为独立方法。 当用户按下“保存”时将允许保存数据,或者当用户离开当前视图时将其保存。 尽管通过使用NSPersistentContainer在iOS 10之后设置Core Data堆栈更容易,但最好具有一些基本知识。 我们将在以下各节中采用这些概念。 因此,在下一节中,我将简要介绍Core Data堆栈。 核心数据栈 根据苹果公司的说法,核心数据栈是框架对象的集合,这些对象是核心数据初始化过程的一部分。 核心数据堆栈中包含4个基本组件: 托管对象上下文 (NSManagedObjectContext):为托管对象提供便签本 持久性商店协调器 (NSPersistentStoreCoordinator):汇总所有商店 托管对象模型 (NSManagedObjectModel):描述商店中的实体 持久对象存储 :包含已保存的记录。 […]

创建一个移动应用程序:您应该知道的事情

您是否知道公司在逐年增加移动应用投资? 如今,创建移动应用程序已非常流行,实际上这是推广品牌的非常明智的策略。 但是在构建移动应用程序之前,您应该仔细考虑所有因素,因为与所有与业务相关的决定一样,确保获得投资回报非常重要。 什么是移动应用程序,什么是网络应用程序? 移动应用程序和Web应用程序可帮助用户通过手机,平板电脑等访问数据。移动网站类似于任何其他网站,但它适用于移动屏幕。 您只能通过Internet浏览器访问它。 但是关键的区别在于,移动应用程序是为较小的手持显示器和触摸屏界面设计的。 移动应用程序是用户从Google Play或Apple商店等数字发行平台购买和下载并安装在其设备(例如智能手机,平板电脑,而不是台式机或笔记本电脑)上的应用程序。 网络应用程序的优势 方便 为了使用移动应用程序,用户需要从在线商店下载该应用程序才能访问其内容。 借助Web应用程序,用户可以直接通过浏览器访问内容,而无需执行下载和安装过程。 兼容性 除非您要使用混合移动应用程序,否则本机应用程序是为不同的操作系统(例如iOS和Android)开发的。 Web应用程序允许从任何移动设备访问其操作系统,而不管其用户如何。 这使得Web应用程序比本地移动应用程序更具兼容性。 灵活性 如果您需要更新Web应用程序上的内容和其他信息,则只需要在Web上进行更改,显然这些更改将立即可见,但是如果要创建移动应用程序,则每次更改时在您的移动应用程序上,您需要对其进行更新,并通知您的用户将其更新为新版本。 更难,更昂贵 开发移动应用程序比构建Web应用程序更加昂贵和复杂。 似乎我在说Web应用程序更好,因为我刚刚列出了拥有Web应用程序的优点。 但是事实并非如此,我认为这取决于情况。 移动应用程序不仅适用于亚马逊,阿里巴巴等大型公司,而且在竞争激烈的世界中,移动应用程序常常带给您领先优势,并发挥了优势。 那么,移动应用程序可以做什么,而网络应用程序不能做什么? 什么时候考虑创建移动应用程序? 授予访问内容和功能的权限 实际上,在移动应用程序上,您授予了访问不需要互联网的内容和功能的权限。 让我们以一个离线应用程序为例,您可以在其中保存视频,文章和其他类型的内容,以供以后选择访问:Pocket。 让他们玩 如果您想为用户提供游戏体验,那么创建移动应用程序始终是为用户服务的最佳选择。 定期使用 如果您打算定期使用您的应用,那么您希望增加用户的参与度,发送有关最新新闻的通知等,那么显然移动应用将是正确的选择。 这适用于许多电子商务企业,使购物体验更加轻松。 有什么要报告的吗? 如果您需要使用某些数据并通过复杂的计算,图表或报告进行操作,则可以使用应用程序。 使其互动 例如,在教育领域,如果教师需要与学生互动以交流想法或帮助他们的学生在学习过程中解决问题,那么创建移动应用程序可能是一个好主意。 分享图片,视频和内容 例如,类似Whatsapp的应用程序允许用户直接从手机发送图片或视频,甚至可以与朋友通话和聊天。 或者像instagram这样的应用程序,使用户可以上传图片和视频,对其进行编辑并与朋友分享。 因此,如果您需要访问用户的摄像机或联系人列表,则应用程序将是更好的选择。 问自己什么 如果要构建移动应用程序,则应首先回答一些重要问题。 您的业​​务真的需要吗? 构建应用程序并不容易且不便宜。 在做出任何决定之前,您应该真正考虑这一点。 是移动应用程序是解决问题的唯一解决方案,还是还有其他选择,例如,使用Web应用程序。 您是否考虑过第二步? 请记住,构建移动应用程序并在网上商店出售后,它并不会全部停止。 如果您想“烧钱”,则您的应用程序需要为用户提供真正的价值,而且这需要定期进行,这意味着可以帮助您规划和推广应用程序的数字营销策略。 另外,请记住,用户有很多原因会在其手机或设备上卸载移动应用程序。 您必须意识到所有这些问题。 目标是什么?您愿意投资多少? 开发应用程序的成本是不同的,并且取决于应用程序的类型和功能。 […]

在开始构建iOS应用之前。

如果要开发高质量的iOS App。 不要直接开始编写代码。 如果您认为没有设计,计划,估算,则可以生产出高质量的应用程序。 你想错了。 您将失去宝贵的时间。 因此,在开始编写iOS应用程序之前,请遵循以下步骤。 1)了解要求并定义应用范围。 在需求收集期间提出您的观点。 询问您在功能和设计级别协商期间观察到的所有内容。 记下所有关键和功能点。 验证App设备平台iOS / iPad / TV-OS / I-Watch。 另一件事是确认该应用程序仅处于纵向或纵向和横向布局。 了解流程并与项目经理(Mediator)和客户确认。 2)创建设计– 线框,模型和原型应在可视化工具或图形设计器的帮助下进行定义。 正如我们认为的那样,这并不简单,根据客户要求设计和原型化应用程序是非常困难且至关重要的任务。 并在开始编写代码之前先向客户和项目经理确认。 一旦您的设计被他们确认。 与项目经理,后端开发人员,图形设计人员,测试人员和android开发人员一起生成适当的成本和时间估算计划。 一旦您从客户那里收到绿色信号,便将您的初步或最终估算发送给客户,以进行进一步的操作。 注—在给出最终时间估计的同时,添加一个缓冲区来解释风险并解决不可预测的行为(错误)。 3)收集所需的资源- 收集所有需要的资源,例如: 1)Apple开发人员帐户,置备配置文件和证书。 2)登录帐户凭据(Facebook Gmail等) 3)推送通知服务提供商凭据。 (如果需要的话) 4)应用程序图标和初始屏幕资产。 5)其他图片和资产。 4)分配资源和人力– 开始之前,请验证客户端提供的凭据和信息是对还是错。您应该至少拥有一台iPhone和iPad设备以进行测试。 然后考虑可用资源制定计划。 将项目模块化为子任务。 将任务分配给开发人员和设计人员。 5)升级Mac OS和最新的Xcode — 在开始编码之前,您必须先更新Mac Os,然后为了应用程序而更新Xcode,才能在当前版本的iOS上使用该代码。 示例—如果您在Xcode 8.3上制作应用,则iOS 11将不支持该应用。 注—首选快速编写代码,而不是目标c。 现在,您可以进一步进行编码了。 快乐的编码。 如果您发现有用的内容,请发表评论并分享该文章。 文章来源-来自我的个人博客-http://ios-support.blogspot.com/

WWDC 2018最新Swift 4.2功能

更少的样板=更快乐的开发人员 作为iOS开发人员,我像许多其他人一样从Objective-C开始。 在日常工作中,我与Swift一起工作,考虑到它的第一次迭代的增长,我发现它的多功能性很有希望。 是的,前几个版本的重大更改难以使用; 但是,这些不断增长的痛苦导致了一种更好,更高效的语言。 它的第四个主要版本在功能和社区方面都继续给人留下深刻印象。 上周,苹果举行了年度全球开发者大会(WWDC),其中展示了Swift的一些最新改进。 尽管Swift 5计划于2019年发布,但Swift 4.2具有其自身的优势,特别是在消除繁琐的样板代码方面。 枚举案例的派生集合 Swift的可爱功能之一是它具有使用类似结构的功能来扩展枚举的功能。 例如,如果我们要遍历下面显示的枚举中的所有Fruits ,则需要实现一些样板代码,其中包含数组中的所有案例。 除了每次要遍历数组时都创建一个allCases变量外,每次向枚举添加新的大小写时,我们还必须更新allCases数组。 这可能很麻烦,并且为开发人员错误留了太多空间。 Swift 4.2添加了一个名为CaseIterable的新协议,该协议默认情况下只是添加allCases数组。 我们需要做的就是将CaseIterable添加到我们的枚举中,现在我们可以遍历所有案例。 但是,请务必注意,具有关联值的枚举将无法扩展CaseIterable 。 allCases数组中的元素必须具有相同的类型,而每个枚举的关联值可以包含不同的类型。 合成等量一致性 假设有一个用户对象具有我们可能要比较的简单属性。 令人讨厌的是,我们需要User对象符合Equatable协议,然后检查两个比较对象的每个属性是否相等。 尽管这看起来很简单,但是如果我们比较具有许多属性的大型对象,这也是一项不必要的麻烦任务。 Swift 4.2现在将能够比较两个 Equatable 对象,而无需实现Equatable函数。 只要每个属性都符合Equatable ,Swift就可以推断出我们的Equatable函数。 因此,开发人员将不再需要编写该样板代码。 数组的条件一致性 以前,我们无法像上面的areArraysEqual函数中所示比较两个数组的内容,因为不将Users数组视为Equatable类型。 虽然如果我们比较两个函数数组可能会有意义,但由于函数类型不是Equatable ,而元素类型为Equatable则没有意义。 在Swift 4.2中,我们提供了一个数组扩展名,可以比较两个具有Equatable元素类型的数组。 除了数组之外,可选内容和字典还通过这种新的条件一致性提供了相同的功能。 新的随机数生成器 如果您想在Swift中创建随机数,则必须使用导入的C API,这些API需要进行严格的平台检查。 坦白说,这不是最优雅的解决方案,而要正确解决问题可能会很棘手。 Swift 4.2现在为Floats和Ints提供了新的随机数生成器功能,可以接受一定范围以准确返回随机数。 此外,现在可以从数组中检索随机元素,并且可以分别通过添加randomElement()和shuffled()函数对数组的元素进行混洗。 更多细节 这些是Swift 4.2的主要更改,但这里还没有涉及其他内容,例如新的哈希算法和协议。 如果您想了解Swift的最新功能,建议您访问https://apple.github.io/swift-evolution/以查看正在审查,接受或实施的最新更改。 一如既往,感谢您的阅读和记忆,更少的样板=快乐的开发人员🙂 资源资源 Swift的新功能– WWDC […]

协调员基本教程。 第二部分

在本教程的第一部分中,我总体上讨论了协调器的方法,并展示了一些与实现有关的常见示例。 为了与本文保持一致,请阅读上一部分。 在这一部分中,我想介绍一些使用协调器的极端情况。 我想最有趣的部分是: AppDelegate配置 管理启动选项 深度链接和协调员推送通知处理 我将逐步说明解决方案并进行解释。 如何使用主应用程序协调器配置AppDelegate? 由于所有导航逻辑都移至AppCoordinator,因此AppDelegate变得非常简单。 因此,您需要做的是创建一个协调器,注入rootController并调用start()。 我们希望通过展示一个教程,展示一个身份验证流程,向他们介绍新功能或仅显示主屏幕来向用户介绍我们的应用程序。 我们应该谨慎处理这种行为。 假设我们有3种不同的情况: 用户应查看入门教程(我们将显示入门屏幕) 用户应登录(我们显示登录屏幕) 用户已完成之前的两个步骤,仅看到主屏幕 为了轻松处理所有这些情况,我们创建了一个枚举作为协调者的助手。 该枚举应检查所有标志,并返回协调器应遵循的正确方案。 我将其命名为实体讲师,因为它指示协调员接下来要做什么。 怎么处理呢? 正如您在上一部分中所记得的,我告诉您有关BaseCoordinator的信息 ,其中包含子协调器数组。 所有协调员都继承它。 这意味着我们可以循环所有孩子并执行动作。 为此,我们只需添加一种方法即可处理DeepLink逻辑本身,也可以循环处理子代以找到可以处理它的方法。 它将像一棵树。 我们可以创建特定的协议来实现此目标。 让我们更新协调器协议: 现在,我们将两个带有空主体的方法添加到BaseCoordinator中,以使其保持可选状态。 孩子们可以继承这些方法之一,也可以两种都继承。 在某些情况下,可以使用不带选项的start来运行默认行为,但是如果继续进行深层链接方案,则应添加有关演示案例的信息。 如何实现呢? 更好的方法是在项目中添加一些实体,其中包含所有深层链接快捷方式,并创建可以使用start()方法发送的对象。 你想念枚举吗? 让我们添加一个新的! 它将是DeepLinkOption: 好处是,协调器中所有的DeepLink方法都将像切换为枚举一样。 是的,与上一个示例中的Instructor相同,您是正确的。 我们可以根据需要添加一些其他的build方法(带有…): 在此迭代之后,如果我们返回AppDelegate并对其进行一些更新,它将看起来像这样: 好了,看起来不错吗?🤔然后您将收到一个推送通知或深层链接,您只需构建您的DeepLink并通过AppCoordinator进行此操作即可。 结论 在我们尝试在代码中实现的每个新解决方案中,我们都面临着很多极端的情况,并且还面临着一些不太漂亮的解决方案。 它不应该像炒作那样驱动开发,我们只需要逐步改进所有棘手的部分即可。 如果您有任何疑问或新的特定问题,请随时给我写信。 并检查整个实现的Github回购。

在iMessage中创建看起来像聊天气泡的聊天气泡-高级方式

本文是有关创建(iMessage样式)聊天气泡的两篇文章的第二篇。 第一篇文章在这里可用。 在本教程中,我们将介绍创建带有尾巴的聊天气泡的高级方法。 本教程是使用Swift 4.1和Xcode 9.2创建的。 源代码在Github上可用。 本教程将教您如何创建带有尾巴的聊天气泡,看起来像iMessage中的聊天气泡。 但是本文不是关于创建一个成熟的聊天应用程序的。 我将专注于如何以高级方式创建动态大小的气泡。 开始吧! 我们将创建一个UIBezierPath实例,它看起来像一个聊天气泡 并根据我们内容的大小调整此路径的大小 我们将使用boundingRect(with size: CGSize, options: NSStringDrawingOptions = [], attributes: [NSAttributedStringKey : Any]? = nil, context: NSStringDrawingContext?) -> CGRect String实例的boundingRect(with size: CGSize, options: NSStringDrawingOptions = [], attributes: [NSAttributedStringKey : Any]? = nil, context: NSStringDrawingContext?) -> CGRect方法来计算文本内容的boundingRect(with size: CGSize, options: NSStringDrawingOptions = [], attributes: [NSAttributedStringKey […]