Tag: iOS应用开发

为什么您应该在没有情节提要的情况下开始学习IOS。

前一段时间,当我开始学习IOS开发时,我总是使用情节提要来构建UI,就像任何初学者一样,这里有自动布局和约束之类的概念以及我无法掌握的其他内容,我起初很挣扎,但随后您就可以掌握它了。之后,我问了我的一个以IOS开发为生的朋友,他为我提供了一些有关编写更好代码的建议,以谋生为生。 他建议我不要使用情节提要,不要用代码编写所有内容。 从那里开始,我开始在网上搜索,结果证明这是IOS开发人员之间的一个大争议。 只是要记住,NIB和XIB是描述用户界面的文件,并且是使用Interface Builder构建的,它们已替换为情节提要,但仍可以在开发中使用。 即使许多开发人员坚持使用一种方法,您也可以将所有方法都应用到同一项目中。 我认为从代码开始可以使您更好地了解swift,并更好地了解IOS开发。 最重要的部分是何时使用这三个选项之一,构建简单而快速的内容对故事板有帮助,您甚至可以在其中制作一个快速原型来快速完成工作,如果您必须复杂的UI或更好地掌握您可以使用代码编写它。 永远记住一些事情 不管您使用什么,重要的是完成产品并为您的客户提供最佳的用户体验。

在表格视图单元格上创建流畅多彩的缩放过渡

动画很棒。 iOS用户喜欢使用具有沉浸感和流畅动画的出色应用程序。 这是我作为该平台上的iOS开发人员的第一篇文章,我想向您解释我对当前正在从事的项目的认识。 想象一下这样的对象列表,或者更好的是UITableView : 简单,清晰,并且对本教程来说最重要的是单色单元。 如果通过点击这些单元格之一来扩展它并转到具有相同颜色背景的另一个视图控制器,那将不是很好吗? 我真的是这样 在本教程中,您将实现它。 因此,让我们打开一个新的Xcode项目并开始编码 让我们从创建带有交替彩色单元格的UITableView开始,我将选择红色和蓝色。 在您的项目中打开ViewController.swift并添加此方法。 如您所见,我将代码放入ViewController.swift的私有函数中,并且由于设置了委托和数据源,因此编写了扩展程序来处理所需的方法。 我在viewDidLoad()中调用setupTableView ()。 这是您在运行项目时看到的: 这是UITableView的非常简单的实现。 但是我不喜欢那些颜色,那些分隔物和那些大的单元格。 我开始以这种方式删除分隔符: tableView.separatorStyle = .none 然后,我认为我们应该为单元格添加一个单独的类。 一切都会变得更加复杂。 转到“ 项目导航器”,“新文件”,“可可接触类” 。 输入“ ColorfulTableViewCell”并使其成为UITableViewCell的子类。 创建文件。 现在,您应该拥有以下内容: 我们希望我们的单元格像我在故事开始时所展示的那样。 我们需要卡片视图样式。 我在类中声明了一个var并创建了图形: 看一下setupGraphic()的前两行。 我需要一个清晰的背景,因为我想使用一个漂亮的卡片视图,并且我还需要一个.none selectionStyle,因为我不需要它。 确保您的ColorfulTableViewCell类是这样的,然后再次打开ViewController.swift进行一些小的更改。 在setupTableView()中,您必须为单元格注册另一个类。 不再是UITableViewCell.classForCoder(),而是新的UITableViewCell.classForCoder()。 tableView.register(ColorfulTableViewCell.classForCoder(),reuseIdentifier:“ ColorfulCell”) 像这样编辑numberOfRows和cellForRow : 现在,我们要使用自定义单元格类,我们将使用其中的五个。 现在您可以再次运行,您应该可以看到以下内容: 让我们添加一些很酷的颜色。 我建议您在coolors.co上找到这5个。 这是一个很棒的免费网站,可让您生成随机的颜色组合。 让我们获取RGB并将其添加到代码中。 现在,在ViewController.swift中,我们必须创建一个数组(我称其为“ coolColors”),以包装这些颜色并在cellForRow()中轻松使用它们。 一旦使用它们并运行,您应该会看到以下内容: 现在,我们有了丰富多彩的“ cardy”表视图💕。 […]

