Tag: iOS应用

构建一个Foursquare克隆iOS应用—第6部分:状态管理

第1部分:简介和设置 第2部分:位置数据和管理依赖项 第三部分:持续集成 第4部分:流媒体位置 第5部分:网络层 第六部分:国家管理 到目前为止,我们已经为我们的应用程序创建了可靠的数据源,现在我们将致力于在数据和视图之间建立通信。 Apple官方文档提出的MVC架构对于新开发人员来说是最直观的。 这种架构足以满足简单的应用程序和小型团队的需要,但是遵循MVC的趋势是将所有代码集中到UIViewController类中,这会使您的应用程序难以理解并且容易出现错误。 首先,我想说明一下这是一个非常主观的概念,受以下因素的影响:功能的复杂性,团队规模,质量的定义和限制,组件的可重用性水平,开发人员的技术技能以及开发人员具有该架构的经验。 我个人在定义应用程序体系结构时优先考虑了3个基本原则: 组件责任:项目包含预定义的角色,避免了繁琐的类,并且添加新功能相对容易。 简便性:新开发人员第一次阅读代码时,应该能够轻松理解基本原理。 它还应该能够理解定义的模式,并在短时间内开始开发新功能或修复错误。 可测试性:顾名思义,代码应该更易于进行单元测试。 我在这里提出的解决方案不应被视为灵丹妙药,但它绝对比普通的MVC更好,而且相对容易学习。 通过选择使用ReSwift,我获得了体系结构以及数据流模式。 ReSwift的组件包括: Store:一个全局变量,代表您应用程序的当前状态。 在我们的情况下,它应该包含一个位置数组和数据获取状态(加载,完成或错误)。 视图:负责观察状态更改并基于新状态显示正确的UI。 在我们的例子中,它将是主要的UIViewController 。 行动: structs ,包含状态更改所需的有效载荷数据。 示例:一个名为SetPlacesAction的结构, SetPlacesAction包含一个公共位置数组。 Reducer:接收两个参数( Action和State )并返回新State 。 所有状态更改应集中在减速器上。 下面的代码定义了“状态”: 国家代表 这里的主要结构是FetchedPlacesState ,它必须符合StateType协议。 此结构包含一个枚举,表示应用程序的所有可能的三种状态: 加载:默认状态,表示应用程序正在等待提取所有数据。 失败:如果发生任何错误,我们使用此状态为用户显示一条人类可读的消息。 已完成:包含成功获取位置的数组 Equatable扩展仅对于单元测试是必需的。 Actions结构如下所示: 现在唯一缺少的是Reducer : 现在我们已经准备好所有代码,现在可以清楚地看到返回的State是Action和前一个State的函数。 我想在Reducer代码中指出一些细节: 具体来说,在我们的应用程序中,新状态不依赖于先前状态。 因此reduce方法仅使用action参数。 当您调用Observable方法时,它在Observable和Disposable ( subscribe方法的返回类型)之间创建了一个循环内存引用。 为了打破保留周期并避免内存泄漏,您只需要像我已经显示的那样调用disposed(by:)方法即可。 有关在此处处理袋子的更多详细信息。 您可能会注意到在此代码中闻起来不太香的是,在这种情况下, […]

使用Eureka在iOS中创建表单

