让我检查我的调度程序

为RxSwift编写测试可能很棘手。 RxSwift的一项核心功能是默认情况下所有操作都是异步发生的。 如果您正确连接了所有可观察对象和观察者,则您的应用程序将按预期运行。 不幸的是,异步代码很难进行单元测试,因为您必须处理近似和可能。 但是,如果我们正确地组织代码,则测试Rx代码将变得非常简单。 通常,RxSwift与MVVM结合使用,因此让我们编写一个ViewModel进行测试。 当我在iOS中指MVVM时,指的是一种体系结构,其中代码按数据传输类型(模型),视图(UIView和UIViewController子类)和ViewModels大致划分。 视图主要用于在屏幕上绘制,模型没有逻辑,并且可以从一个地方到另一个地方传送数据。 ViewModel用于获取模型并以使View简单的方式对其进行转换。 尽管我们的体系结构只有四个字母和三个组成部分,但这并不意味着我们仅限于三种对象。 这些类型中的每一种都可以由名称和责任不同的任何数量的类型支持。 但是,定义整个iOS应用程序应如何设计其体系结构超出了本博客文章的范围,因此让我们继续使用ViewModel。 假设我们有一个应用程序供用户发布他们喜欢的乐器的图片。 在这个应用程序中,我们希望用户能够互相关注。 当您关注用户时,将看到一个显示以下内容的视图: 您有多少个追随者 最后追踪的对象 因此,我们的应用程序需要一种创建关系的方法,在该关系中用户跟随另一个用户,然后我们收集该数据并将其显示在屏幕上。 让我们从考虑网络开始。 假设我们的后端为用户提供了一个不错的RESTful接口。 api / v1 / followers /将使用我们的一系列用户响应GET请求。 该端点还将允许客户端将用户放入用户并创建新的关注者。 对于我们的iOS客户端,我们可能需要使用URLSession发出网络请求。 不必担心URLSession如何工作的细节,我们如何制作一个协议来包装网络调用。 这样,我们可以为生产实现真正的网络类型,但在测试中将其保留。 美丽! 现在我们知道了网络层的外观,让我们考虑一下ViewModel。 我们需要一种跟踪用户的方法。 让我们从这里开始。 这是一个很好的开始! 现在,我们有了一个可以跟随其他用户的对象! 更好的是,由于我们指定了调度程序,因此可以通过将网络调用移至后台队列来防止UI挂起。 如果您不熟悉调度程序,则它们是决定可观察对象的工作将在哪里运行的类型。 尽管这是一个很好的第一步,但是当您仔细观察时,并没有真正好的方法来对该对象进行单元测试。 这是个“火上浇油”的电话,因此,作为消费者,没有办法知道跟踪是否成功。 最重要的是,因为我们在该对象内创建了操作队列,所以即使我们知道要查找的内容,也无法确定它何时真正发生。 让我们解决这个问题。 我们还有两个要求: 您有多少个追随者 最后追踪的对象 由于这些要求都使用来自同一端点的数据,因此我们应该能够将这些实现为对来自followers()方法的可观察输入的转换。 让我们将两个可观察对象连接在一起,以便在您请求关注者时,如果响应成功,则请求更新的关注者列表。 该对象感觉更适合测试,我们提供了输入(用户),并且我们应该能够观察到输出(新计数和最新关注者)。 为了隔离我们正在测试的内容,我们将注入一个模拟的FollowerNetworkLayer,它将返回任意的测试数据。 自创建了FollowerNetworkLayer协议以来,我们可以创建一个接受静态数据的结构并将其返回以进行测试。 我们不在乎测试我们的网络层,我们可以单独进行测试。 当前,我们仅在测试要求我们的ViewModel跟随用户时,它会正确返回预期数据。 它完全需要网络层的事实与我们的实际目的相切。 在这里,我们在Observable上使用.just(_ :)静态方法来创建我们的Observable。 […]

谷歌增加了一个新的队友