60面试问题每个iOS开发人员都应该知道。 (第1部分)

在这第一篇博客文章中,我试图介绍有关ObjectiveC的简单问题。 所有问题的答案均​​来自多个来源。 如果您对以下任何问题有更好的答案,请将其作为评论发送。 (此博客的版权归所有在多个博客,QnA网站和Apple Developer文档中提到这些答案的开发人员所有) 1.解释什么是Objective-C协议。 协议声明了任何类都可以选择实现的程序接口。 协议使通过继承关系远的两个类彼此通信以实现某个目标成为可能。 在这里阅读更多。 2.解释协议的类型。 正式协议声明了客户端类应实现的方法列表。 正式协议具有自己的声明,采用和类型检查语法。 您可以使用@required和@optional关键字来指定其实现是必需的还是可选的方法。 子类继承其祖先采用的正式协议。 正式协议也可以采用其他协议。 正式协议是对Objective-C语言的扩展。 非正式协议是NSObject上的一个类别,它隐式地使几乎所有对象都采用该协议。 (类别是一种语言功能,使您可以将方法添加到类中而不对其进行子类化。)在非正式协议中实现方法是可选的。 在调用方法之前,调用对象将检查目标对象是否实现了该方法。 在Objective-C 2.0中引入可选协议方法之前,非正式协议对于Foundation和AppKit类实现委派的方式至关重要。 3.解释什么是#import。 #import确保文件只包含一次,因此您不会遇到递归包含的问题。 4. Objective-C中的#import和#include有什么区别? 导入是包含的超级集,它确保文件仅包含一次。 这样可以避免递归包含。 关于“”和。 在本地目录中搜索“”,<<用于系统文件。 5,Objective-C中类别的用途是什么? 通常,您可以使用类别将方法添加到现有类中,例如Cocoa框架中定义的方法。 所添加的方法由子类继承,并且在运行时与类的原始方法没有区别。 您还可以使用自己的类的类别来:将自己的类的实现分发到单独的源文件中-例如,您可以将一个大类的方法分组为几个类别,然后将每个类别放入一个不同的文件中。 声明私有方法。 #import“ SystemClass.h” @interface SystemClass(类别名称) //方法声明 @结束 6.类别的局限性和问题? 优点:您可以扩展没有源的任何类,甚至那些类。 例如,查看Apple添加到NSString类的UI扩展,以进行渲染,获取指标等。由于您可以访问所有实例变量,因此类别为您提供了一种使用逻辑在跨编译单元的结构化代码的好方法分组,而不是例如Java采取的“必须全部在一个物理位置”进行分组。 缺点:您不能安全地覆盖该类本身或另一个类别已经定义的方法。 7.说明何时使用NSArray和NSMutableArray。 哪一个更快且线程安全? NSArray及其子类NSMutableArray管理称为数组的对象的有序集合。 NSArray创建静态数组,NSMutableArray创建动态数组 在这里阅读更多。 8.什么是快速枚举? 该对象通常是诸如数组或集合之类的集合。若干个Cocoa类(包括集合类)采用NSFastEnumeration协议。 您可以使用它来检索实例持有的元素,其语法类似于标准C for循环的语法,如以下示例所示: NSArray * […]

托管持续交付的iOS应用程序的ipa和dSYM文件

