Tag: swift

如何正确编写扫描QR码的ViewController

让我们编写一个解耦的代码,通过使用组合甚至可以测试我们的ViewController! 😱 当我不得不编写QR码扫描仪应用程序时,我以前从未使用过AVFoundation。 因此,我遵循了通常的脚本:我阅读了一些文档,阅读了一些教程并将学习的内容应用于我的需求。 通用方法的问题在于,它使ViewController符合另一种协议。 因此,它增加了另一个责任! 我将以一个简单的应用程序为例,向您展示一种更好的方法。 第一个ViewController需要一种使用摄像机捕获视频并显示在此辣味混合框中捕获的内容的方法。 另外,当用户将相机指向QR码时,它需要解释并解码其值。 之后,它可以停止捕获视频。 AVFoundation助我们一臂之力! AVFoundation 尽管QR代码已经很老了,但是直到iOS 7才有了AV Nativeation的巨大改进,我们没有在iOS上读取它们的原生方法。 现在,这是在iOS上实现代码读取器的最简单方法! 它具有我们完成此任务所需的所有功能。 AVCaptureDevice Input负责捕获视频。 AVCaptureVideo 预览层,用于显示实时视频。 AVCaptureMetadata 输出是将解释和解码QR码的输出。 AVCapture Session可以管理输入和输出之间的数据流。 我将所有这些逻辑包装在名为AVCodeReader的类中。 它的界面由两个函数和一个属性组成。 该函数开始读取QR码并使用转义闭包来通知何时解码值。 另一个停止使用相机资源。 还有CALayer属性,其中包含正在捕获的视频。 定义AVCodeReader接口的协议 AVCodeReader 我使用init来设置前面提到的所有AVFoundation类。 https://github.com/danielCarlosCE/aguente/blob/master/Aguente/Model/Implementation/AVCodeReader.swift 首先要记住的是,该设备(如模拟器)可能没有摄像头。 您必须决定接下来会发生什么。 我选择不破坏应用程序,而是选择一个空的videoPreview和一个nil captureSession 。 现在,它可以在不为captureSession时使用captureSession启动和停止读取QR码。 https://github.com/danielCarlosCE/aguente/blob/master/Aguente/Model/Implementation/AVCodeReader.swift 请注意,我将completion闭包分配给didRead属性,因此可以从另一个函数调用它。 要用作输出的委托,它必须符合AVCaptureMetadataOutputObjectsDelegate 。 该协议需要NSObjectProtocol ,因此我将类NSObject的子类。 https://github.com/danielCarlosCE/aguente/blob/master/Aguente/Model/Implementation/AVCodeReader.swift ReaderViewController 承诺是写一个解耦的代码! 让我们看看ViewController的样子。 https://github.com/danielCarlosCE/aguente/blob/master/Aguente/Controller/ReaderViewController.swift 尽管ViewController不知道如何扫描QR码,但它具有依赖关系。 由于在使用情节提要时不能使用构造函数注入,因此我在此处使用了强制展开属性。 因此,如果有人在调用此视图之前忘记设置依赖项,则应用程序将崩溃! 请注意,我不仅要添加videoPreview图层,而且还要在视图布局其子视图时对其进行更新,因为在viewDidLoad尚未设置自动布局的约束。 […]

如何提出出色的应用创意

就像作家有时会受到作家的阻碍一样,应用程序开发人员有时也会得到类似的东西。 您正在尝试为一个应用程序提出一个好主意,但是每次您想到某个东西时,事实就已经存在了。 这个过程可能非常令人沮丧,那么您应该怎么做才能避免呢? 寻找下一代天才革命性应用程序时,它始终取决于视角,您的研究可能性可能会受到限制,但它总是有助于查看您或您的朋友和同事每天面临的问题。 我该怎么做才能改善我或他人的生活? 出色的应用程序使使用它的人的生活更轻松。 这可能是您在寻找下一个想法时必须记住的一句话。 金钱方面不是主要动机,因为提出创意确实需要一定水平的创造力,而且正如大多数艺术家可能会告诉您的那样,创造力并不总是会花钱。 当然,您必须有一个长期的获利策略,但是它绝不应该限制您的创意寻找过程。 我还建议您不要靠近竞争对手,例如,当前的iTunes图表。 因为为什么要看已经存在的东西? 您需要找到您热爱的东西,并且其他人可以与之联系。 无论是猫还是保持生活井井有条。 根据个人经验,我可以告诉您,除非您对所从事的工作充满热情,否则它将永远无法达到最高质量。 不要被少数几家卖了几百万美元的初创公司所迷惑,它们是例外,您永远不要试图模仿它们的成功。 他们都没有想到,当他们开始时会以那么多的钱出售他们的应用程序。 他们之所以这样做,是因为他们相信自己的想法。 因此,总结一下:与您的朋友,家人和同事交谈,以了解他们在生活中的价值。 向他们询问最喜欢的应用程序,缺少什么或如何改进它们。 列出您一周内要做的事情,并考虑这些事情在哪些方面为应用程序带来改进的潜力。 一旦您提出了一个好主意,就该开始编码了,并且如果您不是专业的应用程序开发人员,我建议您参加与我的同事Johannes Ruof一起在Udemy上教授的课程。 使用此链接获取 “学习如何编码-iOS的专业Swift开发”可享受90%以上的折扣。 或点击此链接并使用代码:MEDIUM15