您好,对于所有出色的iOS工程师, 今天是学习令人兴奋的事情的好日子。 因此,如果几天前像我一样,您可能会被标题弄糊涂。 不用担心,我们将介绍Google的新功能。 该消息还将使您对Firebase感到不满。 你看到我在那里做什么吗? 好的,山姆,没有您的任何搞笑笑话,请您说明发生了什么! 谁是新队友? 好的,我不知道您是否听说过Google以Fabric的名义收购了一家公司的消息。 Twitter在2014年将Fabric引入了世界。您可以将Fabric视为Firebase的竞争对手。 如果您不知道Firebase是什么,请立即停止并在此处查看我的文章。 两者都有类似的工具,可帮助开发人员构建应用程序,而无需从头开始创建大量后端基础架构。 这些平台使开发人员可以专注于构建出色的应用程序,而不必担心如何创建身份验证,实时数据库或分析之类的流程。 布 即使Firebase和Fabric相似,Fabric也提供了一些我们可以讨论和探索的功能。 仅查看Fabrics工具(套件),我就感到非常兴奋,因为它们提供了有用的产品。 我认为有三种套件对任何应用都将非常有帮助。 我也相信这些工具也是Google可能正在研究的工具。 1.数字:使用电话号码(而不是电子邮件和密码)验证用户。 无需密码,因为用户将保持登录状态。 Fabric声称Digits的使用体验简单,安全且安全。 另外,他们指出,数字的转换率比要求的电子邮件高20%。 使用此工具,将无需登录电子邮件,但用户只需输入一次电话号码并提供验证码即可。 就我个人而言,我更希望通过电话号码将电子邮件发送给公司。 我将在未来几周内测试Digits,以查看是否可以在应用程序中使用它。 2.解答:提供有关受众如何使用您的应用程序的实时统计信息。 答案检查活动的用户数,会话长度,稳定性等级和保留率。 它类似于Google Analytics(分析),它从应用程序收集什么数据。 他们俩都会收集有关谁在使用该应用程序,获利和崩溃报告的数据。 答案是另一种工具,它不仅提供图表,还向您显示对您来说很重要的数字。 您会为您收集并编译所有数据,因此您不必弄清楚图表上显示了有关您的应用程序的信息。 我知道此工具将是Google尝试在其Firebase Analytics Platform中实现的工具。 为了节省时间,我遗漏了很多其他信息。 请在此处随意检查此工具的功能。 3. Crashlytics: iOS和Android排名第一的崩溃报告平台。 我只能说的是,我对Crashlytics提供的所有信息感到惊讶。 您检查是否由于应用程序,硬件或操作系统(iOS和Android)而导致崩溃。 知道崩溃信息很重要,因为如果您的应用出现问题,您可以准确找到问题发生的地方。 这样您就可以将所需的资源放在正确的位置以修复该错误。 我不能强调拥有像Crashlytics这样的工具有多么重要。 我并未涉及所有功能,但您可以在此处查看它们。 我的想法 现在,我们讨论了Fabric中三个工具的基础知识,让我们看看Google将使用这些产品。 Google为Firebase投入了大量时间和金钱。 Google已使其变得可访问,并开始扩展该平台。 尽管该平台正在增长,但仍有许多开发人员需要抓住。 另一方面,Fabric的产品已经起飞,并且已经被沃尔玛,Uber等大型企业使用。我明白了Google为什么要这些工具的原因,因为它将大大改善Firebase平台。 Google将找到一种将Crashlytics之类的工具整合到Firebase Analytics中的方法。 Firebase产品经理在这里讨论了一些工具的用途。 […]

在iOS 10.3:小版本中自定义应用程序图标。 大功能!

