Tag: swift

使用Swift偷窥iOS 11拖放API

iOS 11带来了许多新的API。 这使我们能够使用户与应用程序的交互更加直观和愉快。 但是一个功能无疑引起了我的注意,它是不同应用程序之间的拖放。 我认为这是用户一次与多个应用交互的方式的改变者。 实现此功能似乎很困难,但我想向您保证并非如此。 今天,我们将构建一个简单的移动应用程序,允许用户将图像从任何应用程序拖动到我们的应用程序。 首先,您需要Xcode 9,可以从Apple官方网站下载。 如果您决定测试我们要在真实设备上构建的应用程序,请确保该应用程序可在iOS 11上运行。我们不会创建任何其他元素,我们将使用默认创建的ViewController类。 为了能够处理此拖放,我们将使用新UIDropInteractionDelegate方法。 您可以在应用程序中使用多种可选方法。 我们将仅需实现3种可选方法,这些方法将帮助我们组织和处理拖放过程: 另外,我们需要确保我们的类符合该新API协议。 我们必须告诉Xcode,我们的视图支持这种交互(图像的拖放)。 为此,只需添加UIDropInteraction并提及我们的ViewController类是此交互的委托: 与我们的视图添加新的交互之后,您的ViewController类应该具有以下内容: 好的,现在我们已经基本设置好一切,可以使我们的应用正常工作。 让我们从“拖放”会话中获取图片,并将其放在视图顶部。 我们将使用第一个委托方法来获取图片并处理Drag&Drop的结尾。 我将向您展示代码,然后将详细描述每个步骤: 现在让我们看看我们已经完成了什么: 放下之后,我们可以使用属性session.items访问我们的项目,该属性返回一个数组(因为可能会拖动多个项目)。 因此,我们遍历这些项目。 为了从拖动的项目中获取对象,我们调用itemProvider属性(这是一个仅获取属性),然后调用一个方法,该方法返回带有对象和错误的闭包。 注意:您还必须输入对象的类,在本例中为UIImage.self 然后,通过使用防护结构,我们检查错误是否为nil。 如果发生错误,我们将打印错误消息并退出此方法。 在此关闭中,我们收到了一个可选对象,因此我们必须检查它是否真的是UIImage类。 我们使用防护结构来做到这一点。 我们的方法dragItem.itemProvider.loadObject(…)做一些异步工作。 因此,如果我们想使用UI添加工作并将图像添加到视图中,则必须确保在主线程上进行操作。 最后,我们使用图像创建一个UIImageView ,并将此视图作为子视图添加到主视图中。 然后,将其框架设置为与图片的框架相同。 通过使用属性session.location(in: self.view)我们将UIImageView的中心放在手指上。 现在让我们检查一下结果: 我们实现了一项非常强大的新功能-拖放的基本功能。 作为开发人员,您不仅可以处理图像,还可以处理文本,链接等的拖放操作。在计算了用户将对象拖动到何处后,可以将其放在任何可视容器中: UITableViewCell , UICollectionView , UIView等。Apple提供了很多种类的委托方法,使您可以轻松实现此功能。 您可以在此Github存储库中找到所有示例代码。 感谢您阅读🙂

iOS App中的社交服务文件浏览器

社会服务浏览器 是一个库,提供了一种简单的方法来浏览,预览和导入来自外部服务(如Dropbox,Amazon Drive,Google Drive等)的文件。我将其编写为通用代码,可以集成自定义服务,您所需要做的就是实现一些协议方法,仅此而已。 它支持自定义UI /布局,并基于UICollectionViewController,在下面您将找到默认UI的外观。 它最初是为了从外部服务导入文件而编写的,但是我认为这对于预览文件也可能有用,因此在GitHub上找到的示例中,您将找到如何与UIDocumentInteractionController一起使用它 我想尽可能地简单,因此如果您想使用Dropbox,已经有实现预览和导入功能的类。 用法仅限于几行代码: 为了能够实现自定义浏览器客户端,您所需要做的就是从SocialServiceBrowserClient协议中实现方法: 除此之外,您还必须为每个节点(文件/目录)实现SocialServiceBrowserNode协议。 @objc公共协议SocialServiceBrowerNode { var nodeId:字符串? {得到} var isDirectory:Bool {get} var nodeName:字符串{get} var path:字符串? {得到} } 将其与某些外部SDK集成的最简单方法是使用扩展。 我已经为Dropbox创建了示例客户端,并使用了SwiftyDropbox。 在下面,您可以看到使用扩展将其集成起来有多么容易。 SwiftyDropbox返回Files.Metadata节点的集合,他们为文件Files.FileMetadata和目录Files.FolderMetadata创建了子类,但出于我的目的,我为父类创建了扩展。 最后一步是处理SocialServiceBrowserClient协议的方法,这是针对Dropbox客户端完成的方法: 希望不久我们将涵盖每种常见社会服务的实施。 我建议您在此处检查示例和源代码,这些示例和源代码可在我们的GitHub存储库中找到! – 请享用。

