Tag: 迅捷

名为“ Objective-C和带有CocoaPods的Swift”的沼泽

名为“ Objective-C和带有CocoaPods的Swift”的沼泽 我最近得到一份合同,内容是客户的应用程序完全由Objective-C编写。 好吧……您知道这个故事……许多应用程序由于缺少Swift的游戏规则改变程序“ Optional ”而崩溃,而且我个人不喜欢Swift中的故事板交互 我决定将这场噩梦变成一个仙境:)…。 不幸的是,该项目已经基于CocoaPods了。首先,由于项目的独立性,我试图将其更改为“ Carthage”,它比Cocoa Pod更好。 我通过“ cocoapods-deintegrate”摆脱了CocoaPods的困扰,它是救生员插件(那里的工作很好的人)……它确实需要简单的步骤…… 然后我在项目上遍历了podfile来找出那里的依赖关系,结果如下: 好吧……大多数真正古老的库都不知道为什么它们仍在呼吸……还有故事的来龙去脉,您可以自己开发该功能,而无需在那里使用任何库…… 有趣的生活开始了,其中一些库没有迦太基版本,我不得不自己将其转换为“迦太基”以及以下剧集..: “迦太基将只构建从您的.xcodeproj共享的Xcode方案。 您可以通过运行carthage build –no-skip-current ,然后检查Carthage / Build文件夹,查看是否所有预期的方案都能成功构建。” 我已经将ACSPinKit和iOS-Slide-Menu更新为“迦太基”,但是紧迫的时间来了,你知道这意味着什么,当你是承包商时…你应该比他们的专职开发人员快得多:) 我决定回到可可豆荚,然后添加我的快速库,没有它们我无法呼吸 然后安装pod …这些术语遇到了“动态框架”,看起来像CocoaPods从“ CocoaPods 0.36 ”中得到支持,这看起来像是个好消息……。我将其添加到podFile的顶部 它开始安装Pod,但是依赖项(FMDB)之一困扰了我的构建。 FMDB是一个有用的库,可以处理应用程序上的SqlLite db,它是用Objective-C编写的,我已经在我的桥接文件“ *****-Bridging-Header.h”中添加了我需要调用的其他文件他们从敏捷的一面: 在这一点上,我真的放弃了,不知道为什么在我的xcode构建阶段中不加入FMDB库。 然后开始运行带有构建设置文件和无步搜索的游戏…。它把我拖到一边说好,我将在Objective C中完成其余的应用程序,但是Swift和RxSwift的悲伤表情促使我继续工作这个问题…。 猜猜是什么……光亮了……我对自己说,为什么不遵循迦太基遵循的概念……手动复制文件……但是我没有完全从FMDB复制所有文件,但是文件并不多……。 我已经从FMDB中跟踪了所有需要的文件,并将其复制到了我的Swift文件夹中 然后运行构建以及交叉手指….. 你知道然后休息,像传奇一样去散步:) 无论如何,希望这对那些必须走同样的路并且拥有一个与Objective C和Swift结合使用的应用程序的人有所帮助。

SWIFT中的舍入进度栏