现在已经有一段时间了,我们一直在从事银行iOS应用程序项目。 我们一直在使用用Objective-C编写的Forms的旧框架,因此我们开始研究更新和更灵活的替代方案。 我们发现Eureka很好地解决了我们的问题,但我们还需要创建许多自定义元素。 在本文中,我将通过概述如何发现Eureka以及如何编写自定义元素来分享我们的经验。 在此表单框架的帮助下,我们可以做什么? 尤里卡(Eureka)的最大力量在于框架已经包含的许多行中。 您可以直接使用它们,选择范围非常广泛。 仅举几例: TextRow , DateRow , CheckRow ,各种格式的数字行,列表行等。 Eureka存储库的自述文件中的图片也可以说明一切。 基本的构建块是节 , 行和单元 。 它们有助于从逻辑上构建表单并抽象出UITableView的复杂性,而Eureka显然是基于此构建的。 这些构建块使您可以专注于表单本身,而不是UITableViewDataSource和Delegate的实现细节。 这些部分等效于UITableView部分。 它们将表单元素的逻辑部分归为一个共同的标题。 它们在可选部分中具有特殊含义,我们将在后面介绍。 行可以解释为表单的元素,其中包含项的值和语义。 它们可以保存类型安全值 ,可以被禁用或隐藏 。 它们也可以具有定义的自定义属性。 单元格是行表示的实现。 他们拥有用户界面。 Eureka框架定义了许多单元,但是您可以定义自己的单元。 单元格对行属性的变化做出反应。 每个行都有其对应的Cell ,它已通过泛型定义了其类型。 泛型实际上是框架的重要组成部分。 如果您查看源代码,则可以看到它们。 对于我们最基本的示例,我们将实现一个简单的表单,其中包含名称,生日和一个布尔值(如果有人喜欢Eureka)。 我们还将使用一个按钮行,它将预填充前3个字段。 这听起来很简单-实际上确实如此,但是为我们提供了编写Eureka Forms的良好介绍。 为了更好地了解这一点,我制作了我们正在构建的应用程序的屏幕截图。 构建第一部分的最基本代码如下: 输入选择器允许用户通过显示出现在键盘区域中的选择器来选择答案。 如果要使用Eureka提供的默认单元格,则代码很简单。 视图控制器中的代码非常简单,因此我将向您展示而无需任何进一步的说明。 我们定义了我们在这里使用的自定义StringLengthRow类。 我将更详细地介绍这些自定义元素的定义代码。 我们定义两个类。 对于行,我们使用StringLengthRow,对于单元格StringLengthCell。 让我们从StringLengthRow开始,因为这是更简单的一种,并且将在我们的viewcontroller代码中使用。 在这里,我们只声明要设置的属性。 我们还在初始化程序中定义了如何获取新单元格。 我们选择从笔尖加载它。 StringLengthCell当然更复杂。 […]

iOS:在Swift中重新添加关键字

Rethrows是您在Swift中很少遇到的关键字之一。 在本文中,我们将尝试以一种简单的方式来解释它,而无需太多文献😉 我们将Rethrows用于可能会或不会引发错误的方法(取决于其功能参数) 在拥有Rethrows关键字(Swift 2)之前,我们必须复制函数“ doSomething”以支持两种情况。 那就是所有的朋友。 感谢您阅读并继续编写良好的代码👍

适用于iOS的Material Showcase

基于Material Design Guidelines的iOS应用的优雅美观的水龙头展示柜视图库。 介绍 在开发跨平台应用程序时,应将统一的UI / UX置于较高优先级。 当我们实施“功能发现”以指导用户首次浏览我们的应用程序时,我们的设计师决定遵循材料设计准则。 Android团队感到很自在,因为那里有一些流行的库(例如TapTargetView或MaterialTapTargetPrompt)开始。 相比之下,对于iOS版本,它需要我们的工作来从头开始实现,因为没有现有的库可以满足我们的需求。 因此,我们计划将其构建为一个开放源代码库,其他开发人员也可以使用它。 结果 通过仔细遵循Google Material页面上有关UI优点和动画的详细指南,我们得到了如下结果。 您可以使用CocoaPods轻松将其添加到iOS应用中。 材质展示柜 iOS应用的优雅美观展示。 cocoapods.org 或者,您可以从Github存储库包装其源代码并将其放入您的项目中。 aromajoin / material-showcase-ios material-showcase-ios – iOS应用程序的优雅美观的展示柜。 github.com 特征 支持任何UIView 提供便捷的方法来快速与特殊的UI组件(UIBarButtonItem,UITabBarItem,UITableViewCell)进行交互。 轻松自定义主题和动画。 有关更多信息,请在Github存储库中进行检查。 贡献 我希望它不仅是第一个“ Material Feature Discovery” iOS库,而且希望它成为减少iOS开发人员工作的简单,优雅且可靠的组件。 如果您发现它有用并且想做出贡献,请在Github上查看它,所有拉取请求都非常感谢。

App Store中的移动应用提交准则