通过持续交付,可以在产品所有者准备就绪并获得批准后立即频繁发布新功能。 连续交付管道应该能够分析,构建,测试,存档并将iOS应用程序部署到iTunes Connect。 在上一篇文章中,我们已经看到了如何使用Fastlane工具设置基本管道。 作为存档步骤的一部分,部署到iTunes Connect的每个iOS版本都会创建一个.ipa文件,而dSYM文件是一个“调试符号文件 ”。 这些是在构建过程中生成的非常重要的构建工件,可用于返回到iOS应用的早期版本。 将这些IPA文件托管在某个位置非常有用,这样我们就可以轻松访问iOS应用的早期版本。 在本文中,我们将看到将IPA文件托管到GitHub或类似托管服务器的自动化方法。 您可能想知道为什么我们需要在服务器上托管已发布应用程序的IPA文件。 在某些情况下,方便使用IPA文件 如果需要,轻松安装以前版本的iOS应用 由于源代码的构建可能会因Swift版本或其他依赖项的更改而失败,并且在过去发布应用程序时开发人员可能没有相同的环境。 IPA文件是通用二进制文件,因此可以部署到iPhone和iPad。 对于Xcode Server,Jenkins,TeamCity等自托管CI服务器,Continuous Integration服务器是托管IPA文件的最佳位置,但是对于TravisCI和CircleCI等云托管CI服务器,我们需要在其他地方托管IPA文件。 这是因为基于云的CI服务器会为每个构建启动新的VM,并且在构建完成后会销毁VM。 除非将其上传到其他服务,否则我们可能会丢失IPA和其他构建构件。 有几种选择,我们可以托管我们的构建工件,例如测试报告,IPA文件dSYMS等。 用于自托管解决方案的Continuous Integration Server AWS S3存储桶或类似第三方服务(例如Artifactory) 的GitHub 公司内部服务器 有自托管CI服务器(如Apple的Xcode Server),其他开源CI服务器(如Jenkins,TeamCity等)。自托管CI服务器的好处是我们无需找到其他任何地方来托管构建工件。 除非我们删除它,否则它在CI服务器上已经可用。 有时,在这种情况下,我们需要清理CI服务器,我们需要将发布版本的构建工件移到同一服务器上的任何其他位置。 在这两种情况下,我们都可以访问IPA文件和dSYMS。 带有Xcode 9的最新版本的Xcode Server具有一项新功能,它将创建和IPA文件,这些文件可以从Xcode Bot中看到。 我在之前的博客文章“ Xcode Server + Xcode 9 =全面的iOS CI”中分享了Xcode Server的新功能。 使用Xcode Server,可以轻松地访问发布漫游器的IPA文件。 同样,我们可以将它们放在Jenkins或其他CI服务器上。 如前所述,从基于可能的CI服务器访问构建工件将具有挑战性,因为已经为每个构建启动了新VM,并在构建结束时将其销毁。 我们必须使用脚本将生成的构建工件上载到其他一些服务,例如AWS或类似服务。 我们可以使用Fastlane set_github_release操作轻松地将资源上传到GitHub。 我们可以结合一些Fastlane动作来实现此目的: $ […]

Swift并行编程:操作

在Swift的并行编程:基础知识中,我介绍了许多低级选项来控制Swift中的并发。 最初的想法是在一个地方收集我们可以在iOS上使用的所有不同类型的方法。 但是在编写该指南时,我意识到有太多方法可以在一篇文章中列出。 因此,我决定减少高级方法。 我在上一篇文章中确实提到了操作,但是让我们更仔细地研究它们。 操作队列 让我们回顾一下:运营是Cocoa在GCD上的高级抽象。 准确地说,它是dispatch_queue_t的抽象。 它使用具有可在其中添加任务的队列的相同原理。 对于OperationQueue,这些任务是Operations。 在执行操作时,我们需要知道它正在运行的线程。 与往常一样,如果要更新UI,则需要MainOperationQueue。 操作在其生命周期中会经历不同的阶段。 当添加到队列中时,它处于挂起状态。 在这种状态下,它将等待其条件。 一旦所有这些都满足,它将进入就绪状态,并且如果有空闲插槽,它将开始执行。 完成所有工作后,它将进入完成状态,并将其从OperationQueue中删除。 在每种状态下(“完成”除外),均可取消操作。 消除 取消操作非常简单。 根据操作,取消可能具有完全不同的含义。 例如,运行网络请求,取消操作可能导致停止该请求。 在导入数据时,这可能意味着放弃您的交易。 您将负责给出取消的意思。 那么如何取消操作? 您只需调用.cancel()。 这将切换isCancelled属性。 这就是iOS为您服务的全部。 由您决定是否取消并相应地执行操作。 请注意,取消操作会导致它放弃所有条件,并立即开始立即执行以进入完成状态。 进入完成状态是将操作从队列中删除的唯一方法。 如果忘记检查取消标志,即使您取消了操作,也可能会看到正在执行的操作。 另请注意,这容易受到比赛条件的影响。 按下按钮并设置标志需要几微秒。 在此期间,操作可能会完成,并且取消标志不再起作用。 准备就绪 就绪状态仅由单个布尔标志来描述。 这意味着该操作已准备好执行,并且正在等待队列启动它。 在串行队列中,将首先执行进入就绪状态的操作,即使该操作可能位于队列中的位置9。 如果有多个操作同时进入“就绪”状态,则优先级将决定。 仅当一个操作的所有依赖项都完成时,它才会进入就绪状态。 依存关系 这是Operations真正重要的功能之一。 我们可以创建任务,具体说明其他任务必须先执行才能执行。 同时,有些任务可以与其他任务并行执行,但是是后续操作的依赖项。 这可以通过调用.addDependency()来完成。 默认情况下,任何具有依赖关系的操作都将在其所有依赖关系完成后才进入就绪状态。 但是,由您决定取消依赖项后如何继续。 这使我们能够严格命令我们的运营。 我认为这不容易阅读,因此让我们创建自己的运算符(==>)来创建依赖项。 这样,我们可以说,按从左到右的顺序执行操作。 关于依赖项的好处是,它们甚至可以跨不同的OperationQueue。 同时,这可能会导致意外的锁定行为。 例如,您的UI可能会结结巴巴,因为更新取决于后台操作并阻止其他操作。 注意循环依赖性。 […]