可选类型的扩展

嘿大家! 我想写这篇简短的文章,因为我喜欢使用这种技术,它并不是最明显的实现。 因此,如果您在Swift中工作了2分钟以上,那么您可能已经看到Optional了 。 有很多很棒的文章解释了这些东西是什么以及如何使用它们。 我不会在这里讨论。 我想说的是恐惧 表达式从“字符串”隐式强制转换 去任何’ 每次尝试打印Optional时出现的错误。 好的,这不是世界上最重要的用例,但是如果没有它,您的代码将被警告打乱,或者每次执行此操作时都必须将所有内容转换为Any类型。 所以下面的实现: let val:字符串? =无 // … print(val)//警告在这里生成 会成为 let val:字符串? =无 // … print(val as Any) 如果您有很多这样的事情,或者如果val的类型发生变化,那么这将成为一场噩梦。 因此,什么是优雅的修复程序,因为它绝对没有使用String(describing: val) ,这是Xcode中建议的修复程序。 我很高兴你问😁。 为了解决这个问题,让我们在Optional类型上编写一个扩展名,是的,这是完全可能的,而且非常酷! 让我们开始编写以下代码: 扩展名可选,其中Wrapped ==字符串{} 在上一个代码块中,我们扩展了Optional类型,其中Wrapped类型是String 。 Wrapped属性是使用Optional声明(Swift Generics)声明的泛型类型的标识符。 这意味着我们在此扩展中编写的任何代码仅可用于可选的字符串类型( String? )。 因此,让我们实现我们的扩展。 在下一个代码块中,我们将添加一个名为valueOrEmpty的新属性。 这是代码: 扩展名可选,其中Wrapped ==字符串{ var valueOrEmpty:字符串{ 守卫让自己解开=自我否则{ 返回“” } 退回包装 } […]

我对Xcode 10感到兴奋的7个理由

我们都在工作到很晚的时候打开了Xcode,并且被界面所蒙蔽。 我的眼睛仍然没有原谅我。 幸运的是,Xcode 10可以通过新的黑暗模式防止这种情况。 2.多行编辑 这是我最喜欢Atom的东西之一。 它使您可以快速快速地真正编辑多行。 按⌥+↓+⇧或CTRL + down + shift 。 3.侧面栏中的Git更改 我很高兴Xcode采纳的另一个Atom功能是边栏中的git changes。 在必须打开“源代码控制”面板然后浏览所有更改之前,打开文件并查看所做的更改很酷。 这使得管理git更容易。 4.翻页 另一个Atom插件功能! 过度滚动似乎没什么大不了的,但是使用完后就无法返回。 5. CreateML游乐场 今年夏天初,我写了一篇关于如何使用TuriCreate创建自己的CoreML图像分类器的方法,这非常简单,但是现在您可以在Xcode Playgrounds中创建CoreML模型。 基本上,只需拖放即可弹出CoreML模型,准备在您的应用程序中使用。 观看此WWDC视频,以了解有关在Xcode Playgrounds中使用CreateML的更多信息。 介绍创建ML – WWDC 2018 –视频– Apple Developer Create ML是一个新框架,旨在帮助您使用Swift和Xcode轻松构建机器学习模型。 设计… developer.apple.com 6.改进的SceneKit编辑器 如果您使用ARKit或Scenekit,这将帮助您节省大量时间。 还有很多选项可以显示诸如线框 , 边界框 , 骨架等内容。 3D设计师欢欣鼓舞! 7.代码折叠色带 这不是我每天都会使用的东西,但是我认为代码在调试大型函数或进入地狱时确实很有用。 跟我来了解有关Xcode,Swift和iOS开发的更多提示 改善Xcode工作流程的提示 Xcode是创建iOS应用的绝佳工具,但有时可能会有些笨拙,并会拖慢您的工作流程。 这里… medium.com