苹果基于Swift的iBeacon应用开发,带有适用于iOS 7/8的CoreLocation

如今,许多用户更喜欢使用Apple的新编程语言Swift开发其iBeacon应用程序。 为了增强开发能力,Apple的开发人员更喜欢使用Swift,Xcode 6和iOS 8。 在过去的几年中,iBeacon应用程序的开发已大规模增加,这为开发人员提供了广泛的机会来了解iBeacon技术并通过使用它来构建其重要的应用程序。 如果您是iOS开发人员,则可以轻松高效地开发基于Swift的iBeacon App。 以下是一些基本步骤,开发人员在开发有价值的基于Swift的iBeacon模板应用程序时需要遵循这些步骤。 1.创建一个Swift项目 在第一步中,从“文件”菜单中选择“新建”->“项目”。 然后从左侧菜单中选择“ IOS应用程序”,然后从右侧选项中选择“单视图应用程序”。 然后单击“下一步”。 2.配置项目选项 在下一步中,配置项目名称,组织名称和组织标识符。 另外,请确保选择“ Swift”作为语言,然后选择“ iPhone”作为设备。 3.将CoreLocation框架添加到项目中 在下一步中,在文件浏览器中单击主项目条目。 然后选择“常规”选项卡。 然后滚动到底部,然后单击+添加一个链接框架。 添加CoreLocation.framework后,您可以在列表中找到它。 只需选择它,然后单击添加按钮。 但是,如果要更改旧版本的iOS应用,请在“常规”设置中进入“部署”目标。 6.x进入7.0版本,因为它无法正常工作,并且没有必要的CoreLocation功能,并且无法与Swift一起执行。 4.配置后台功能 要执行后台测距和监视以及接收通知,应用必须在后台使用位置更新和Bluetooth LE配件。 要实现此目的,请在文件浏览器中单击主项目条目。 选择功能选项卡和背景模式,然后将它们打开,然后检查位置更新并使用Bluetooth LE配件。 5.定义要监视的区域 在这一步中,我们将在AppDelegate.swift中的application:didFinishLaunchingWithOptions方法中进行设置。 最初,我们需要导入CoreLocation标头,然后为信标设置带有UUID的CLBeaconRegion。 UUID是标识信标或信标集的标识符。 6.设置位置列表项始终 对于iOS 8,需要始终运行位置监控的特殊权限,其中还包括iBeacon测距。 因此,您需要添加一个特定的plist条目,使iOS能够通知用户为什么他们需要此权限。 在此步骤中,在支持文件下的文件浏览器中输入,打开Info.plist。 然后选择第一行“信息属性列表”。 要添加行,只需单击小加号即可。 为它提供密钥(在左列)NSLocationAlwaysUsageDescription。 然后将type设置为String,然后在提示他们输入位置权限时,将其值设置为您要用于通知用户的任何字符串。 7.设置CLLocationManager进行前景/背景监视和测距 定义区域后,我们需要指示设备对其进行监视。 为此,我们需要创建一个CLLocationManager实例,并指示它开始监视刚刚创建的区域。 我们还需要定义一个“代理”,一个对象在位置管理器发生任何事情时都会得到通知。 在此步骤中,您需要导入CoreLocation标头。 然后,您需要指示编译器我们的AppDelegate类将实现CLLocationManagerDelegate协议,并声明一个属性以保存我们的CLLocationManager对象,以便它在应用程序的整个生命周期内都有效。 稍后,在didFinishLaunchingWithOptions方法内部,您需要创建CLLocationManager实例。 然后,您请求“始终”授权以获取位置信息。 由于这是iOS 8中的新方法,因此您需要首先检查CLLocationManager是否响应选择器。 […]

A / B测试移动应用