容器视图控制器Redux

在上一篇文章中,我讨论了iOS中容器视图控制器与组合相关的用法。 在本文中,我想通过在一个具有协调器和多个内容屏幕的更复杂的应用程序中的插图来扩展该概念。 让我们开始吧! 以防万一您没有阅读上一篇文章,或者只是需要对视图控制器包含进行快速复习,我们将回顾基础知识。 自iOS 5以来,自定义容器视图控制器就已经存在,并且由Apple提供,部分是为了防止他们认为滥用应用程序中的视图层次结构。 当来自一个视图控制器的视图层次结构被“剥离”并放置在另一个控制器的视图层次结构中时,就会发生这种情况。 苹果公司提到这种方法会导致层次结构不一致。 不一致的层次结构会导致外观和旋转方法无法正确转发到层次结构的各个部分,进而导致意外行为和不良的用户体验。 苹果的演讲可以在这里找到: WWDC 2011 —第102节 。 在上一篇文章中可以找到添加子控制器的基本代码。 为了更好地演示容器视图控制器的用法,我创建了一个示例应用程序,该应用程序实现了各种包含方法。 这个应用程序旨在模拟一个真实世界的应用程序,而不仅仅是关注视图控制器的包含。 尽管视图控制器示例有些人为设计,但该应用程序使用视图控制器容器以及流协调器,协议,类扩展,依赖项注入和其他几种应用程序体系结构技术来尝试为视图控制器容器提供更广泛的上下文。 我们将遍历每个屏幕,并探索组成该屏幕的组件。 该应用程序的根视图控制器是一个UITabBarController由四个内容视图控制器组成。 第一个选项卡是自定义ContainerViewController的示例,该ContainerViewController是一个标准视图控制器,用于管理其他两个视图控制器的内容。 这旨在说明两个概念。 首先,一个图像加载视图控制器将图像简单地加载到视图控制器中(从Dave DeLong借来的一个概念)。 ImageViewController用ImageLoader对象初始化,该对象进行网络调用以检索图像。 就是这样,它无所不包,简短而简单。 其次,屏幕的下半部分是ListViewController ,它只是一个UIViewController ,其中包含一个UITableView ,该UITableView从Web加载一些JSON数据。 ListViewController使用ListLoader对象初始化,以进行网络调用以检索数据。 DataSource被分离成单独的ListDataSource,它只是一个Swift对象,用于管理节,行计数和单元格创建。 同样,非常简单明了。 这些控制器中的每一个都使用容器来添加LoadingViewController ,这是一个仅包含活动指示器的视图控制器。 我已经在多个应用程序中使用了此概念,它非常有用,尤其是当您具有自定义活动指示器时。 加载数据后,将删除加载视图控制器。 在ListViewController选择一行将过渡到新的ListDetailViewController 。 该控制器采用像以前的视图控制器一样的ImageLoader对象来加载较大版本的图像。 我们也可以在这里使用图像加载视图控制器,但是我想展示如何覆盖loadView以在视图控制器的代码中提供自定义视图。 此方法在以后的视图控制器中再次使用。 此ListViewController还实现了窥视和弹出动作,这些动作正逐渐成为应用程序中预期的用户体验。 实施此行为时,会发现协调员存在问题。 协调器用于弹出动作,就像用于任何其他导航流一样。 但是,peek直接在ListViewController 。 这与期望协调器模式如何工作相反,因为视图控制器不应该知道任何其他视图控制器。 问题就变成了谁应该处理该视图控制器的销售? 列表视图控制器对协调器的存在一无所知。 我们是否应该将其移到ListViewController协调器中并注入该协调器,以便列表可以请求窥视视图控制器? 我们是否应该考虑将工厂对象出售给窥视实例的视图控制器? 我仍然需要回答这个问题,因为理想情况下,我们希望ListViewController能够基于列表内容显示不同的详细信息屏幕。 在当前的实现中这是不可能的。 该概念由Halide应用程序的Ben […]