多年来,iOS开发人员(包括我自己)一直希望能够自定义应用程序图标。 但是整个iOS生态系统(以及后来的Clock)中只有一个应用程序可以实现:Calendar-本地Apple应用程序,使用当前日期更新其图标。 这个看似很小但看似复杂的功能(需要4个API)开辟了许多可能性! 这里只是几个: 利用多租户模型的企业应用程序; 为每个客户提供他们自己的自定义品牌的应用程序图标。 利用免费增值模式的应用; 当用户购买完整版本时,请从图标中删除“精简版”。 让用户选择他们支持的团队作为其应用程序图标; MLB应用程序可以提高用户参与度,并提供新颖的应用程序体验。 让我们以MLB At Bat应用程序为例,说明自定义应用程序图标的过程。 打开应用程序,点击设置,然后点击“设置主屏幕图标”。点击您最喜欢的团队,您就完成了。 就这么简单。 从安全角度来看,我敢肯定苹果公司不愿意启用此功能,因为它可能会误导用户或给非技术精明的人造成混乱或问题。 但是,苹果公司最终解决该问题的方式非常简单。 无论更改是由手动用户选择还是由自动配置驱动,都会显示一个弹出窗口(如上所示)以请求用户验证。 如果要利用此功能,开发人员要考虑的唯一警告是,必须在Info.plist文件中包括资产和条目才能使其正常工作。 这意味着您将无法即时更改图标; 图标在提交到AppStore之前必须预先包装在IPA中。

Ruby on Rails的最佳做法

红宝石宝石 今天,我们将讨论使用MVC框架时众所周知的良好实践。 谁从未听说过“肥胖模型,瘦身控制器”这句话? 那是一个非常普遍的想法。 但是,有很多方法可以帮助您使我们的模型,视图和控制器变得更加瘦弱。 这可以帮助您进行更好的测试,并使代码可重复使用。 在本文中,我们将讨论方法和类中逻辑的分离,以及如何不将所有代码仅保留在模型,视图或控制器中。 首先,让我们记住MVC架构模式以及每个职责是什么。 基本上,MVC代表模型,视图,控制器,其主要目标是将逻辑分为三个主要层。 模型:负责表示数据,数据验证,业务逻辑以及与数据相关的所有事物。 查看:它向用户显示信息。 控制器:它是模型和视图之间的中间层。 它通过路由器接收用户请求,然后向模型询问数据并在视图中显示响应。 这里要强调的重要一点是,并非所有内容都应保存在这三个地方。 当您打算干燥应用程序时,其他一些类确实很有用。 让我们开始谈论它。 帮手 Rails允许您使用助手,以便您可以从视图中提取逻辑。 如果需要格式化或在显示之前进行验证,则应使用它。 例如,不要这样做: 你应该做这个: 模块ProductHelper def product_price(产品) product.price是否为product && product.price.present? 结束 结束 然后,在您的视图中,您只需要调用预定义的方法。 像这样: 这样,您可以轻松地测试您的助手,也可以多次重用它,而不必将逻辑带到视图中。 通常,它可以自动在视图和控制器中使用。 但是,更常见的是将其用于视图(后端还有其他辅助功能)。 您在模块中声明的所有帮助程序将在您的所有视图中可用-不仅仅是在同一个命名视图中。 服务 服务是一种干燥控制器的方法。 人们通常创建目录“ / service”并将文件放入其中。 每个文件都是一个类,具有一个初始化程序,输入和该类的特定/相关方法。 为什么要使用它? 如果您想集中精力应用程序的核心逻辑,并且还需要瘦小的模型和控制器,则应该这样做。 服务用例的一个示例: 类ProductLogisticService def initialize(参数) //初始化变量 结束def addInStock //在您的库存中添加产品的方法 结束def removeFromStock //从库存中删除产品的方法 结束 […]

尽早制作-Siri快捷方式入门| Byteout博客