什么是A / B测试? 是一项实验,您将两个版本的服务提供给不同的人群,并评估每个变体的性能。 这很简单,例如更改网站上按钮的颜色并衡量哪个按钮获得了更多点击。 A / B测试的其他名称是存储桶测试和拆分运行测试。 我为什么要在乎? A / B测试提供了一种科学的,没有偏见的方法来改善您提供的服务。 您可以制定假设,与真实用户进行检验,并根据真实数据制定业务决策,而不受HiPPO(最高薪人士的意见)的驱动。 该技术的强大之处在于,当您发现违反直觉的结果时,如果不使用科学方法很难找到该结果。 谁在使用它? 几乎每个科技公司都以某种方式使用它。 一些著名的例子是Google,Facebook和Spotify。 您很可能已经在不知不觉中参加了实验,例如,在Facebook中,您看到的UI不同于朋友。 如何实施? 以最简单的方式,A / B只需要两件事,一种是创建统一的变体,另一种是测量结果。 例如,我们可以有一个标志,当用户首次启动应用程序时,它会随机决定用户是在A组还是B组上,然后根据此标志更改行为。 当用户与应用程序进行交互时,我们会评估其行为,并使用分析将结果与用户所在的组一起发送。 但是,如果您使用商业平台从小处着手,则可能会有一些优势并简化您的工作。 在这篇博客文章中,我们将探讨如何使用Taplytics完成A / B测试。 集成SDK是一个非常标准的过程,一旦您在Taplytics中注册,便可以遵循。 之后,您可以使用“实验”标签开始创建A / B测试。 我们设计的实验称为“表情符号或图片”,以了解我们的用户是否更喜欢使用表情符号或图片的界面。 我们最初的用户界面是: 我们想测试通过用表情符号替换图像是否可以增加应用程序的整体使用率。 我们可以衡量的一项测试和一项指标。 该服务的可视化编辑器可让您点击应用中的任何内容,并为实验进行编辑,而无需编写代码。 这个功能虽然很有希望,但并未按预期工作,将UI中的错误图片关联了起来。 即使给视图提供不同的标签和IBOutlets也不会改变情况。 我们联系了Taplytics团队以更好地了解问题。 因此,我们使用布尔变量来控制UI并将其更改为用表情符号替换图像。 然后,我们可以创建实验目标: 然后,您可以创建暴露测试的用户细分,并按特定参数进行过滤: 您甚至可以选择要公开实验的用户百分比和要进行首次展示的用户百分比: 开始实验后,您可以获取摘要和结果以衡量假设。 一段时间后,您可以声明Winning变体并将该版本部署到所有用户。 样例项目 我们的示例项目可在我们的GitHub上找到。 注意:不要忘记更改帐户的API密钥和URL方案。 更多工具和服务 其他工具和服务的列表在此处提供。 例如Optimizely,Apptimize,Lifecycle,Leanplum和Localytics。

服务器端Swift简介(工具和框架)

这篇文章旨在提供Server Side Swift开发的介绍,并介绍工具和框架。 工具类 Swift软件包管理器(SPM) Swift Package Manager是在Mac和Linux上运行的必不可少的构建和依赖性管理工具。 苹果/快速包装经理 swift-package-manager – Swift编程语言的软件包管理器 github.com 最有用的SPM命令包括: swift build以构建快速软件包 swift build -c release构建用于发布的快速代码 swift package update以更新依赖项 swift package generate-xcodeproj用于从Swift代码创建或更新Xcode项目 swift package resolve以获取所有依赖项 将来,我将发布更完整的SPM指南。 Xcode Apple提供的IDE可以编写,编译和调试Swift代码。 尽管还有其他选择可以开发Server Side Swift ,但是Xcode是最传统的选择。 Xcode –苹果开发人员 Xcode包含了为iPhone,iPad,Mac,Apple Watch和Apple TV创建出色应用程序所需的一切。 developer.apple.com 其他选项包括 文本编辑器,例如vim,Sublime Text,Atom和VS Code + SPM Jetbrains的AppCode AppCode:JetBrains的Smart Swift和Obj-C IDE 适用于iOS / macOS开发的智能IDE,专注于代码质量,高效的代码导航,智能的代码完成… […]

Swift中的功能组合

