Tag: 移动

Gotta Go Fast:在iOS中构建速度。 第1部分

有许多技巧可以使iOS开发人员知道如何进行性能优化,以使应用程序中的动画流畅运行。 阅读本文之后,您将了解iOS开发人员意味着16.67毫秒的时间,以及使用哪种工具更好地跟踪代码。 本文基于Fyusion的iOS工程师,RayWenderlich.com上的iOS开发教程作者Luke Parham在国际移动开发者大会MBLT DEV 2017上发表的主题演讲。 “大家好。 假设可以,您可以将启动时间缩短10秒,再将其乘以500万用户,那么每天就是5000万秒。 一年多的时间可能是数十年。 因此,如果使其启动速度加快十秒钟,那么您可以挽救十几条生命。 那真的很值得,你不觉得吗?” 史蒂夫·乔布斯(Steve Jobs)谈性能(Apple II的启动时间)。 主线程负责接受用户输入并将结果显示在屏幕上。 接受点击,平移,所有手势,然后进行渲染。 大多数现代手机的渲染速度为每秒60帧。 这意味着每个人都希望在16.67毫秒内完成所有工作。 因此,摆脱主线程是一件非常大的事情。 如果花费的时间超过16.67毫秒,那么您将自动丢帧,并且在播放动画时用户会看到它。 有些设备的渲染时间甚至更少,例如,新的iPad具有120赫兹的频率,因此每帧仅需要8毫秒来完成工作。 规则1:使用CADisplayLink跟踪丢帧 CADisplayLink是在Vsync上触发的特殊计时器。 Vsync是应用程序渲染到屏幕时的时间,它每16毫秒发生一次。 出于测试目的,您可以在AppDelegate中设置添加到主运行循环中的CADisplayLink,然后只需执行其他函数即可进行一些数学运算。 然后,您跟踪该应用程序已运行了多长时间,以及自上次启动此功能以来已经运行了多长时间。 并查看是否花费了超过16毫秒的时间。 只有在实际渲染时才会触发。 如果您正在做大量工作,并且减慢了主线程的速度,那么它将在100毫秒后运行,这意味着您做了太多的工作,并且在那段时间内丢了帧。 例如,这是应用程序Catstagram。 图片加载时会结结巴巴。 然后您可以看到该帧在某个时间被丢弃,经过的时间大约为200毫秒。 这意味着该应用正在执行耗时太长的操作。 用户不喜欢这种体验,特别是如果该应用程序支持iPhone 5,旧iPod等旧设备。 Time Profiler可能是追踪这些内容的最有用的工具。 其他工具也很有用,但最终,在Fyusion中,我们有90%的时间使用了Time Profiler。 该应用程序的常见可疑对象是滚动视图,文本和图像。 图像是非常重要的。 我们有JPEG解码-“ UIImageView”等于一些UIImage。 UIimage解码该应用程序的所有JPEG。 他们做的很慢,所以您不能真正直接跟踪性能。 当您设置图像时,它不会正确发生,但是您可以在时间分析器跟踪中看到它。 文本测量是另一件事。 它确实出现了,例如,如果您有很多非常复杂的语言,例如日语或中文。 这些可能需要很长时间才能进行线路测量。 层次结构布局还会减慢应用程序的渲染速度。 对于自动版式尤其如此。 与手动布局相比,它很方便,但速度也很慢。 因此,这是这些折衷之一。 如果它减慢了应用程序的速度,则可能是时候放弃它并尝试其他一些布局技术了。 在示例调用树中,您可以看到CPU正在进行多少工作。 […]

使用Swift将单元测试应用于MVVM