iOS 11密码自动填充

密码自动填充是iOS 11的令人兴奋的功能之一。输入密码始终是造成麻烦的原因。 在iOS 11中,您无需记住密码。 就像safari提示输入密码一样,现在您的应用程序可以自动填写用户凭据,并为他们提供更快的登录速度。 如何执行? 在您的应用程序中实现密码自动填充非常简单。 您需要做的就是设置textContentType 用户名和密码文本字段。 userNameTextField.textContentType = .username passwordTextField.textContentType = .password 同样可以在情节提要中完成 QuickType栏 让我们运行该应用程序,看看它在屏幕上的显示方式。 当点击用户名或密码文本字段时,快捷类型栏将显示并带有一个钥匙图标。 单击钥匙图标将要求使用Touch-Id进行身份验证,然后它将列出钥匙串中保存的所有密码。 选择任何密码将填充用户名和密码文本字段。 关联应用和网站 到目前为止,我们还没有告诉应用程序那是我关联的网站。 因此它显示了钥匙串中的所有密码。 现在,让我们关联我们的应用程序和网站。 首先,我们需要将我们的网站域添加到Xcode中的“ 关联域”中。 在Xcode项目设置-> Capabilites->关联域中,添加您的网站域。 现在,您的应用程序知道您关联的网站。 您的网站应确认该关联。 为此,使用以下内容创建一个名为apple-app-site-association的json文件。 { “网络凭证”:{ “应用”:[“ SR9HR505U.com.anilvarghese.pw-autofill”] } } SR9HR505U 是您的 团队ID , com.anilvarghese.pw- autofill是应用程序bundleId。 将此文件添加到您的网站根文件夹或.well-known目录(提供)。 启动应用程序时 iOS使用安全连接在服务器上查找此文件(您必须在服务器上设置SSL)。 应用程序将自动向https://www.example.com/apple-app-site-association发送请求,并在响应中查找您的应用程序bundleId。 您可以通过在运行应用程序时在控制台中检查设备日志来验证设置。 如果一切正常,您将获得“ SiteApproved ”。 现在,我们在应用程序和网站之间建立了双向关联。 启动应用程序,然后注意QuickType栏会在您的键盘上提示您的凭据,以便您单击即可登录。 酷😎。 […]

Belajar Menginstall Aplikasi iOS ke设备Generik,Tanpa开发人员帐户计划

Semua开发人员移动应用程序tentu ingin aplikasi yang dia buat dapat berjalan dengan mulus tanpa kendala di berbagai macam device tujuan。 Namun belum tentu semua开发人员mempunyai kesempatan untuk melakukan建立了aplikasinya menjadi arsip yang dapat disebarluaskan。 在Android上,文件arsip aplikasinya berekstensi * .apk在iOS上,文件arsipnya berekstensi * .ipa Karena judul artikel membahas tentang iOS,Maka langsung saja artikel ini akan memberikan langkah-langkah untuk membuat file arsip * […]

关于新Xcode 9的所有内容都很酷