让我们通过引用WWDC 2018中的Apple来开始这篇文章 Siri快捷方式是iOS 12中强大的新功能,可让您的应用向Siri公开其功能。 这使Siri可以根据各种上下文在相关时间建议您的快捷方式。 有了这项新功能,应用程序便有了新的面貌-语音。 而且,它们会在您可能想到的时候立即出现在Spotlight上,从而自动“变得更聪明”。 因此,在本教程中,我将向您展示使用NSUserActivity在应用中实现快捷方式的速度—包含2个代码块 。 我将指导您完成一些步骤,向Siri展示我们喜欢的应用程序的一些最有价值的功能。 注意:您可以 在 Byteout Software博客 上 找到带有 更好格式的代码 的原始帖子 。 简短介绍-我们示例的背景故事 早期游戏警报是一款闹钟应用,在用户赢得简单游戏之前,它不会停止响铃。 用户也可以随时随地玩游戏,即使没有警报也是如此。 为此,在没有新的快捷方式的情况下,他们必须: 启动应用 转到列出所有游戏的屏幕 滚动到他们最喜欢的一个 按“播放” 但是有了快捷方式,他们将只能使用自己的声音,或者在搜索中键入游戏名称。 因此,让我们深入研究代码! 第一步是进行用户活动并在适当的时间捐赠。 // GamesSelectionViewController.m // 1. Make activity – (void)donateActivity { NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:@”com.your_appname.game_activity”]; // A activity.title = [NSString stringWithFormat:@”Play %@”, self.selectedGame.name]; // B […]

什么是Cydia下载iPhone 8?

Cydia Download是越狱设备的应用商店。 Cydia背后的开发商是Jay Freeman,他的名字叫Saurik。 Cydia下载实际上是二级应用商店,一旦设备越狱,用户便可以从中获取第三方的自定义应用。 只有通过越狱技术,才能在iOS设备上获取Cydia Download。 Cydia Download是越狱后用户能够下载,安装和管理设备活动的位置。 Cydia下载iOS 11无法从Cydia官方网站上安装,因此,您需要使用越狱工具(例如Pangu,Yalu或TaiG)来安装Cydia。 越狱过程会有所不同,具体取决于设备的型号和所使用的iOS版本。 因此,在启动越狱过程之前,需要确保已选择正确的越狱工具。 建议在下载Cydia之前先阅读与Cydia Download相关的教程。 Cydia Download可以提供比现有功能更多的功能,从而使您的iDevice更加智能。 因此,在Apple每次发行新固件后,等待新版本的Cydia出现都不会有危害或不利之处,因为它始终是使用户满意的版本。 使用所有Cydia应用程序以及进行调整,用户可以通过使其iOS设备脱离其有限的框架来提高其性能。 随着iPhone 8和iPhone 8 Plus的发布,iOS用户会想到的一个问题是Cydia是否与他们的设备兼容。 iOS 11越狱是实现这一目标的关键,因为iPhone 8和iPhone 8 Plus均运行在最新的Apple iOS 11固件上。 因此,iOS 11越狱的开发人员一定会确保已将Cydia支持添加到iPhone 8和iPhone 8 Plus中。 应当指出,有些应用程序可以在不越狱设备的情况下安装Cydia应用程序。 视频指南Cydia下载iPhone 8

如何在可编码协议中使用Swift 5结果

