通常,在进行编码时,我们的应用程序会遇到很多问题,因此能够识别错误至关重要。 想象一下,您的应用程序需要Internet连接,但没有提供连接,或者您想要检索的数据不再可用,如果有一条消息通知您此用户错误或指出该错误发生的位置,那不是很好。 这是Swift 3中错误处理非常方便的地方。 错误处理不仅限于Internet连接,还可以在整个应用程序中使用。 它是捕获特定错误的有用工具,可以节省时间和麻烦,因此您无需通读数百行代码即可找出问题所在。 If-Else陈述 当我开始使用错误处理时,我无法想到它与if-else语句相比具有相似之处。 您甚至可能会想到为什么我根本需要错误处理。 var fullyFuctional = true func usePhone(){ 如果功能完整{ 打印(“ 100%模式😁”) } 其他{ 打印(“电池电量低😭”) } } 使用if-else语句来识别您的错误有几个问题。 第一个问题是代码的可读性。 想象一下在else块中创建具有更多步骤的复杂函数,找到您的错误可能会感到困惑,我们的else块立即变得肿。 第二个问题是,我们希望尽早通知开发人员我们的功能可能会导致错误。 您可以在上面的示例中看到,如果要在函数上堆叠更多代码,就不会轻易识别错误消息。 使用错误处理 为了开始使用错误处理,我想介绍一下错误协议。 在我们的应用程序中,可能要显示几个错误。 我们需要创建一个符合我们的错误协议的枚举,并列出我们案例中的各种错误。 枚举PhoneError:错误{ 电池不足 电池没电 案例软件问题 案例屏幕问题 } 当我们需要应用程序显示错误消息时,我们可以轻松地引用我们创建的枚举。 接下来,我想通知我,我的函数可以使用throws导致错误。 通过在我的参数后面加上引发 ,则无需编译其余代码即可发现我的错误。 在开始实现其余代码之前,我告诉我的函数识别这些错误。 func usePhone()抛出{ 如果lowBattery { 抛出PhoneError.lowBattery } 如果deadBattery { 抛出PhoneError.deadBattery } 如果软件问题{ 抛出PhoneError.softwareIssue […]
您可以从我的网站上阅读此故事: https://devgenes.com/posts/hero-transitions-with-xcode-10-swift-4-2/ “ Hero是用于构建iOS视图控制器转换的库。 它在UIKit繁琐的过渡API之上提供了一个声明层,使自定义过渡对于开发人员而言是一项轻松的任务。” Hero的GitHub库说。 我已经尝试过多次在Google上搜索,但是找不到任何最新教程。 我决定制作自己的教程。 所以,我们开始。 我通过了安装程序,因为在Hero的文档页面上对此进行了很好的解释。 我们将以代码开始。 我说代码是因为我将近一年没有使用Storyboards。 (感谢@ buildthatapp) 创建简单的UI(没有情节提要) 在“ pod安装”并“打开myapp.xcworkspace”之后,我们要做的第一件事是从Targets-> General-> Deployment Info-> Main Interface中删除“ Main.storyboard”。 如果我们运行该应用程序,它将显示黑屏。 因为我们还没有UIWindow。 (实际上现在是“ nil”。) 因此,让我们弄清楚。 我们完成了。 请让我知道你的想法。 如果您想保持联系,也许只是说“嗨”,您可以使用下面的链接。 谢谢。 Twitter —邮件
这篇文章是关于Rage的,Rage是我们的库,用于抽象iOS中的API实现。 如今,很少有移动应用程序没有API。 因此,我们必须每次为每个新项目创建网络层。 从移动开发的角度来看,我们看到每个后端的实现方式有何不同。 它在很大程度上取决于所选的服务器技术,例如严格且可预测的Java和.net,灵活且不同的node.js,ruby和python。 同时,在处理移动应用程序时,我们始终具有相同的技术堆栈,并且我们希望拥有清晰可预测的代码,每个项目看起来都相似。 世界状况 当您从Android世界过渡到iOS开发领域时,您将不可避免地对这里非常流行的模式感到惊讶。 出于联网目的,Apple的URLSession相当不错,但是许多项目仍使用Alamofire (它是AFNetworking的后继产品) 。 有Moya ,它比Alamofire更高 。 Moya很不错,我们在某些项目中使用了它。 它有充分的文档证明和测试,但是它的枚举滥用语法是我们无法忍受的。 在相同的枚举中,API描述立即变成大量的开关盒。 单个请求的每个参数都在其自己的位置描述,当您尝试了解单个请求的所有内容时,这确实令人困惑。 我们接受Moya的意识形态认可,但这会影响我们的生产力。 有时候,看起来像莫亚(Moya)自己陷入了困境。 Android世界的主要流行词是OkHttp , Retrofit和Moshi 。 没有人质疑他们为什么这么好。 我们也自然希望在iOS中也有这样的事情。 Swift没有我们在Java / Kotlin中常用的注释处理,因此在此处进行直接类似并不容易。 据说, Swift 4解决了JSON问题。 OkHttp为网络请求规范提出了一种不错的构建器样式语法。 Retrofit提出了一种描述请求列表的方法,如何对数据进行序列化/反序列化以及应使用哪个http客户端进行请求。 愤怒 愤怒做了类似的事情。 这是我们的库,使API规范更具可读性和更清晰。 我们努力减少错误,并力争拥有高定制能力。 这就是我们创建Rage的原因 。 我们之所以给该库起这个名字,是因为在使用该库之前在iOS应用中实现API时必须处理的所有事情。 基本上,我们可以将网络层表示为请求描述列表以及有关一般如何发出请求(即客户端)的信息。 客户发出请求。 它知道有关所有请求的常规信息。 每个请求都有其自己的特定参数。 至此,我们为客户端提供了以下参数: 基本网址 基本ContentType URLSessionConfiguration 一些插件,例如记录器 所有请求的标题 请求授权流程说明 这是我们对每个特定请求的要求: 网址 内容类型 […]
最初在 这里 发布在XCBlog上 苹果已经发布了带有Xcode 9.3的新命令行工具xccov,用于检查Xcode代码覆盖率报告的内容。 不幸的是,还没有任何Web文档,因此我们必须在终端中键入man xccov以获得有关此命令行工具的更多信息。 此实用程序需要Xcode 9.3和Xcode 9.3附带的命令行工具。 使用xccov,我们可以使用人类可读格式以及机器可表示格式(例如JSON)生成Xcode代码覆盖率报告,而无需使用第三方工具。 在本文中,我们将探讨如何使用带有演示iOS应用的新命令行实用工具生成和查看Xcode代码覆盖率报告。 注意名字 命令行工具xccov是Xcode 9.3附带的本地Apple开发人员工具。 但是,很少有名称相似的开源工具可能会使您感到困惑。 不是xcov 有一个名为xcov的Ruby库可生成美观的代码覆盖率报告,可与Fastlane和Danger等工具一起使用。 不是hiroakit / xccov 还有另一个纯粹的Swift库可以生成Xcode代码覆盖率报告,也称为xccov,但由Hiroaki ENDOH编写 这些库的名称与Apple发行的新实用程序相似或几乎相似,巧合的是,它们正在执行相同的工作,即为Xcode生成不错的代码覆盖率报告。 随着苹果公司xccov的发布,可能不需要这些库。 生成代码覆盖率报告 为了探索xccov,让我们使用带有单元和UI测试目标的“ Tabbed App”模板创建一个新的iOS应用,并将其命名为“ XCCov-Demo”。 这将创建Xcode项目方案“ XCCov-Demo”。 我们可以通过编辑方案并在“测试”操作中选中“代码覆盖率”框来明确启用该方案的代码覆盖率。 如果我们不想包括UITest的覆盖范围,我们也可以过滤目标,如下所示 现在,我们为方案启用了代码覆盖率。 一旦我们使用Xcode中的CMD + U按钮构建并测试了该方案,这将生成代码覆盖率报告到默认的派生数据目录中,该目录位于〜/ Library / Developer / Xcode / DerivedData中,您将看到在Logs / Test中生成的代码覆盖率报告目录。 但是,对于此演示,我们将在项目内部生成派生数据,以便我们可以轻松查看报告。 让我们使用xcodebuild从项目根目录使用以下命令来构建和测试我们的应用程序 $ xcodebuild -project XCCov-Demo.xcodeproj / -scheme […]
如果您像我一样,则在查看代码时可能会看到这些“ .nib”和“ .xib”文件,并想知道它们到底意味着什么。 即使当我有人向我解释它们时,它们仍然没有多大意义,我也不知道为什么要使用它们。 但是由于这些东西在Swift中似乎比较流行,所以我决定对它们做更多的研究,然后搞一个新的项目,看看我是否能解决。 那么这些NIB和XIB是什么? 出于所有意图和目的,它们是同一件事–可在整个项目中重复使用的自定义视图。 实际上,XIB(XML接口生成器)在编译期间会转换为NIB(NeXTSTEP接口生成器),因为XIB易于人类阅读,而NIB则易于计算机阅读。 为了简洁起见,在博客的其余部分中,我将它们都称为“ XIB”。 好的,看来XIB可以帮助我们直观地创建视图,但这不是Storyboard的目的吗? 为什么使用其他类型的Interface Builder使事情复杂化? 好吧,实际上,XIB和情节提要板有很大的不同,即使它们经常相互结合使用也是如此。 XIB只是一个“事物”(一个自定义的,可重复使用的视图),而情节提要是许多“事物”(ViewController,TableViews,Segues等),主要用于导航和布局。 太酷了,所有这些都在概念上有意义,但是如何将其转化为代码? 我有同样的问题,它实际上对我自己的项目有很大帮助。 因此,我创建了一个(伪)音乐库,该库将在TableView中显示,并使该单元格成为创建为XIB的自定义单元格。 让我们进入代码… 等等,这不是XIB。 我以为我们正在学习如何创建和使用XIB! 是的,这也让我感到困惑,但实际上,我们首先需要创建一些东西,以使我们的XIB有意义。 由于我的应用程序要在音乐库中显示歌曲,因此我创建了一个Song结构(非常基本)以及一个MusicLibrary结构来保存我的所有歌曲: 现在我们有了一些基础集,我们实际上可以创建我们的XIB。 为此,您可以创建一个新文件并选择“查看”。这将带您进入一个新屏幕,如下所示: 对您来说,这应该看起来有些陌生,几乎就像一个情节提要。 尽管您可以使用许多与Storyboard相同的工具,但仍存在一些主要差异。 如您所见,主要的是XIB文件默认为视图,而不是ViewController。 不要被默认矩形形状与ViewController相同的事实所迷惑-实际上,让我们通过选择“大小”下的“自由形式”和“状态栏”下的“无”来改变它。更改自定义视图的大小,在我的情况下,我希望它是TableView Cell的大小(在Storyboard中查看以查看原型单元的大小)。 那里看起来好多了。 但是现在我们还需要将此XIB链接到代码中的某些内容,因此让我们使用UIView类(通常与XIB文件具有相同的名称)创建一个新文件,不要担心这不会混淆Xcode,因为是.xib,另一个是。swift)。 现在,就像在Storyboard中一样,我们需要创建一个插座以使连接完成。 在情节提要中,我们将从视图对象中执行此操作,对吗? XIB并非如此。 实际上,我们必须从“文件所有者”部分执行此操作: 完成后,我们可以将出口拖到我们的SongView.swift文件中: 现在,XIB变得有些混乱了。 我们可以通过两种方式初始化自定义视图-通过代码或通过Storyboard。 因此,我们需要两个初始化程序:带框架的初始化(用于代码)和带编码器的初始化(对于Storyboard): 但是,无论我们如何初始化视图,本质上我们都希望它以相同的方式进行设置,因此让我们创建一个可以为我们完成此操作的函数: 那里发生了什么事? 好吧,首先我们需要使用文件名实际加载XIB。 然后,我们要告诉Xcode我们希望自己设置约束,这就是“ translatesAutoresizingMaskIntoConstraints = false”行的作用。 下一行虽然很容易编写,但是起初有点复杂。 请记住,我们上面创建的SongView类本身就是一个UIView,而我们刚刚为其(我们的contentView)创建一个出口的视图也是一个UIView。 我们想将此contentView添加到SongView中,因此我们使用addSubview(contentView)。 我喜欢将其视为图层-SongView是我们的底层,而contentView现在位于其顶层,因此无论我们在何处添加SongView,contentView始终都在其中。 之后,我们只需添加约束以确保contentView始终约束在SongView的边缘。 ! 好的,现在已经完成了很多繁重的工作,我们可以通过设置我们想要的实际视图看起来像什么来获得一些乐趣: 看起来不错。 […]
苹果已经发布了Xcode 8.1 GM-这是新版本中的新增功能和改进功能: 快速更新 将C和Objective-C代码导入Swift时,将定义一个新的宏__swift__。 该宏的值的格式为XYYZZ,其中X是语言的主要版本,YY是次要版本 语言的版本,而ZZ是“补丁”版本(YY和ZZ始终为两位数)。 Swift标准库中添加了两种类型:UnsafeRawBufferPointer和UnsafeMutableRawBufferPointer。 它们表示固定内存区域(缓冲区)上的非所有视图。 它们将底层缓冲区公开为UInt8字节的集合,而与该内存中保存的值的类型无关。 一个新的withUnsafeBytes(of :)函数将值的内存表示形式公开为UnsafeRawBufferPointer。 Swift标准数字类型现在作为NSNumber桥接到Objective-C。 NSValue类为其提供工厂方法的结构现在作为NSValue桥接到Objective-C。 由乔·格罗夫(Joe Groff)建议。 当Optional值桥接到Objective-C对象时,当Optional传递给采用非空ID的API或[T?]数组桥接到NSArray时,如果有一个值,Swift运行时将桥接已包装的值。 如果桥接了nil值,并且API不接受nil指针,则Swift将使用NSNull。 由乔·格罗夫(Joe Groff)建议。 快速修复 Swift 3.0.1现在生成一个const UnsafePointer而不是UnsafeMutablePointer。 现在可以正确处理C属性swift_error(zero_result)。 覆盖和满足协议要求的成员的访问检查已修复为与SE-0025更紧密匹配。 如果需要保持Swift 3代码与Xcode 8.0兼容,请对顶级类和结构使用private而不是fileprivate。 解决了使用@NSManaged属性来满足协议要求的问题。 Objective-C更新 现在,使用“手动引用计数”的Objective-C文件支持__weak引用,而不是忽略它。 您需要在项目设置中启用它,否则将触发编译器警告。 核心数据更新 现在,在创建新实体时,Xcode 8将为实体名称和类名称设置相同的值。 更改实体名称也将更改类名称,除非它们已经不同。 核心数据修复 使用自动代码生成保存后,现在可以对数据模型进行更改。 界面生成器更新 新的“更新框架”按钮将更新所选对象及其子对象的框架。 固定按钮已重命名为添加新约束。 自定义手势识别器已添加到对象库,以允许继承UIGestureRecognizer或NSGestureRecognizer而不是使用NSObject。 界面生成器修复 修复了使用重力区域分布的NSStackView的自动布局性能。 解决了布局不明确时Xcode不能始终从情节提要和xib恢复视图帧的几个问题。 现在,您可以解决歧义,并且Xcode将继续存在。 将内容拖动到画布上的静态UITableView单元中,将再次起作用。 创建IBAction连接不再使用Swift 2.3插入WithSender。 在非视网膜上的设备栏中选择横向方向 在OS X 10.11上运行时显示的内容现在将不再挂起。 调试修复 […]
你好! 我叫Vladyslav Semenchenko,我是iOS开发人员。]这是我在Medium上的第一篇文章,欢迎您! 几周前,我开始了新的iOS项目。 经过几天的编码,我遇到了问题-我的UIViewController类为动画提供了太多代码。 按照我的计划,这还不错,但是对于干净的代码也不是很好。 我希望我的UIViewControllers仅具有用于用户交互的代码,也许还有一些基本设置。 所有其他逻辑必须在工作程序中。 这对于可测试性非常有用。 所以我的问题是:如何将动画移到UIVIewController之外,并使其易于使用和理解? 我想到的第一件事是为动画创建单独的类,并在UIVIewController外部调用函数。 让我们看看它是如何工作的。 好的,让我们假设我们有IntroductionViewController。 首先,让我们看一下它的外观如何: 我们可以将该对象添加到ViewController中,设置动画类Custom Class,然后链接所需的变量。 让我们尝试这样做! 首先将对象添加到ViewController中: 然后为对象设置自定义类: 现在,您可以将UI元素拖放到动画类中: 另外,您必须将动画对象与ViewController链接。 只需Ctr将Animation Object拖动到ViewController并设置插座名称即可。 这是InitialViewControllerAnimation类的最终版本: 现在是最后的ViewController类: 清洁得多吧? 我们解决了两个问题: 1)将动画块移出ViewController类之外 2)将动画类所需的外部变量移到ViewController类所需的外部变量 希望本文对读者有所帮助。 请留下您的评论。 与社区讨论此问题将很酷! PS我几天前发现的很酷的歌曲:齐柏林飞艇(Led Zeppelin)-自从我一直爱着您-https://itun.es/ru/F-imO?i=674271721
最近,有一位朋友告诉我,在最近的一次采访中,有人问她有关Notification的经历。 我认为稍微研究一下会很有用。 我了解到的一件事是,通知中心(以前称为NSNotificationCenter)适合观察者设计模式,该对象在其中将任何更新或更改通知其他对象。 Apple的文档指出,“ NSNotificationCenter对象(或简称为通知中心)提供了一种在程序内广播信息的机制。”换句话说,Notification就像广播消息的广播电台一样。 这样, 发送者 (广播者或广播电台)发出消息, 观察者 (听者)可以决定何时收听以及收听什么内容。 基本上,通知提供了一种在应用程序内传递信息的方法,而类之间没有直接引用。 通知中心会跟踪关注特定通知的所有不同类型的观察者,因此在发布通知时,通知中心会将消息发布到已为该通知注册的每个观察者。 要设置通知中心,需要3个步骤: 步骤1:将事件(消息)发布到通知中心,该事件将通知要侦听此特定消息的所有对象。 步骤2:将观察者(侦听器)添加到通知中心。 步骤3:编写一个代码块,该代码块在发生通知时被调用(收到通知后您将要做什么?)。 我制作了一个带有标签栏控制器的简单应用程序。 标签1:显示随机的海洋图像。 选项卡2:如果用户喜欢选项卡1中的图像,则选项卡2将向他们显示另一个随机海洋图像。 在上面,我向NotificationCenter.default发布了一个名为“ LikedItNotification”的通知。一旦用户单击FirstViewController中的 Like Like按钮,该通知就会被发布! 在上面,我为在FirstViewController中创建的通知创建了一个观察者(侦听器)。 我还编写了将在收到通知后执行操作的代码。 在这种情况下,我的操作是取消隐藏youLikedItLabel并将随机图像分配给SecondViewController中的imageView。 埃里卡(Erica),如果您在想,我觉得您可以通过使用单例来做类似的事情,您是对的。 看来NotificationCenter只是让您的班级互相交谈的另一种方式。 我的理解是,如果整个应用程序需要了解特定的通知(即显示键盘,用户确实登录/注销),则可以最佳地利用NotificationCenter。 这是我完成的应用程序的演示视频! 希望您今天了解到有关NotificationCenter的新知识。 您可以在此处下载项目。 资源: Apple文档— NSNotificationCenter 视频— Swift 3中的iOS通知中心 停止使用NSNotificationCenter Ray Wenderlich — iOS设计模式:观察者模式
Segues是一种有用的导航模式,在iOS上用于在视图控制器之间进行转换。 这篇文章将展示如何在许多常见用例中有效地使用与segue相关的代码。 使用segues的一个主要好处是,从源视图控制器到目标视图控制器的过渡可以完全在情节提要中进行编码,并且不需要任何代码即可管理演示。 一个例外是需要自定义序列,例如自定义表示控制器时—详情请参见下文。 任务创建和准备 给定一个带有带有按钮的源视图控制器的情节提要,只需选择按钮并按住CTRL +拖动到目标视图控制器,即可创建到目标视图控制器的简单序列: 如果需要,可以在源视图控制器类中重写prepareForSegue方法,以配置目标视图控制器,如下所示: 假设我们的数据源是一个项目数组,并且我们想为目标视图控制器配置与所选单元格的indexPath相对应的项目。 由于segue是从表视图中的某个单元格触发的,因此prepareForSegue中的sender对象将是该单元格本身,并且我们可以将它的indexPath检索为tableView.indexPathForCell(cell)并使用它来引用我们的数据源数组。 例: 然后,我们需要像这样实现UIPopoverPresentationControllerDelegate的adaptivePresentationStyleForPresentationController方法: 摘要 利用情节提要板来定义应用程序的导航流程,并遵循以下规则将代码链接到您的任务上: 重写prepareForSegue方法以在显示目标视图控制器之前对其进行配置。 当通过点击按钮或单元格执行搜索时,请在源视图中直接挂钩到按钮/单元格。 有条件地执行segue时,将其挂接到源视图控制器,如果条件评估为true,则调用performSegueWithIdentifier 。 对于表视图和集合视图,使用indexPathForCell获取为prepareForSegue中的数据源建立索引所需的indexPath 。 选择Present as Popover选项,并实现adaptivePresentationStyleForPresentationController方法以返回UIModalPresentationStyle.None,以在iPhone 上将 segue呈现为弹出框 。 参考文献 Apple Docs:故事板Segues PSPDFKit博客:演示控制器和自适应演示 注意 :此故事 最初 于2016年1月25日 发布在我的博客 上。 有关更多此类故事,请 订阅我的邮件列表 。 如果您喜欢,请单击下面的so,以便其他人在中此看到此内容。
在我最近的iOS项目中,我有一个视图,其中内容显示为垂直可滚动的卡,并且每个卡都可以扩展以显示更多详细信息。 我已经将整个解决方案建模为UITableView ,其中每个单元格包含垂直堆叠的子视图(由于iOS 8的支持,我无法使用UIStackView ),并且每个子视图都使用其自己的视图模型进行了初始化(但这只是实现细节)。 在最终视图中,层次结构看起来类似于下图。 通过单击“ 更多和更少”按钮,“ 描述”字段在短文本和长文本之间切换。 从iOS 8开始,UITableView提供了一种自动管理UITableViewCell高度的简便方法,而无需手动计算并为每个单元格提供高度。 通过将行高设置为自动并提供估计的行高来完成 tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 124 您只需要确保设置正确的约束即可,这意味着,例如,如果UILabel正确计算了其大小,便可以将其超级视图推到所需的大小。 这意味着您不能例如设置高度限制,最终应该从上到下固定标签。 我的情况非常简单,我只是将UILabel固定在每一侧。 当涉及到动画时,无需考虑高度就非常简单。 您只需更新文本并设置动画大小即可。 因此,代码如下所示: //细胞 @IBAction功能按钮MoreTouched(_发送方:UIButton){ labelDescription.text = longText 委托?.contentDidChange(cell:self) } //代表 扩展TableViewController:CellDelegate { func contentDidChange(cell:Cell){ UIView.animate(withDuration:1){ self.tableView.beginUpdates() self.tableView.endUpdates() } } } 结果是有效的,但存在一些缺陷。 文本立即更改,整个表格都具有动画效果。 但是,文本在垂直方向居中,在我看来,这不是故意的。 我想实现“更多显示”行为。