苹果公司在几乎所有方面都以其严格性而闻名。 App Store不是豁免。 将移动应用程序提交到App Store比在Google Play上展示移动应用程序要困难得多,Google Play是唯一一家在数量,种类和受欢迎程度方面均与App Store相当的应用程序公司。 展示您的第一个iOS应用程序更加困难。 您必须具有Apple认证的应用程序。 但是,无论Apple有多权威,它都会为开发人员提供开发iOS激励的动力,并试图解释您的应用不应该是什么,看起来像什么。 如果您是软件所有者,则开发公司应为您进行功能部署。 但是无论如何,只需要提供服务即可。 这意味着必须计划您的iOS产品。 测试和发布过程 测试是软件开发的重要阶段,这是有原因的。 节省时间-Apple拥有稳定的硬件和iOS版本阵容。 这里没有Android众多。 在质量检查过程中以及在Apple,您的移动应用程序都被询问了两次。 由于崩溃,可疑内容,速度减慢,内存泄漏以及许多其他因素,可能会拒绝应用程序。 您的应用至少可以运行iOS版本; 它是预先设置的,并显示在App Store中。 这就是为什么将来的更新必须将您的用户的操作系统版本(即您在应用页面上声明的版本)改写为原来的版本。 如果您有矛盾之处,则拥有最旧iOS版本的用户将无法使用更新后的应用; 他们可以通过iTunes下载现代化的版本,它将替代以前的版本-因此将出现不应有的失败。 但是好消息是,Apple与iOS更新兼容,并且用户倾向于直接安装它们。 设计 您的应用程序的图标是什么? 当然,不是所有的东西,而是接近的东西。 图标图稿必须以几种精确定义的尺寸显示。 图标是用户获得的第一印象,以及应用程序名称。 名称必须不同,并且可能与设备主屏幕上图标下方显示的名称不同。 这两个名称相同时,通常会很有益。 但是,例如,如果您提供一个新的计算器,则它必须在App Store的页面上显示一个不同的名称,但是对于用户来说,如果在家里简单地命名为“ Calculator”,那将是准确的屏幕。 平台和屏幕兼容性范围 您的移动应用程序在其“应用程序商店”页面上的主要展示是什么? 正确,截图。 您的应用程序可以在页面上拥有1-5个屏幕截图。 当然,如果您的应用程序是通用的,并且同时支持iPad和iPhone / iPod touch,请确保为它们开发多个屏幕截图。 iPhone 5的细长4英寸屏幕与其3.5英寸的屏幕形成了鲜明的对比。 但是,您还应该了解一件事。 屏幕截图必须具有固定的大小-这是设备的大小,这是规则。 但是图像不必是原始的应用程序屏幕截图。 如果您的软件产品合理,则可以有效地使用此规则。 另请参阅: Google Play中的移动应用提交准则 内容分级 […]

iOS 10中的互动消息

iOS 10 SDK引入了新的Messages框架,该框架使应用程序开发人员可以创建扩展程序以与Messages应用程序进行交互。 今天,我将说明如何使用Messages框架发送交互式消息。 我们将创建一个扩展,使两个用户可以使用Messages应用程序玩经典的井字游戏。 什么是互动讯息? 以下屏幕截图将使您了解交互式消息气泡的外观。 您可以在交互式消息中嵌入图像或视频。 创建消息扩展 通过扩展可以使用向Messages应用程序添加功能的功能。 因此,首先我们将打开Xcode,创建一个新的Xcode项目,然后选择Message扩展模板。 您将观察到创建了一个带有附加MessageExtension目标的新项目。 今天,我们将为此目标进行所有工作。 MSMessagesAppViewController MessagesViewController.swift包含MessagesViewController类,它是MSMessagesAppViewController的子类。 此类是扩展的入口点和控制中心。 演讲风格 消息扩展有两种表示样式。 紧凑型-从应用程序抽屉启动扩展程序时,最初显示此样式。 扩展-您可以单击紧凑样式中的扩展箭头以过渡到扩展样式。 当发件人单击交互式消息之一时,也可以触发它。 应用逻辑 我们仅允许用户使用扩展的呈现方式玩此游戏。 因此,您可以单击一条消息,放置标记(x或0)。 一旦放置了标记,将包含表示游戏板当前状态的图像的消息插入到输入字段中。 用户可以控制是否要发送消息。 接收者收到消息后,可以单击该消息并继续前进。 用户移动后,显示新状态的图像将插入到输入字段中。 通过仅添加标签,我们将使紧凑的演示文稿样式保持简单。 项目概况 GameBaordVC —此视图控制器以扩展的呈现方式呈现。 这将处理与玩游戏有关的所有功能。 GameBoardVC管理的视图具有collectionview。 轻触单元格可让用户在单元格上放置x或0标记。 CollapsedVC —此视图控制器以紧凑的表示形式表示 GameStateVM —此视图模型将保存有关游戏板当前状态的信息,并做出有关游戏结果的决定。 呈现消息扩展UI MSMessagesAppViewController通过以下方法通知扩展的各种状态更改。 启动扩展时,将按指示的顺序调用以下方法。 1. func willBecomeActive(与对话:MSConversation) 2. func didBecomeActive(与对话:MSConversation) 3. func viewWillAppear() 4. func viewDidAppear() MSConversation对象表示消息对话。 […]

iOS开发部分-5