数学中一个非常有趣的概念是函数合成 ,正如名称所暗示的那样,它允许将两个函数合成。 用数学符号表示,可以写如下的方程式 f-> x:x * 3 g-> x:x + 4 h-> x:f。 G h(5)= 27 总结起来,这意味着放在组合函数中的x值将首先在右边服务该函数,并且其结果将用作左边函数的参数。 Haskell是一种可以充分利用后者的编程语言,下面是一个示例: 所以, 将返回13。 但是我们如何在Swift中实现函数组合呢? 让我们使用游乐场看看! 优先级组的唯一用途是使我们后面的“°”中缀运算符保持关联。 …函数的签名非常有趣,让我们来看一下。 我们有三种通用类型-T,U和V。我们的第一个参数f1接受一个函数,该函数接受U并返回V。但是,第二个参数f2接受一个函数,该函数接受T并返回U。我们的返回类型为一个函数本身,它采用T,因此为f2的自变量,并返回V,因此返回类型为1。这是正确的,考虑到如何在顶部解释函数的组成。 由于我们的返回类型将是一个函数,因此我们必须能够插入一个值,因此,我们是否必须使用闭包,这将说明返回后的花括号。 将要输入的值称为x,然后将我们的函数放在一起:f1取f2,x取x。 我们定义了以下两个函数,以便可以测试组成,最后一个表达式表明它有效。 我们完成了,看起来不是很优雅吗?

其他一些ReactiveKit扩展