我已经写过有关Alamofire API管理器的文章,但是有了新的Swift 5 Result功能,我想对其进行一些升级。 我们将它与Codable协议一起使用,使我们的生活更加轻松。 如果您不是Alamofire粉丝,则可以将其删除。 但是,结合Codable和Result的原理,您应该尝试在网络处理程序中实现。 这个想法是建立一个可重用和直接的API管理器。 我们必须使用单一职责原则创建一些帮助程序类-ErrorObject,EndpointType,EndpointItem,NetworkEnvironment。 我现在不会解决这些问题,因为您在这里。 API管理器 我们的APIManager使用EndpointItem对象创建URL请求。 同样,它解析数据。 使用Codable时,解析是一项简单的任务。 因此,代表数据模型的所有结构和类都应实现Decodable和Encodable协议。 我们使用通用参数T,其中T是可编码的。 T通知APIManager我们正在获取哪种数据以及希望管理器返回哪种类型的对象。 T可以是实现“可解码”和“可编码”协议的任何对象或对象数组。 处理程序需要Result类型。 因此,Result的第一个参数是通用参数T,第二个是错误对象。 我们使用Swift.Result表示法,因为Alamofire也有其Result对象,并且我们需要指定要使用的对象。 APIManager —带有Swift 5结果的通用方法 收到响应后,APIManager尝试解码数据。 如果成功,他将退还。 在其他情况下,它将返回AlertMessage对象。 值得一提的是,Result对象的第二个参数必须符合Error协议。 我们需要扩展AlertMessage对象。 AlertMessage —错误对象 在APIDemoViewModel中,我们使用API​​Manager的方法。 在这里,我们指定要获取的结构,以便将数据解码为适当的对象。 APIDemoViewModel-实现的APIManager通用方法 好处 如果将APIManager与Results和没有结果进行比较,则主要优点是我们不再具有可选参数,并且可以使用强类型引用。 这意味着我们的代码更直接,更容易读写。 结果错误也很重要,因为它们是强类型的,我们可以创建自定义错误,使它们适合我们的项目。 只是不要忘记它需要符合Swift的Error类型。 现在我们确定我们将获得成功或失败,不可能两者皆有或两者皆有。 没有Swift 5结果的APIManager旧版本 结论 我们将Swift 5结果和Codable协议结合在一起,使我们的代码更清洁,更高效。 这是一个简单的代码示例。 如果您有任何问题或建议,请随时发表评论。 资源资源 示范项目 Alamofire Api Manager-原始帖子

raywenderlich.com的官方Swift样式指南

类前缀 Swift类型由包含它们的模块自动命名,并且您不应添加类前缀(例如RW)。 如果来自不同模块的两个名称冲突,则可以通过在类型名称前添加模块名称来消除歧义。 但是,仅在可能出现混淆的情况下指定模块名称,这种情况很少发生。 导入SomeModule 让myClass = MyModule.UsefulClass() 代表们 创建自定义委托方法时,未命名的第一个参数应该是委托源。 (UIKit包含许多示例。) 首选: func namePickerView(_ namePickerView:NamePickerView,didSelectName名称:字符串) func namePickerViewShouldReload(_ namePickerView:NamePickerView)->布尔 不推荐: func didSelectName(namePicker:NamePickerViewController,名称:字符串) func namePickerShouldReload()->布尔 使用类型推断上下文 使用编译器推断的上下文编写更简短的代码。 (另请参见类型推断。) 首选: 让选择器= #selector(viewDidLoad) view.backgroundColor = .red 让toView = context.view(forKey:.to) 让view = UIView(frame:.zero) 不推荐: 让选择器= #selector(ViewController.viewDidLoad) view.backgroundColor = UIColor.red 让toView = context.view(forKey:UITransitionContextViewKey.to) 让view = UIView(frame:CGRect.zero) 泛型 通用类型参数应为描述性的大写驼峰名称。 当类型名称没有有意义的关系或角色时,请使用传统的单个大写字母,例如T , U或V […]

适用于Swift开发人员的Python