斯威夫特Typealias 目录 什么是打字别名? 如何创建打字别名? 内置类型的Typealias 用户定义类型的类型别名 复杂类型的Typealias Typealias 类型别名允许您为程序中的现有类型提供新名称。 声明类型别名后,可以在整个程序中使用别名代替现有类型。 类型别名不会创建新类型。 它们只是为现有类型提供一个新名称。 typealias的主要目的是使我们的代码更具可读性,并且在上下文中更清晰,便于人类理解。 如何创建打字别名? 使用关键字typealias声明为: 类型别名=现有类型 在Swift中,您可以对大多数类型使用typealias 。 它们可以是: 内置类型 (例如:字符串,整数) 用户定义的类型 (例如:类,结构,枚举) 复杂类型 (例如:闭包) 内置类型的Typealias 您可以将typealias用于所有内置数据类型,例如String,Int,Float等。 您可以将typealias用于所有内置数据类型,例如String,Int,Float等。 例如: typealias StudentName =字符串 上面的声明允许在所有地方使用StudentName而不是String 。 因此,如果您想创建一个字符串类型的常量,但是却更像是学生姓名。 您可以这样做: let name:StudentName =“ Pratik” 在不使用typealias的情况下,应将string类型的常量声明为: let name:String =“ Pratik” 在以上两个示例中,创建一个String类型的常量。 但是使用typealias声明时,我们的代码变得更具可读性。 用户定义类型的类型别名 在许多情况下,您需要创建自己的数据类型。 假设您要创建一个表示Student的Type,则可以使用以下类来创建它: class Student { } 现在,一组学生可以表示为数组: […]

嗯,我在那里花多少时间? —时间地点

第一次使用Medium。 我新年的决议仍在进行中! 😄 今天的帖子是有关Timeplaces第二版的,我的个人应用程序可在App Store上找到。 什么事啊 让我们看一下App Store的内容: Timeplaces是一个简单的时间跟踪应用程序,专注于记录,显示和分析您执行项目的时间。 可视化并改善您在哪里花费的宝贵时间。 作为读者,您可能会问:“如果您已经有了第一个版本,为什么要花这么长时间? Well”好吧,让我们回到一年前这个项目是如何开始的。 在我上一份工作期间,我们被要求每周提交一份报告,描述在每个项目上花费的时间。 但是,可用的跟踪工具无法实现我对自动化跟踪的愿景😅。 手动启动/停止项目,到处都有弹出窗口,嗯……作为一名开发人员,我开始变得富于创意,并开始思考替代方案。 第一个问题:我该如何追踪工作时间以做某事? 一个独立的笔记本电脑应用程序可能对我没有帮助。 在很多情况下,您仍可以在不激活笔记本电脑的情况下工作,可以在不重新启动应用程序的情况下重新启动计算机,也可以只在另一台计算机上工作。 为什么不使用移动应用程序? 那里一定有一百万! 我开始关注一些基本要求的市场: (1)免费 (2)基于位置开始/停止项目 (3)电池没电 (4)导出CSV数据 (5)分析概述 有一些众所周知且非常好的应用程序可以完成工作,但是为什么不自己做呢? dirty弄脏自己的双手并从头开始做某事始终是一个很好的借口💯。 2个月后,Timeplaces的第一个版本发布了! 它涵盖了上面提到的所有用例,但是有点太适合我当时的目的:我的每周报告。 休息一会之后,我想重新开始对自己的东西进行编码,为什么不使Timeplaces更加简单/直观,以便其他人也可以使用它呢? 我不再需要提交每周报告,但是我无法追踪在办公室,去健身房或在家中活动所花费的时间(出于好奇)。 我对专注于某件事的时间有些痴迷,我也必须努力解决这个问题。 是时候改变几件事了,让我们着手开发第二版应用程序。 我有以下想法: *我只想了解该项目,不需要花哨的描述或特殊字段。 *区分项目的直观方式。 *具有不同日期范围过滤器的简单分析视图。 *一个可轻松启动/停止项目的小部件(在午餐时间,我发现它很有用!🍕)。 结果,这就是我组织应用程序的方式: (1)项目清单 (1.1)创建新项目 (1.2)访问现有项目 (2)分析 (3)设定 从项目列表中,您可以检查现有项目,创建新项目或访问它们。 在创建新项目时,您将需要一个名称,一个可以轻松区分它们的主题以及一个用于自动跟踪的可选位置。 请注意, 始终需要访问位置权限才能使其正常运行。 别担心,它不会耗尽您的电池电量,我正在使用CoreLocation的区域检测功能,该功能经过了非常优化,可以使用尽可能少的GPS传感器。 您还可以通过在初始列表中点击一个项目来手动启动/停止项目。 等待! 更好的是,只需转到小部件并从那里开始您的项目,您甚至不需要解锁手机! 💪 分析为您提供了有关花费时间的概述,这是应用程序的主要目的。 […]