Xcode的最新版本Xcode 9于今年发布,在开发人员社区中引起了极大的兴趣。 Xcode具有一些时髦的新功能,而旧的功能已被完善,Xcode提供了一些很棒的功能。 以下是它的一些最佳功能- 改进后的新编辑器 :Apple已在Swift中构建了整个Xcode。 它是基于结构的快速编辑器,可让您智能地突出显示和导航代码。 它还包括Markdown的强大支持。 重构:重构内置于编辑体验中,可在Swift,Objective-C,Interface Builder和许多其他文件类型中使用。 超快速搜索 :“查找”导航器返回即时结果。 调试: Xcode 9使您可以通过网络无线调试iOS和tvOS设备(它还将支持iOS 11设备)。 源代码控制: Xcode集成了对GitHub帐户的支持,可快速浏览存储库并将您的存储库推送到云中。 核心ML: Xcode 9带有内置的核心ML编辑器,可让您将一些很棒的机器学习模型集成到您的应用程序中。 这些只是使构建应用程序更加快速,轻松和有效的众多功能中的几个。 查阅此博客文章,详细介绍所有令人兴奋的新功能以及如何使用它们来增强Apple应用程序的开发。 这是在Moveo Apps博客上发布的原始帖子的简短版本。 阅读全文

Swift并行编程:基础知识

大约一年前,我的团队开始了一个新项目。 这次,我们希望利用从先前项目中获得的所有经验。 我们做出的决定之一是使整个模型API异步。 这将使我们能够更改模型的整个实现,而不会影响应用程序的其余部分。 如果我们的应用程序能够处理异步调用,则无论是与后端,缓存还是数据库进行通信都没关系。 它还使我们能够同时工作。 同时,它具有一些含义。 作为开发人员,我们必须了解并发和并行性等主题。 否则,它将使我们陷入困境。 因此,让我们一起学习如何并行编程。 同步与异步 那么,同步处理和异步处理之间的真正区别是什么? 想象一下,我们有一个项目清单。 在同步处理这些项目时,我们从第一个项目开始并先完成它,然后再开始下一个项目。 它的行为与FIFO队列(先进先出)相同。 转换为代码意味着:方法的每个语句将按顺序执行。 代码中的一个示例是简单的回调。 我们可以看到在处理回调之前最后执行的代码。 但让我们想象一下,我们可以同时使用多个工作程序。 他们每个人都将带一个盒子并一直携带。 这会大大提高我们的生产率,不是吗? 由于我们使用多个工人,因此增加的数量与我们拥有的工人数量相同。 只要至少有2名工人同时搬运箱子,他们就会并行进行搬运。 并行是关于同时执行工作。 但是,如果我们只有一名工人并且可能使用更多的工人,会发生什么? 我们应该考虑在处理状态下有多个盒子。 这就是并发性。 可以看作是将A到B的距离分为多个步骤。 工人可以将箱子从A拿到整个距离的中点,然后回到A抓住下一个箱子。 使用多名工人,我们可以使他们所有搬运箱子的距离不同。 这样,我们异步处理盒子。 如果我们有多名工人,我们将并行处理这些箱子。 因此,并行和并发之间的区别很简单。 并行是关于同时进行工作。 并发是关于同时进行工作的选择。 它不必并行,但可以并行。 我们的大多数计算机和移动设备都可以并行工作(由于内核数量的原因),但是您拥有的每个软件肯定可以同时工作。 每个操作系统都提供使用并发的不同工具。 在iOS中,我们拥有默认的工具,例如进程和线程,但是由于其在Objective-C中的悠久历史,因此也有调度队列。 处理 流程是您的应用程序的实例。 它包含执行应用程序所需的所有内容,其中包括堆栈,堆和所有其他资源。 尽管iOS是多任务操作系统,但它不支持一个应用程序执行多个进程。 因此,您只有一个过程。 查看macOS有点不同。 您可以使用Process类产生新的子进程。 它们与父进程无关,但包含父级在创建子进程时拥有的所有信息。 如果您使用的是macOS,下面是创建和执行过程的代码: 苹果公司对上述内容的实施称为“大中央派遣”(简称GCD)。 在iOS中如何处理? 优先继承 优先级反转的解决方案是优先级继承。 在这种情况下,只要线程1被阻塞,就将其优先级交给线程3。 因此,线程3和2具有较高的优先级,并且都可以执行(取决于操作系统)。 3解锁资源后,高优先级又回到线程1,它将继续其原始工作。 […]