在上一篇文章(ReactiveKit的扩展集合)之后,还有更多… 对信号的承诺 导入ReactiveKit 导入PromiseKit 扩展承诺 { 公共函数toSignal()-> Signal { 返回Signal { self.then {elem-> Void in Observer.completed(with:elem) } .catch {错误 rator.failed(错误为NSError) } 返回NonDisposable.instance } } } 在我正在从事的项目中,有一段时间,我们同时使用PromiseKit和ReactiveKit,此扩展对于将PromiseKit Promise转换为ReactiveKit信号非常有用,从而提供了帮助迁移的桥梁。 2.顺序信号 func serialSignals (_信号:[Signal ], 已完成:[ReactiveKit.Result ] = []) -> SafeSignal <[ReactiveKit.Result ]> { 守卫信号=信号。第一 否则{返回Signal.just(已完成)} 让newSignals = signal.count> 0吗? Array(signals [1 …]):[] 返回信号 .map {ReactiveKit.Result.success($ 0)} .flatMapError […]

核心图形第2部分

上一篇介绍的是线条与几何图形,但很多时候光是用几何图形是没办法做到想要的效果。首先要介绍的是渐层色,渐层色非常非常的常见,Core Graphics有中有CGGradient可以定义渐层色的颜色与比例区块: 那如何在这个色块里面增加另一个拥有渐层色的图形?现在画布是全部的范围,所以要先裁切出你需要的图形,现在addClip这个方法裁切区块: 在处理完第二个色块之后,看起来都没什么问题,但是如果要添加新的色块呢?我们尝试看加一个同木板的圆,然后把圆心位置移动: 会发现圆被裁掉了,因为现在画布就只有中间圆形的大小,所以可以编辑的区块链只有在这个圆的范围内,那如果编辑区域要超过这个被裁切过的画布,就要恢复到裁切之前,那要如何回到哪裁切之前,在裁切之前,我们使用saveGState这个方法把裁切之前的画布存起来,在用restoreGState把存起来的画布调用出来: 以上是Core Graphic比较基础的用法,当然还有很多方法,但在这边就不多做介绍。如果是太复杂的图就需要很大量的数学运算,看到这边应该都会觉得画图就是在算数学,所以如果不是图表之类需要运算的图,把找图片套入元件就好,不要把自己搞到疯掉。如果有什么想知道的方法可以留言让大家一起讨论! Nibelheim11 / CoreGraphicsDemo 通过在GitHub上创建一个帐户为CoreGraphicsDemo开发做出贡献。 github.com

适用于Objective C开发人员的30个Swift概念-扩展

因此,让我猜想,您曾经是iOS开发人员一段时间,或者自己是初级开发人员,与Objective-C一起工作,并且擅长于此,您不想在您的应用程序中使用其他任何东西,如果没有将代码放在方括号中,将无法想象您的生活。 如果是这种情况,则此博客文章适合您。 如您所知,Swift如今变得越来越受欢迎,招聘人员和公司都要求开发人员更加了解这种语言。 这是我在过去的采访中曾问过的一些主题与其他一些主题之间的简短混合,这将有助于使从Objective-C过渡到Swift的过程稍微容易一些。 1 —结构和类之间有什么区别? 结构和类之间最重要的区别之一是,结构是值类型,并且在代码中传递它们时总是被复制,而类是引用类型并通过引用传递。 而且,类具有继承,该继承使一个类可以继承另一个类的特征。 2 —值类型和引用类型之间有什么区别? 要扩展有关结构和类之间差异的答案,有必要了解值和引用类型之间的差异, 当您复制值类型时,它会将要复制的内容中的所有数据复制到新变量中。 它们是2个独立的事物,更改其中一项不会影响另一项。 复制引用类型时,新变量将指向与要复制的对象相同的内存位置。 这意味着更改一个将更改另一个,因为它们都引用相同的存储位置。 如果还不清楚,这是一个例子 3 —关键字“ mutating”在Swift中是什么意思? 我们无法在实现中直接更改值类型的值,只有在创建副本并将我们想要的值分配给新副本时,才有可能。 但是,如果要在实现中更改值类型,可以在函数声明之前使用“ mutating”关键字。它表示该方法将修改结构的值,从而允许编译器创建该结构的副本。 这是一个代码示例 4 —“静态”,“类”,“最终”关键字在Swift类型方法中意味着什么? 在类型方法中,这些关键字的意思是: static:在值类型(例如结构)中,此关键字表示方法在类型级别而不是在实例级别关联。 在引用类型中,这还意味着该方法在类的类型级别上关联,但也不允许该方法可为子类覆盖。 class:在目标C中创建类方法的方式,它们可以被子类覆盖。 final:它是方法中static的别名,但是您也可以在类声明之前使用它,以使其不可变。 对于类,通常总是使用“静态”来创建类型方法,只有在您的子类确实需要重写它时,才应使用“ class”关键字。 这是代码示例。 5 — Swift中的可选项是什么? 在许多语言中,当遇到数据缺失时,必须通过编写代码的另一条路径来处理它。 没有迹象表明数据不存在,因此在程序中的许多地方都必须编写防御性代码。 这不是Swift中的情况,可选类型是Apple处理应用程序中数据缺失的方式。 有关可选项的更多信息,请转到此处 6 — Swift中的let和var是什么? 在Swift中,var表示变量。 变量是可以更改或更改的对象。 另一方面,let表示常量,表示分配给对象的值永远不会更改。 设置完成后,就完成了。 当需要设置永远不变的值时,可以使用常量。 欲了解更多详情,请点击这里 7 — Swift中的元组是什么? 元组只是值的有序集合,出于我们的目的,它们将多个值分组为一个复合值。 为什么这很重要? 在Objective-C中,如果希望一种方法返回多个值,则有两个选择-返回一个自定义对象,该对象具有存储返回值的属性或将这些值粘贴在字典中。 […]

SKSpriteNode动画

最近,我在Flatiron学校的工作重点一直是SpriteKit。 值得注意的是,SpriteKit并未在iOS课程中教授,因此,当我和我的合作伙伴使用这种(看似)复杂的游戏引擎时,很大程度上取决于我们自己。 上周一直专注于使用SpritKit对物理进行简短的演示,但是不幸的是,我们的演示并未涉及如何使Sprite动画化它们的方式。 现在,您可能会想,“为什么要这样做?”,当谈到SpriteKit动画时,它可以很好地帮助用户传达正在发生的事情,更具体地说,是传达用户如何发生,发生什么以及他们应该如何反应。 在我们的案例中,我们有一个非常简单的跑步和跳跃游戏,我们称之为“ FlatIronMan”。 “游戏”的目标很简单,按住屏幕的时间越长,跳得越远-记录跳的长度和高度。 用户可以点击其他按钮来改变影响游戏物理的各种属性和功能。 接下来要讨论的主题是我们如何对“ FlatIronMan”精灵进行动画处理,这实际上非常简单。 为了动画化精灵,我们首先必须导入一系列带有所有可能动画的图像,以供SpriteNode循环播放。 之后,我们只需要调用某个函数即可遍历数组 func WalkingMan(runningRate:Double){ 让anim = SKAction.animateWithTextures([SKTexture(imageNamed:“ man1”), SKTexture(imageNamed:“ man2”), SKTexture(imageNamed:“ man3”), SKTexture(imageNamed:“ man4”)], timePerFrame:runningRate) 让我们运行= SKAction.repeatActionForever(anim) man.runAction(运行) } 让我快速地解释一下这里发生了什么—在声明函数时,我们传入了一个名为runningRate(这是Double值)的属性,该属性指定动画的循环速度。 然后,我们将SKAction定义为一个常量,因为无需进行任何更改。 然后,我们调用函数animateWithTextures(),该函数带有一个SKTexture数组和一个timePerFrame参数。 因此,我们使用括号格式以数组形式传入一系列纹理值,此外,我们将timePerFrame设置为与runningRate相等。 接下来,我们需要创建一个永远重复SKAction的常量(这是我们在本例中需要的常量,但是您也可以指定一定数量的迭代)。 最后,我们将SKAction附加到我们的SKSpriteNode上,瞧! 大功告成 这就是我本周的博客,希望您对SKSpriteNodes的动画制作有所了解。