嗨,大家好! 作为您的IOS开发人员,我在这里附带有关如何制作圆形进度条的第二个故事。 在IOS中,我们有“状态栏”,但是我们无法使其四舍五入。 让我们深入研究如何自己编写代码。 首先,我们在uiview子类上使用CAShapeLayer()类对象进行绘制,然后在屏幕或窗口上显示该View。 采取IBDesginable类,它是UIView的子类。 @IBDesignable class RoundProgressBar:UIView { } 2.我们需要此组件的属性。 我们先绘制浅色的backLayaer,然后在其上面用另一种颜色制作另一层,以用当前值标记进度。 因此,它具有最小值,最大值和当前值来表示外观。 因此,属性用于2层,即背景和前景,最小值,最大值和当前值,以及一些IBInspectables,用于在Interface Builder上呈现视觉效果。 私人var bgLayer = CAShapeLayer() 私人var fgLayer = CAShapeLayer() var minValue:Double = 0 var maxValue:Double = 1.0 var currentValue:Double = 0 { didSet { fgLayer.strokeEnd = currentValue> 0.01? CGFloat(currentValue):0.01 } } IBInspectables颜色和条形宽度 @IBInspectable var progressBarWidth:CGFloat = 20.0 { didSet { […]

适用于Swift iOS App的GRPC BFF

gRPC移动BFF 本教程重点介绍后端前端(BFF)设计模式如何表示移动应用程序开发人员“永远的最佳朋友”,尤其是不同的技术如何帮助实现最佳BFF,从而实现移动应用程序的最佳反应性和响应性 。 一般而言,BFF的目标是简化客户端应用程序的开发时间,以使“服务API”调用解耦,从而有可能减少调用次数,并最终在不同的客户端实现中共享一些逻辑,从而优化常规网络和数据转换,同时增加共享的数据连接,分页,缓存,同步,流式传输等,并最终执行安全性和其他策略。 Internet上已经有很多教程介绍了这种现在非常普遍的设计模式。 在这里,我们没有谈论多通道,微服务,api网关,服务网格,也没有使用任何其他现代的“服务器”术语,我们只是说BFF是移动应用程序与每个移动设备“服务API”之间的“中间件”。应用需要在云端或内部调用。 本教程更具体地侧重于BFF模式如何帮助简化对这些服务API接口的访问,尤其是采用gRPC协议在很大程度上确实有助于减小数据大小,优化网络以及实现和实施一系列协议。共享的基础结构功能。 当然,与其他许多领域一样,这里没有银弹。 其他接口(例如GraphQL)可以在某些情况下提供其他好处,而特定的移动技术(例如iOS上的URLSession后台下载任务)可以在特定移动环境下(例如有限的多任务处理)对网络优化提供非常强大的控制 样本问题:必须全部抓住! 在本教程中,我们将创建一个移动应用程序和一个BFF服务器,以实际演示该设计模式的优势。 我们将创建一个Pokédex移动应用程序,该应用程序将使用公开可用的http://pokeapi.co/ REST API,允许用户按名称或类型搜索Pokemons,并将为找到的每个Pokemon显示以下信息: 名字 图片 所有类型 身高和体重 他住在哪儿 物种栖息地的全文描述(风味文字) 为了获取所有这些数据,将使用以下后端REST API: / pokemon :获取特定口袋妖怪名称的基本口袋妖怪数据 / pokemon-species :获取特定口袋妖怪的栖息地信息 / type :获取特定类型名称的所有宠物小精灵的列表 为什么我们需要BFF? 等一下 这些Pokemon API只是简单的REST API,我可以轻松地从移动应用程序本身直接调用它们。 为什么我需要gRPC,更重要的是为什么要使用BFF? 那就对了。 这些API可以直接由移动应用本身使用,但让我们在下面的图片中看到这些简单方法的缺点。 首先,我们可以看到,即使这个超级简单的应用也需要协调来自三个不同网络API调用的数据。 基本上,要搜索特定类型的所有宠物小精灵,我们需要先调用/ type Rest API以获取口袋妖怪名称或ID的列表,然后对于此列表中的任何单个口袋妖怪,我们都需要调用/ pokemon Rest API以获取基本信息例如名称,类型,高度和宽度,还可以调用/ pokemon-species Rest API获取栖息地信息。 除了需要“协调”对不同的Rest API的调用之外,另一个需要重点关注的事情是,所有这些神奇宝贝Rest API都返回了我们渲染应用程序用户界面实际所需的更多数据。 实际上,在此示例iOS移动应用程序中,我们将使用非常经典的UICollectionView界面,并且仅需要在集合单元中显示上面介绍的口袋妖怪信息(名称,图像,类型等)。 这些神奇宝贝Rest […]

如何绕过进度视图的角落(高度增加)

目标: 问题:增加进度条的高度会破坏角半径。 拐角处不会圆滑。 增加高度 如果您搜索如何增加UIProgressView的高度,则可能会遇到答案: progressBar.transform = progressBar.transform.scaledBy(x:1,y:8) 很简单。 拐弯处 如果您搜索如何绕过进度条的角落,则可能会遇到此Stack Overflow帖子。 它告诉您设置拐角半径,然后裁剪到边界:(子层是这样,因此内部栏也具有圆角。) progressBar.layer.cornerRadius = 8 progressBar.clipsToBounds = true progressBar.layer.sublayers![1] .cornerRadius = 8 progressBar.subviews [1] .clipsToBounds = true 问题在于将它们放在一起会导致: 显然这不是我们想要的。 解决方案 无需使用.transform来增加高度,而是需要在进度条上使用高度约束。 这将增加高度,.cornerRadius将按预期方式工作。 TL; DR 使用高度约束来增加进度栏的大小。 然后,您可以使用.cornerRadius和.c​​lipsToBounds圆角化。

第一次感动-Swift代表

星期一,Peter Pan的iOS Swift类的新主题是如何使用委托。 今天,我将向您展示如何使用“ UITextFieldDelegate”中的函数来处理事件。 今天的挑战是设置一个文本字段,规则是我们只能在文本字段中插入10个字符。此外,必须有一个标签来显示我可以插入多少个字符。 因为今天的要点不在情节提要上,所以我直接跳到viewController。 首先,我让类实现UITextFieldDelegate,以便可以在委托中使用函数来处理insert事件。 类ViewController:UIViewController,UITextFieldDelegate { 然后转到情节提要,右键单击鼠标并将委托拖到viewController。 这是我在练习中使用的功能。 func textField(_ textField:UITextField,shouldChangeCharactersIn范围:NSRange,replaceString字符串:String)-> Bool {} 现在回到viewController并开始插入代码。 您可以在每一行上看到这些注释。 导入UIKit 类ViewController:UIViewController,UITextFieldDelegate { @IBOutlet弱var countDownLabel:UILabel! @IBOutlet弱var insertTxt:UITextField! let limitCHTs = 10 //设置字符数限制 func textField(_ textField:UITextField,shouldChangeCharactersIn范围:NSRange,replacementString字符串:String)-> Bool { let oldLength = textField.text?.characters.count //在交互之前获取文本长度 let insertLength = string.characters.count //获取插入的文字长度 让newLength = oldLength! + insertLength-range.length //插入后计算文本长度 let isWithinLimit = […]

斐波那契,黄金分割与记忆

让我们首先定义将在本文中探讨的两个关键主题: 首先, 斐波那契数列是一系列数字 给定数字的方法是将其前面的两个数字相加。 该序列揭示了有关宇宙深层定律的某些东西,因此它出现在自然界的许多地方,包括诸如植物和动物之类的东西以及诸如星系的螺旋形之类的东西。 因为在这些地方都可以找到它,所以它已经成为物理学家,数学家和程序员一样着迷的话题。 其次, 记忆化是由Donald Michie (人工智能领域的一位真正有趣的英国思想家)创造的术语(或单词),它是一个编程术语,它意味着存储可能需要花费时间或空间的函数调用结果。运行,并在多次出现相同的输入时返回缓存的结果。 在本文中,我将首先描述斐波那契数列是什么以及在何处找到它。 其次,我将探讨斐波那契数列与黄金比率之间的联系。 最后,我们将研究Michie教授的备忘技术如何帮助我们更快地找到斐波那契数列中出现的第N个数字。 最后,我将讨论一些地方,在这些地方我们可以使用序列的知识来理解其他事物。 介绍 斐波那契是意大利人,出生于1175年,一直活到1250年-他为西方数学做出了重要贡献。 尽管他的名字与我们的话题同义,但他并不是第一个发现“斐波那契”数列的人,因为该知识似乎已经在意大利数学中广为人知。 该概念的较早知识显然是在梵文韵律中编码的 显然在斐波那契之前很多年在印度享有盛名。 确实是维拉哈卡(Virahaṅka) 与斐波那契数列的第一个已知描述(来源:E)有关,这位公元6世纪印度数学家对梵语韵律的长音节和短音节的分析反映了这一自然数值序列。 但实际上是在斐波那契的著作Liber Abaci(1202)中 ,他描述了给定兔子种群(在理想条件下)的生长将如何符合这种特定的自然序列。 让我们看一下斐波那契数列:这是斐波那契注意到在整个自然中重复出现的数字序列,因此他着手描述。 该序列如下所示: 1,1,2,3,5,8,13,21,34 … 等等。 像这样用数学描述: 上面的等式在数学上描述了斐波纳契数列(X 1)中的第N个数等于其在数列(X 1)中的后一位,再加上在数列(X 2)中的后两位。 但是,重要的是,我们还必须在上述方程式中添加几个限定条件 ,并注意, 如果n == 1或n == 2,则Xₙ= 1。 此外,如果使用序列的“现代版本”(如我们现在经常使用的)并从0开始,则如果n == 1,则 Xₙ = 0,如果n == 2,则 Xₙ = 1。 注意:现代版本的斐波那契(实际上是相同的序列,但起点不同,始于0)将如下所示: 0、1、1、2、3、5、8、13、21、34 […]

2018铃木雨燕—比以往任何时候都更加强大和男性化

很显然,铃木在汽车设计上采取了一种相当保守的方法。 进行中的Swift外观与最初于2004年发布的汽车大致相同。不过,这种情况即将改变。 几周前,全新的2018铃木雨燕已经在日本见到,似乎这种车型也正向欧洲和其他一些市场发展。 该车使用新平台,配备新引擎,并确实为Swift名称带来了不少风格。 到目前为止,铃木对此还没有多说,这仍然很不寻常。 尽管如此,日本模式似乎与我们将要获得的模式基本相同,并且看起来很有希望。 2018铃木雨燕–新一代雨燕 很显然,铃木在汽车设计上采取了一种相当保守的方法。 正在进行的Swift外观…… cardissection.com 2018铃木雨燕价格和其他细节 新型号使用与Baleno相同的HEARTECT平台。 这是一种轻巧的底盘,比以前使用了更多的高强度钢。 最终结果应该是一辆更坚固,更安全的汽车。 新的底盘还允许铃木重新设计地板,因此新的Swift也应该在机舱内更宽敞。 通过新平台,他们还添加了新的跑步装备。 到目前为止,尚无有关此方面的大量信息,但与以前相比,汽车似乎要好得多。 这也要归功于Baleno占领了铃木的低端市场,因此Swift可以比以前更好,更昂贵。 持续生产的车型起价约为10,500欧元,具体取决于所销售的市场。相比之下,新的2018年铃木雨燕在日本的售价为11,900欧元,因此可以肯定地认为它的售价将甚至超过当时的价格。将袭击欧洲海岸。

学科

Subject是一个代理,即Subject即是Observable又是Observer。 Subject可以作为一个Observer订阅一个或多个Observable,又可以作为一个Observable被其他的Observer订阅。 它可以传递/转发做为观察者收到的值,也可以主动发射值。 Subject在RxSwift中的实现有多种。 PublishSubject对应ReactiveX中的PublishSubject ReplaySubject对应ReactiveX中的ReplaySubject BehaviorSubject对应ReactiveX中的BehaviorSubject 变量 发布主题 代理 我们先以PublishSubject解释主题为一个代理的含义。 让publishSubject = PublishSubject () 发布主题 .subscribe {事件在 print(“事件:\(事件)。”) } publishSubject.onNext(1) publishSubject.onNext(2) publishSubject.onNext(3) publishSubject.onCompleted() Subject做为Observable提供了订阅等方法。在订阅之后我们调用了onNext方法,向Observer发射了1、2、3,完成。打印结果和我们的预期一样。 事件:next(1)。 事件:next(2)。 事件:next(3)。 活动:完成。 我们可以调用Subject的系列方法主动发送值给Observable。 注意在这里如果我们在订阅之前调用了on Next方法,观察者将不会收到发送的值,这一点涉及到Hot Observable的概念,我们放到后面讨论这个问题。 Subject可以作为代理转发订阅到的结果。 让publishSubject = PublishSubject () 发布主题 .subscribe {事件在 print(“事件:\(事件)。”) } 让intSequence = Observable .create {(观察者)->一次性 viewer.onNext(1) viewer.onNext(2) viewer.onNext(3) rator.onCompleted() 返回Disposables.create() } intSequence […]

如何避免情节提要中的Segue标识符

Segue标识符是纯字符串 。 故事板中的属性和代码中的文字。 我们需要确保情节提要中的代码与代码匹配。 如果我们需要以编程方式调用segue,则它们很有用,因为它们可以识别segue。 但是通常, 标识符用于将信息从一个视图控制器传递到另一个视图控制器。 像在此示例中一样,标识符用于从源视图控制器A配置B或C: 运行时错误 。 标识符是字符串。 我们可能会拼写错误或重构代码并更改字符串,而不会更新对应的字符串。 这会导致运行时错误。 如果标识符错误,则将继续执行segue,并且目的地将无法正确准备。 准备目的地的代码永远不会执行。 编译器无法检查标识符是否匹配,因此对错误一无所知。 开发人员也不了解它们。 将显示新的视图控制器,并且该应用将崩溃或行为不正确。 最糟糕的部分是,如果我们犯同样的错误,即仅在一侧更改标识符,则会在修复它们后再次出现这些错误。 我们可以通过定义标识符的命名约定( 请参见 stackoverflow问题 )和/或使用常量或枚举而不是文字来尝试最小化此问题 。 注意:Natasha The Robot在文章“ Swift中面向协议的Segue标识符 ”中解释了使用协议和枚举的字符串文字的另一种方法 。 他们摆脱了文字字符串,提高了代码质量。 序列标识符仍被使用。 刚性和脆弱性 。 Segue标识符很难维护。 它们的变化会影响不同的部分,它们是刚性的 。 如果您改变一侧,则会破坏另一侧,它们很脆弱 。 注意:刚度和脆弱性是不良设计的标志,摘自 罗伯特·C·马丁(Robert C. Martin)的 “ 依赖反转原理 ”。 重复的代码。 当我们重写方法prepare(for segue:UIStoryboardSegue, sender: Any?) ,我们将在条件prepare(for segue:UIStoryboardSegue, sender: Any?)和目标cast中复制代码。 […]

使用Kue排队作业

向开发人员询问有关Redis的信息,大多数人会告诉您这是键/值存储。 然而,不仅如此; 这也是实现作业队列的非常有用的机制。 将工作单元封装为作业有很多优点: 作业可以在后台运行 。 在Web应用程序的上下文中,这意味着您可以处理请求而无需等待作业完成。 您可以延迟作业的执行 ,将其搁置以在以后的日期或时间运行。 作业可以在与 “主”应用程序不同的上下文中运行,可以是不同的进程或线程,环境甚至是不同的服务器。 如果作业失败,则可以将应用程序配置为多次重试 。 您还可以优先处理作业 。 假设您急需通过电子邮件发送故障通知,同时您的应用程序正在发送大量新闻通讯。 设置较高的优先级,可以说“它将跳到队列的最前面”。 许多队列实现还提供了监视作业的能力; 它们的状态-例如,它们是成功还是失败,或者正在等待重试-以及监视长时间运行的作业的进度。 现在,我们已经了解了作业的一些优点,让我们看一下在Node.js应用程序中实现作业的一种方法; 使用K。 介绍K Kue是一个Node.js程序包,它提供了Redis队列的抽象级别,并提供了一些有用的工具来监视您的作业。 从最基本的角度来看,Kue允许您将代码单位定义为作业,并且在幕后将其放置在Redis队列上的必要信息(运行内容以及运行数据)。 然后,工人负责实际运行这些工作。 前提条件 要使用Kue,您需要安装Node.js和npm,当然,还需要安装和配置Redis。 我们假设您在本地主机(127.0.0.1)上安装了Redis,并在默认端口6379上进行侦听,但是您当然可以适当地配置它。 安装 使用npm安装Kue: NPM安装k 然后,您将需要它: var kue = require(’kue’); 创建工作 在创建作业之前,您需要创建一个队列实例: var queue = kue.createQueue(); 还有许多其他选项,例如命名队列和覆盖默认的Redis连接设置。 有关更多详细信息,请查阅文档。 现在让我们通过在新创建的队列上调用create()方法来创建作业。 第一个参数标识作业的类型,第二个参数将任何其他数据作为哈希传递。 然后必须将作业保存到队列中。 这是一个例子: queue.create(’email’,{ 标题:“欢迎使用该网站” ,发送至:“ user@example.com” ,模板:“ welcome-email” })。保存(); […]