在我的上一篇文章“如何不急于MVVM实现”中,我们学习了Model-View-ViewModel(MVVM)架构,并了解了如何使用它来创建简单的Gallery应用程序。 借助MVVM,我们将业务逻辑和表示逻辑与视图逻辑分离。 关注点分离(SoC)使编写单元测试比以往更加容易。 尽管MVVM的想法很简单,但仍然值得一提的是针对各种用例编写单元测试。 因此,在本文中,我们将更进一步,学习如何为MVVM进行单元测试。 简而言之,我将介绍两种技术: 如何设计模拟来模拟不同的网络状态。 如何使用存根测试用户交互。 让我们从上面提到的上一指南中精心制作的Gallery应用程序开始。 一个简单的图库应用 回想一下,简单的图库应用程序具有以下功能: 该应用程序从500px API获取流行的照片,并在UITableView中列出照片。 表格视图中的每个单元格都显示照片的标题,描述和创建日期。 该应用程序中的第一个屏幕称为PhotoListViewController ,此图描述了数据流: APIService负责网络层的工作,例如设置URL,发送请求等。PhotoListViewModel向APIService询问照片对象,并为PhotoListViewController提供呈现接口。 PhotoListViewController是一个简单的View,根据PhotoListViewModel呈现的数据渲染可见元素。 这是我们将在本文中测试的一些用例: PhotoListViewModel应该从APIService获取数据。 如果请求失败,则PhotoListViewModel应该显示一条错误消息。 如果用户按下“待售”照片,则PhotoListViewModel应该允许将其切换到详细信息页面。 MVVM和依赖注入 这是PhotoListViewModel的实现的一部分: 在下面的setUp()和tearDown()代码段中,注入的想法会更加清楚。 我们使用APIService对象初始化PhotoListViewModel ,但在测试环境中使用MockAPIService对象: 在下一节中,我们将看到如何设计MockAPIService来模拟所有测试用例的不同情况。 行为测试 我们的第一个用例是: PhotoListViewModel应该从APIService获取数据。 也就是说,我们要检查PhotoListViewModel是否确实从APIService请求数据。 这是模拟的实现: 为了被注入到PhotoListViewModel中 ,该模拟应符合APIServiceProtocol协议。 因此,我们创建所需的方法fetchPopularPhoto(complete 🙂来遵守协议。 现在,我们要确保PhotoListViewModel是否调用了fetchPopularPhoto(complete 🙂方法来获取数据,因此我们在MockAPIService中创建了一个属性isFetchPopularPhotoCalled 。 还记得apiService属性在测试环境中是MockAPIService对象吗? 如果模拟功能fetchPopularPhoto(complete 🙂由PhotoListViewModel调用,则isFetchPopularPhotoCalled将设置为true。 这是我们第一次测试的代码: 这是一个简单的测试用例。 sut (SUT,被测系统)是一个PhotoListViewModel实例。 代码段显示,当PhotoListViewModel提取数据时,我们检查它是否调用了fetchPopularPhoto(complete 🙂方法。 通过使用这种技术,我们可以检查PhotoListViewModel是否为依赖项注入调用指定的方法。 换句话说,我们成功地测试了ViewModel的行为。 成功还是失败? 除了行为测试之外,我们还希望查看PhotoListViewModel是否正确处理网络状态。 通过使用DI技术,我们可以通过更改MockAPIService的响应来模拟成功和失败的网络状态。 在本节中,我们将看到如何更改MockAPIService的响应状态。 […]

字符串格式还是字符串插值?

大多数开发人员逐渐不再担心代码的性能。 您可以问“为什么?!”。 每年,苹果公司都会推出一款新的iPhone,它具有更好的CPU和更多的RAM,并且应用程序优化的重要性越来越低。 我决定检查什么更有效,更旧的好字符串格式或称为字符串插值的快速功能。 为此,我用不同的创建字符串的方法创建了几个函数。 一开始,我需要一个测试模型。 结论 半秒的差异可以视为测量误差,因此可以说执行没有差异,特定功能的执行时间也没有差异。 但是编译时间呢? 这是另一篇文章的问题。 感谢您的阅读! 如果您喜欢这篇文章,请鼓掌,以便其他人也可以阅读。 下一篇文章我也会有更多动力。🙂您还可以查看其他文章,也许您会找到适合您的东西。 如果您有任何问题或建议,请发表评论。

在iOS#2中列出适配器

我的上一篇文章提出了基础知识。 您可以在此处找到源代码。 带多个电池的适配器 以前,我们为一个单元创建了演示者,但是适配器并不仅限于一个单元。 因此,我们可以更清楚地更改CellPresenter的名称: 资源 sayler8182 / Adapter2 通过在GitHub上创建一个帐户来为sayler8182 / Adapter2开发做出贡献。 github.com [第1部分] 感谢您的阅读! 如果您喜欢这篇文章,请鼓掌,以便其他人也可以阅读。 下一篇文章我也会有更多动力。🙂您还可以查看其他文章,也许您会找到适合您的东西。 如果您有任何问题或建议,请发表评论。

使用UICollection视图聊天UI

为此,我们仅使用带有单个UICollectionView单元格的UICollectionView组件,但是我们根据聊天的源值更改单元格上的子视图布局。 编写一个UIView扩展以使用VisualFormat添加约束。 2.定义一个聊天模型和一个基本集合视图单元格。 3.定义聊天单元。 4.将UICollection视图拖放到视图控制器上,并将该视图控制器嵌入到UINavigationController中。 另外,将UITextField和UIButton放在UIStackView中,并将该StackView放在UIView对象中,并给出约束。 您需要为此容器视图的底部约束创建一个IBOutlet,因为当键盘框架发生更改时,我们需要它来处理堆栈视图。 根据您的UI,为其余所有子视图赋予约束。 在本教程中,我在Utilities文件夹中放置了一个chat.json文件,因此在fetchChats方法的视图控制器中,我获取了chat.josn资源的URL,然后从该URL中创建数据对象,然后使用JSONDecoder对象,我在模型对象的帮助下获取聊天对象数组。 在这里,我们主要需要关注cellForItemAtIndexPath()和SizeForItemAtIndexPath方法。 首先,我们计算聊天消息的大小,然后根据它的大小,在聊天单元中布置子视图。 我们还使用聊天的源值在控制器的左侧或右侧布置单元格子视图。 与Collection视图的Delegate和DataSource方法一起,我还使用UITextFieldDelegate方法来处理聊天输入文本字段事件和功能。 为了进行仿真,在发送时,我正在从chat Textfield输入值构造一个Chat对象,并将其添加到集合视图数据源中,通过滚动到该项目来显示最近添加的项目。 通过查看以上代码片段和示例项目(可以从本教程底部的链接下载),您可以了解逻辑。 您可以在此处下载示例项目。

C ++和Swift中的不交集联合

您是否曾经想过,当您开车开车时,导航系统如何根据基于输入数据的变化(例如交通拥堵和错位)校正从当前位置到目的地的最佳路线? 这是最小生成树(MST)问题的实时实际应用之一,其中像Kruskal算法那样的算法试图解决该问题。 在本文中,我们将学习Kruskal算法中使用的主要数据结构,以便有效地解决MST问题。 在本文中,我们将快速完成: 介绍 怎么运行的 用C ++实现 在Swift中实现 结论 资源资源 介绍 想象一下有一个图,就像下面的图片一样。 您被要求非常快速地进行两个查询: 1. unionSets,即将两个集合合并在一起。 2. isSameSet,即查找两个节点是否在同一集合中。 Disjoint-set数据结构使我们可以非常快速地确定两个项目是否在同一集合中(或等效地确定两个顶点是否在同一连接的组件中),并且还可以非常快速地将两个集合联合(或等效地组合两个连接的组件)成为一个连接的组件)。 联合查找算法是一种对此类数据结构执行两个有用操作的算法: 查找:确定特定元素位于哪个子集中。这可用于确定两个元素是否在同一子集中。 联合:将两个子集合并为一个子集。 联合查找算法可用于检查无向图是否包含循环。 此方法假定该图不包含任何自循环。 我们可以跟踪一维数组中的子集。 怎么运行的 在下图中,让我们找出在此图是否有周期的情况下购买此联合查找算法。 对于此图中的每个边缘,请使用边缘的两个顶点制作子集。 如果两个顶点都在同一子集中,则会找到一个循环。 然后创建一个父数组并将其memset为-1(即,将-1作为所有数组的初始值)。 然后一一处理所有这些边缘。 0 1 2->节点。 -1 -1 -1->父数组。 边缘0–1:查找顶点0和1所在的子集。 由于它们位于不同的子集中,因此我们将它们合并。 要采用并集,请将节点0设为节点1的父级,反之亦然。 0 1 2->节点。 1 -1 -1->节点编号1是节点0的父节点。 我们将动态创建父数组和sz数组,我们还将需要一个私有方法来获取当前节点的父节点,最后,在私有成员部分中,我们将需要一个swap方法。 在公共成员部分,我们需要一个构造器 ,该构造器将使用图的大小,并用unionSets方法将两个集合合并在一起,使用isSameSet方法来找出两个节点是否位于同一集合中,最后当然,我们需要一个析构函数。 在实现这些方法时,从find_parent()开始 。 这里的想法是将节点的父级保存在父级数组中,因此,当您需要此信息时,它将以摊销的O(1)复杂度而不是O(n)的形式提供给您信息。 在same_set()中 方法,我们将只比较两个节点的父节点。 如果它们匹配,则它们在同一组中。 […]

我如何创建Apple的语音备忘录克隆

几个月前,我真的很想用苹果的Voice Memos应用程序创建带有音频可视化器的录音机。 作为一个初学者,我在Google上搜索了很多,但找不到任何有效的方法或确实要实现的功能。 因此,我决定尝试并尝试自己构建它。 遵循我的学习道路,了解如何创建语音录音应用程序,该程序具有音频可视化效果以及与苹果的Voice Memos应用程序一样的录音按钮。 基本设置。 当然,我将从创建一个新项目开始。 随您自己的喜好命名,我将其命名为VoiceMemosClone。 确保该应用程序正常运行,并且您得到令人满意的白屏。 现在,一切看起来都很不错,但是在进一步之前,让我们将原始的Voice Memos应用程序分解为较小的部分。 就个人而言,我发现很难在没有先准备的情况下开始构建/编码某些东西,而且我觉得这很令人生畏。 因此,我喜欢将所有内容分解成较小的部分,并独自解决每个小任务。 因此,如果您查看Apple的Voice Memos应用程序,将会发现几个关键功能: 1.可拖动的底视图。 2.录制/停止按钮的动画。 3.录制时的音频可视化器。 4.实际录音。 现在,让我们一起构建它们! 准备基本的用户界面。 在ViewController的 Main.storyboard中,嵌入NavigationController ,检查PrefersLargeTitles ,并为其指定“ Voice Memos”作为标题。 1.卡视图。 首先,将两个containerViews添加到View Controller。 其中一个是RecordingsViewController,另一个是那个RecorderViewController。 从文件->新建菜单中创建一个新的UIViewController类,选择UI Cocoa Touch Class文件。 将RecorderViewController的背景色更改为ViewFlipsideBackgroundColor ,将size属性更改为Freeform。 在“大小”检查器中,将高度设置为150。还添加一个UIView,使其与ViewController的大小相同,并为黑色提供45%的alpha值。 就像在RecorderViewController中一样,在RecordingsViewController中添加一个tableView并添加一个UIView,并且在两个UIView中都检查Hidden属性。 最后,连接刚刚创建的UIView的出口。

众所周知,内容如此丰富,您可以分享

消费,评论和分享有趣的基于事实和真实故事的应用程序,由我们的团队策划和创建。 语言: Objective-C 功能:推送通知,Facebook SDK,离线保存 作为业务中比较流行的一面,只有开发了相应的移动应用程序才有意义,该应用程序具有一些您无法在网络上获得的功能。 从一开始就构建了此应用程序(构想,线框图,功能列表),然后在应用程序商店中发布。 建立推送通知,用于发布新内容或您最喜欢的作者发布内容的时间,以及其他用户回复您的评论的时间。 除了构建“脱机保存”功能外,还可以保存内容以供以后使用,尤其是在您没有网络连接(通过地铁上下班)的情况下,这些内容是通过iOS端的Core Data构建的。 您是否曾经构建过移动版本的Web应用程序? 您添加了哪些功能?(如果您添加了)以区别或添加到移动版本? 让我们连接! 通过评论我的帖子或与我联系,不要犹豫, 电子邮件: markgage86@gmail.com 推特: markgage86 盘带: markgage86

适用于iOS的Zenkit在这里!

Zenkit iOS版是Web应用程序的轻量级,直观的伴侣,无论您身在何处,都可以访问所有馆藏。 无论您是要通勤上的工作,在会议上做笔记还是在旅途中快速捕捉想法,Zenkit都能为您提供帮助。 以您在网络上开始的工作为基础,创建新项目,附加相机或照片库中的图像。 没信号? 没问题! Zenkit for iOS 支持脱机工作 ,一旦您再次联机,便会与Web应用程序同步。 需要快速记笔记的方法吗? 全局添加使您可以直接从主页将项目添加到任何集合。 需要了解细节吗? 您可以直接从手机上更新任何收藏集中的任何字段,甚至可以附加相机或照片库中的图像。 随时了解您的项目,对新活动发表评论并随时随地与团队合作。 Zenkit还将向您的手机发送推送通知,因此您始终处于循环状态。 您可以使用“分组”视图查看按不同标签分组的项目。 可以在组之间移动项目,就像您期望的那样-通过令人满意的平滑拖放,将项目从一个标签快速移动到另一个标签。 我们认为Zenkit应用程序非常棒,但是请不要相信我们! 看看The Next Web上的Bryan Clark的想法! “尽管如此,iOS版本还是对本已出色的Web应用程序的绝佳补充。” 我们的iOS团队在过去几个月中一直在努力创建此应用,因此,我们要非常感谢团队投入工作并做出了出色的贡献! 我们还想向Beta测试人员大声疾呼,没有他们,我们将没有今天拥有的应用程序。 你们有什么感想? 立即下载该应用并尝试一下! 我们很想听听您如何在旅途中使用Zenkit。 干杯, Siobhan和Zenkit团队

如何在视频预览中使用AVFoundation分析帧

AVFoundation是Apple开发的框架,可在iOS上使用。 该框架用于创建,编辑和播放媒体内容。 它使开发人员可以直接访问摄像头和麦克风。 在本教程中,我们将看到如何访问摄像机流以在每个帧上执行操作。 注意: AVFoundation是一个高度自定义的框架。 例如,如果您有一个只需要拍照的应用程序,则应使用UIImagePickerController。 要在应用程序中配置AVFoundation,必须使用AVCaptureSession。 此类拥有访问相机和正确使用输入所需的不同配置。 它将链接输入配置(相机,麦克风),输出配置(照片,视频流,音频流)和实时预览。 每个类的体系结构如下所示: 以下示例基于以下类: WASSA是室内位置和计算机视觉领域的创新数字代理专家。 无论您是想帮助客户在建筑物中找到自己的出路,增强产品的用户体验,收集有关客户的数据还是分析某个地点的人流量和行为,我们的创新实验室都将科学的专业知识带给您最大的设计灵感根据您的目标调整解决方案。 在 – 找到我们: Facebook和Twitter 领英 的GitHub 我们的网站