执行任务所需的循环语句需要重复特定的次数。

循环(For,ForEach,While,do…while) 执行任务所需的循环语句需要重复特定的次数。 假设,如果您要打印从1到10的数字,可以不执行循环操作,如下所示。 NSLog(@“ 1”); NSLog(@“ 2”); NSLog(@“ 3”); NSLog(@“ 4”); NSLog(@“ 5”); NSLog(@“ 6”); NSLog(@“ 7”); NSLog(@“ 8”); NSLog(@“ 9”); NSLog(@“ 10”); 在这里,您要编写10次NSLog语句以打印从1到10的数字。这里可能出现循环,因此您可以执行重复的任务而无需多次编写相同的代码。 为循环 For循环的语法 for(初始化器;条件表达式;循环表达式) { //要执行的语句 } 使用For循环打印1到10之间的数字 对于(int i = 1; i <= 10; i ++) { NSLog(@”%d”,i); } 输出 : 第一次i = 1,因此它将打印1并将i值增加+1 第二次i = 2,因此它将打印2并将i值增加+1。 当i值达到10时,它将打印10并将i的值增加1,因此i为11,11 <= 10将不被满足,循环将中断。 让我们看看如何使用FOR […]

#if在动态环境中工作#endif iOS中的App Environment抽象

2.问题 在谈论包括多个后端和应用程序环境的开发设置时,配置将成为救生员,并且是一种设置和构建满足多种需求的应用程序的好方法。 当我们开始考虑明确设置应用程序环境的主要原因时,就会出现问题。 他们注定会有所不同! 这意味着Alpha版本应该与Beta版本有所不同,并且可以肯定的是, Debug和Release之间存在有意义的区别。 只要与其他API URL或某些资产有关,就可以了。 但是,如果它们提供的实际功能有所不同,则可能适得其反。 我确定您至少看过一次此代码: #if调试 // 做点什么 #其他 //做其他事情 #万一 还算不错。 请记住,在大多数情况下,除非您开始归档或在Release中构建,否则将不检查#else之后的代码。 因此,它已经失去了一些编译时安全性。 考虑到这一点: #if调试 //调试流程 #elseif AlPHA //被认为是Alpha流程 //但是有一个错字,编译器永远不会突出显示 #elseif测试版 // Beta流 #其他 //应该是Release,对吗? //除非我们添加了更多配置 //忘了处理它们 #万一 从理论上讲,它可以在代码的许多地方发生。 每个添加/删除配置都可能需要重新访问这些位置,然后重新检查流程。 没有编译器的帮助,代码很快变得难以维护。 另一个主题是单元测试-编写有趣的测试。 我有🙂 3.环境抽象 我在许多不同的项目中都在为这个问题而苦苦挣扎。 不管功能切换的好坏,我经常以类似以下内容结束: 公共枚举环境:字符串{ 案例调试 案例测试版 案例发布 公共静态var当前:环境{ #if调试 返回.debug #elseif测试版 返回.beta #其他 返回.release #万一 } […]

使用EasyPeasy III掌握自动版式:关系

到目前为止,您已经掌握了材料,您必须对EasyPeasy的工作方式,其语法和自动版式的基础知识有很好的了解。 关系允许您根据其他视图的约束来放置视图或调整视图的大小。 例如,将一个视图放置在另一个视图的左侧10px ,或将宽度设置为等于另一个视图的宽度。 职位关系 在上面的屏幕截图中,我们在标题下方放置了一个20px的按钮。 为此,您只需要创建一个常量为20.0的Top属性,并按如下所示指定关系: 现在,该关系在button Top属性和header Top属性之间。 .to方法接受第二个参数,您可以实现此目的。 现在,我们的蓝色按钮看起来有点肿,这是因为我们指定的height等于标题的height 。 header宽度为320px而button宽度为160px 。

IOS面试常见问题解答(2018年9月)第2部分

iOS最新面试题 在本文中,我要向iOS开发人员添加最近问到的新问题,让我们开始吧。 Q1。 什么是NSZombie? 当您的iPhone应用程序因“错误访问”而崩溃时,您将遇到麻烦–内存错误,您试图在已删除的对象上调用方法。 Instruments拥有对NSZombie的支持-通过向您显示导致崩溃的对象的每个分配,保留,释放和自动释放的完整历史记录,可以轻松地找到错误的来源! 哇。 它是内存调试的辅助工具。 具体来说,当您设置NSZombieEnabled时,只要对象达到保留计数0,而不是将其释放,它就会将自身变形为NSZombie实例。 每当此类僵尸收到消息时,它都会记录警告,而不是以无法预测的方式崩溃或行为。 这样,您就可以调试细微的过度发布/自动发布问题,而无需使用高级工具或在干草堆搜索中费尽心思。 这个名称是一个相当明显的玩法,因为当对象达到保留计数0时,它们通常被视为“死”。在这种设置下,它们继续以奇怪的半衰期存在-既没有生命,也没有死亡。 就像真正的僵尸一样,除了它们的大脑吃得更少。 Q2。 什么是线程清理和静态分析? 线程清理程序将帮助您查找数据争用和其他并发错误。 静态分析器已扩展为搜索可定位性问题,检查为空性以及在MRR代码中查找内存泄漏。 Q3。 什么是延期调用? 编写示例代码? 使用libdispatch,计时器的最简单形式是DispatchQueue.asyncAfter 。 这是“延迟调用”的一种形式,它仅延迟函数但不返回引用,因此不提供取消的可能性。 基本的调用after可能看起来像这样: DispatchQueue.global()。asyncAfter(最后期限:DispatchTime.now()+ .seconds(10)){ //一些延迟的代码 } Q4。 什么是调度源? 调度源是一种基本数据类型,可协调特定底层系统事件的处理。 大中央调度支持以下类型的调度源: 计时器调度源生成定期通知。 UNIX信号到达时, 信号分发源会通知您。 描述符源会通知您各种基于文件和套接字的操作,例如: 当数据可供读取时 何时可以写入数据 在文件系统中删除,移动或重命名文件时 文件元信息更改时 流程调度源会通知您与流程相关的事件,例如: 进程退出时 当进程发出fork或exec类型的调用时 当信号传递到过程时 Mach端口调度源会通知您与Mach相关的事件。 自定义调度源是您定义并触发自己的源。 Q5。 什么是应用程序稀疏? App Store和操作系统通过根据用户特定设备的功能量身定制应用程序交付,从而以最小的占用空间优化了iOS,tvOS和watchOS应用程序的安装。 这种称为应用程序细化的优化,使您可以创建使用最多设备功能,占用最少磁盘空间并容纳Apple可以应用的将来更新的应用程序。 更快的下载速度和更多空间可用于其他应用程序和内容,从而提供更好的用户体验。 切片 切片是为不同目标设备创建和交付应用程序包变体的过程。 变体仅包含目标设备所需的可执行体系结构和资源。 […]

Swift中的出租人已知功能

上一次,我们研究了Swift标准库中Array及其相关类型的一些功能。 在本文中,我们将研究AVFoundation和URLSession中的一些框架功能,以及带有日期格式的键编码的新Swift 4.1功能。 让我们开始吧! AVMakeRectWithAspectRatioInsideRect 我们不会深入研究AVFoundation框架,但是AVFoundation有一个方便的功能,在处理图像时非常有用。 它是AVPlayerLayer的一部分,称为AVMakeRectWithAspectRatioInsideRect CGRect AVMakeRectWithAspectRatioInsideRect(CGSize AspectRatio,CGRect boundingRect); AVFoundation框架中的此功能对于调整照片的大小以匹配图像视图的大小非常有用,例如在UITableViewCell或UICollectionViewCell 。 确保图像的大小与UIImageView的大小匹配(或接近UIImageView的大小)是一项重要的性能增强。 动态缩放图像可能会很昂贵。 调整大小可减少对分配给图像视图时必须重新缩放图像的系统的影响。 当您知道最终尺寸的一个方面(例如宽度)并且想要计算尺寸以在保留宽高比的同时重新绘制图像时,此功能很有用( 注意 :矩形的高度和宽度之间的比例关系为长宽比)。 假设您有一个包含两列的UICollectionView ,其宽度根据屏幕尺寸是固定的,并且您要根据集合视图单元格的宽度将图像的大小调整为保持纵横比的高度。 首先,使用适当的大小约束(在这种情况下为宽度)创建一个边界矩形,将边界矩形与原始图像的大小一起传递给AVMakeRect函数,以获取一个新的矩形,该矩形保持长宽比。 在代码示例中,原始图像为1276 x 800,宽高比为1.595(1276/800 = 1.595)。 边界矩形宽度设置为300,这将导致纵横矩形大小为300 x 188,并保持原始图像的纵横比为1.595。 URLSession等待连接 每个应用程序都需要联网功能,从而使URLSession成为Foundation框架的重要组成部分。 我们经常使用可达性来确定是否由于缺乏可达性而导致失败的网络请求(首先要检查您的可达性?请查看这篇文章),但是您是否知道在iOS 11中向URLSessionConfiguration添加了URLSessionConfiguration名为waitsForConnectivity的新属性? 如果在发起网络请求且没有连接时将此属性设置为true ,则URLSession将在URLSessionTaskDelegate上调用urlSession(_:taskIsWaitingForConnectivity:)并等待连接。 连接恢复后,任务将正常开始工作。 如果我们具有此功能,则可以使用委托回调来更新我们的UI和/或切换到离线模式。 我们可以通知用户连接可能存在问题,并让他们知道任务将等待连接,然后自动恢复或允许他们取消请求。 文档中有关此功能的重要说明: 每个任务最多调用一次此方法,并且仅在最初不可用连接时才调用此方法。 永远不要为后台会话调用它,因为这些会话将忽略waitsForConnectivity 。 这意味着,如果您具有连接性,但是连接断开,则不会调用此方法。 在这些情况下,Apple的文档将我们引向以下技术问答QA1941文档。 简而言之,根据请求类型( GET或PUT)您可以重试该请求,但是POST请求是一种特殊情况,您的应用应使用应用需求提供的自定义逻辑来相应地处理任何POST重试请求。 托收平等 Swift 4.1在集合上引入了一项新功能,即测试是否相等。 这是通过新的语言功能实现的,该功能可自动将类型合成为Equatable和Hashable协议。 在Swift 4.1中,数组(和字典)是Equatable ,只要它们的基础值也是Equatable 。 […]

Swift 4中的闭包简介

苹果,什么是瓶盖? 闭包是可以独立传递的功能块,可以在代码中传递和使用。 – 苹果 别担心,如果那没有道理。 起初,这听起来像: 闭包是一堆自成体系的单词,就像该死的篮球一样。 如果您不知道,操场上可能有一个篮球场。 去看看吧。 – 苹果 目的 在什么,如何以及在什么地方介绍闭包。 什么是封闭 闭包采用以下三种形式之一: 全局功能 嵌套函数 闭包表达 前两个是闭包的特殊情况。 如果您不知道函数如何工作,请在此处为您提供一篇文章: Swift 3中的主函数 当我们谈论Swift中的闭包时,我们经常提到闭包表达式。 如果有一件事可以帮助您记住什么是闭包,就是这样: 闭包是无头功能 。 闭包是没有func关键字和函数名称的函数。 它们也称为匿名函数。 它们本身不能像函数一样调用,因为它们没有名称。 它们结合使用。 封闭语法 由于其语法简单,因此鼓励使用闭包。 功能与关闭 以下是函数和闭包之间要记住的主要区别: 功能 有个名字 具有func关键字 没有关键字 关闭 没有名字 没有func关键字 有关键字 限定 让我们看看如何定义函数与闭包。 func GiveAFunc(){} var GiveNoFunc = {()->()in} 注意:我们的闭包以{开头,以}结尾。 我们将闭包存储在变量内,因此可以调用它。 呼叫 让我们调用一个函数,然后调用一个闭包。 GiveAFunc() […]