公开食物事实夏季食品’18

Open Food Facts是一个免费的在线人群资源数据库,来自世界各地。 该项目的目的是通过以下方式改进以Swift语言编写的新的本机iOS应用程序,以推动大规模采用和大规模贡献: 登机屏幕介绍功能 即时更改语言 连续扫描条形码和覆盖 个性化 离线贡献 滴灌编辑 更新用户界面 在App Store中列出特定关键字 增长黑客技术以获取更多客户 应用商店优化 用户测试的评论和评分 每个功能都将由Open Food Facts提供的基础API提供支持。 主要目的是通过实施新功能和改进现有功能来增强用户体验。 通过添加内联注释和完善文档,该项目也将变得对开发人员更友好。 您可以在GitHub上找到该项目。 openfoodfacts / openfoodfacts-ios openfoodfacts-ios – Open Food Facts的iOS版本(Swift)。 我们需要帮助🙂 github.com

使用iOS Pushkit的VoIP推送通知

在此博客中,我将介绍有关pushkit框架及其在VoIP应用程序中的用法。 让我们从一个场景开始。 场景:我正在编写VoIP应用程序,我想在后台状态下更新我的应用程序,或者想在收到任何VoIP呼叫时唤醒我的应用程序。 解决方案 :PushKit旨在通过提供具有大负载的高优先级推送通知来解决这些问题。 VoIP应用程序在后台接收通知,建立连接。 当我们有了用户通知框架时,我们为什么需要pushkit的原因已经明确了,现在让我们检查一下它们之间的区别。 与UserNotifications框架支持的用户通知不同,PushKit通知从不向用户显示-它们不显示徽章,警报或声音。 那么,为什么我们需要推包,这对于开发人员来说是一个非常明显的问题。 在iOS 8之前,开发人员需要满足以下情况: 前景中的ActiveConnection 通过VoIP授权的活动后台连接(VoIP套接字) 定期推送通知 该技术导致频繁的设备唤醒,浪费了能量。 这也意味着,如果用户退出VoIP应用程序,则将无法再接收来自服务器的呼叫。 开发人员应该使用PushKit框架-允许应用程序从远程服务器接收推送(数据可用时的通知)的API,而不是持久连接。 每当收到推送时,就会调用该应用程序。 例如,VoIP应用程序可以在收到呼叫时显示警报,并提供接受或拒绝呼叫的选项。 如果用户决定接受,它甚至可以开始采取前期步骤来发起呼叫。 使用PushKit接收VoIP推送有很多优点: 仅在VoIP推送发生时才唤醒设备,以节省能源。 与标准推送通知不同,用户必须先响应标准推送通知,您的应用才能执行操作,而VoIP推送将直接进入您的应用进行处理。 VoIP推送被认为是高优先级的通知,并且不会延迟地发送。 VoIP推送可以包含比标准推送通知所提供的更多的数据。 收到VoIP推送后,如果您的应用未运行,则会自动重新启动。 即使您的应用程序在后台运行,也会为您的应用程序提供运行时以处理推送。 在iOS 8中,Apple引入了一种新的推送方式:VoIP推送。 此推送消息有两个好处: 您无需允许推送; 它在用户不知道的情况下起作用。 苹果承诺将高度优先地提供这些推送通知。 最好的东西? 它允许您在推送到达时执行代码。 我在沙盒环境中进行的初步测试表明,它非常快,而且由于您可以用相同的方式处理所有调用,因此可以减少实现我们的Voice API的时间。 PushKit框架将特定类型的通知(例如VoIP邀请,watchOS并发症更新和文件提供商更改通知)直接发送到您的应用程序进行处理。 让我们看一下PushKit框架提供的类,协议。 像所有支持后台操作的应用程序一样,您的VoIP应用程序必须在“ Xcode项目”>“功能”窗格中启用后台模式。 选中IP语音复选框。 您还必须为VoIP应用程序创建证书。 每个VoIP应用程序都需要自己的个人VoIP服务证书,该证书映射到唯一的应用程序ID。 该证书允许您的通知服务器连接到VoIP服务。 访问Apple Developer Member Center并创建新的VoIP服务证书。 参见下图。 下载证书并将其导入“钥匙串访问”应用程序。 要配置您的应用程序以接收VoIP推送通知,请链接到应用程序委托中的PushKit框架(或应用程序中的其他位置)。 然后,创建一个PKPushRegistry对象,将其委托设置为self ,并注册以接收VoIP推送。 接下来,实现一个委托方法来处理更新的推送凭证。 […]