我什至尝试了一下,但并没有太认真,但是这次我向自己保证,我将彻底探索该语言。 它把我吹走了! Python仅需几行代码即可为您提供强大的功能。 几行代码,您正在绘制一个UI,其中包含一个窗口和几个在OSX,Linux和Windows中运行的控件。 再加上几行代码,就可以像这样以2D渲染游戏。 Python语言 有人声称Python和Swift非常相似。 我会说它们是完全不同的,但是在某种程度上,Python在编写代码时似乎非常熟悉。 我发现的第一个区别是Python使用的数据类型是: 整数,浮点数,字符串,复数,布尔值,元组,列表,字典和集合。 除了复数(这是我看到的第一种语言,它本来就支持它,这似乎很奇怪,因为除科学家们以外,它们没有被广泛使用,尽管很酷),它们都是Swift程序员非常熟悉的数据类型因为我们使用了所有这些,尽管可能有些不同。 Python并不使用带有方括号{}的块,而是一种非常聪明的方式,使块位于缩进内部。 在Python中,缩进内置于解释器中。 属于代码块的代码必须缩进,否则会收到错误消息。 这是使Python特别可读的功能之一。 Python非常直观,使用诸如PyCharm Community Edition之类的IDE可以非常轻松地调试代码并了解程序中正在发生的事情。 徽标作家回来了! 在1980年代,我还是一个孩子的第一步就是使用Logo Writer完成计算机和编程方面的工作,在学校里用乐高积木和所有这些东西建造机器人。 这一切对我来说似乎都是神奇而令人兴奋的,我每天都会去实验室尝试学习新事物。 我不得不承认,当我发现Python拥有一个名为Turtle的超棒库时,我有点感动,该库基本上模仿了我成长时用来绘制的Logo Writer turtle。 类和对象 作为现代语言,Python是一种具有面向对象编程能力的语言,并允许其用户创建类和对象。 输出 : – [Johhny,41] – 他们是一样的 在Python中,您可以像在Swift中一样创建对象。 它们有一个构造函数(在某种程度上类似于第4和第5行中描述的Swift构造函数)。 在python中,您不必声明对象的成员变量(只需像第4行那样访问它们,它们就会自动创建,即self.name =’mortimer’ 在Swift中,您可以覆盖运算符! 耶! 您可以覆盖==,+,,*,无论您想要哪个! 在此示例中,我重写了等于运算符 就像我们在Objective-C和Swift中所做的那样,您可以声明一个描述符方法,并输出一个友好的类描述,您可以在Python中执行相同的操作: var description: String { return “-[” + self.name + .. + “]-“} 在第15行中,我编写了一个简单的描述符,用于调试Person类,该描述符实际上在第18行中使用。 […]

iOS中的资源包和静态库

如何在静态库中使用图像,Xib和情节提要之类的资源。 默认情况下,这在动态库中很容易实现,但是当涉及静态库时,可能会遇到一些挑战。 在本文中,我希望解释如何在静态库中使用故事板和图像之类的资源。 让我们跳进去。 步骤1:创建静态库 导航到“文件”->“新建”->“项目”,然后选择“ Cocoa Touch静态库”。 让我们给静态库起个名字。 那很简单! 步骤2:设定资源套件 导航到您的库项目,然后选择“添加目标”。 然后导航到macOS并选择Bundle。 命名资源束,我将其命名为Resources🙃 由于我们正在为iOS开发,因此将您的资源包基础SDK设置更改为“最新的iOS…”。 最后,将资源作为目标依赖项添加到您的静态库中。 步骤3:设定资源 在静态库中使用所有适当的配置和链接设置一个简单的ViewController和Storyboard。 为了使Storyboard成为捆绑软件的资源,您要做的就是将它们添加到目标的“复制捆绑软件资源”构建阶段。 现在您的静态库已准备就绪。 步骤4:链接静态库和资源包 通过创建一个简单的单视图应用程序并在viewDidLoad上模态显示“ MyViewController:”,来使用我们的新静态库。 为此,您必须将静态库.xcodeproj拖放到基本应用程序中。 这可能看起来像这样。 然后,您可以通过“链接的框架和库”链接静态库,就像这样。 最后,添加将资源束从静态库链接到基本应用程序。 为此,我们只需要将其从导航器窗格拖到应用程序项目的“ Copy Bundle Resources”阶段即可。 这应该看起来像这样。 第5步:使用它吧! 🎉 将以下代码添加到基本应用程序的视图控制器中,以便可以从适当的资源包中加载Storyboard。 一旦捆绑包被加载,您就可以简单地实例化并呈现它。 小菜一碟吧! 图像呢? 是的,您可以将图像引入静态库,但是必须将图像资产添加到资源包中,然后通过Xib,Storyboard或Bundle加载它。 希望您发现本教程对您有所帮助。 如果您有任何问题,请给我ping通,我很想听听您关于在静态库中使用资源包的想法。 和平✌️