Tag: swift

使用ALRT轻松创建UIAlertController

Dejavu? 您需要不时创建一个UIAlertController。 经过几行之后,您开始意识到自己之前已经编写了类似的代码。 编写步骤并不困难, 但乏味而乏味 。 这就是为什么几年前我创建ALRT的原因,它是UIAlertController的一种更简单的构造函数。 ALRT如何工作? 让我们通过示例来指导您。 典型的步骤就是这样。 使用ALRT,您只需一行即可获得相同的结果。 用法页面涵盖了其他常见的用例。 如何开始? 迦太基和可可足都被支持。 迦太基 github的“ mshrwtnb / ALRT”〜> 1.3.2 椰子足 吊舱回购更新 pod’ALRT’,’〜> 1.3.2′ – 享受ALRT https://github.com/mshrwtnb/ALRT

iOS开发课程:照片库隐私

如何从照相馆获取图像? 什么是隐私说明? 让我们做一个简单的项目来演示它的实际作用。 创建一个新的Single View App项目。 热键:shift + Command + N NSPhotoLibraryUsageDescription ( String – iOS)此键可让您描述应用访问用户照片库的原因。 当系统提示用户允许访问时,此字符串将显示为警报的一部分。 尽管此密钥控制着对用户照片库的读写访问,但是如果您的应用程序仅需要向资源库添加资产并且不需要读取任何资产,则最好使用NSPhotoLibraryAddUsageDescription。 重要说明:为了保护用户隐私,在iOS 10.0或更高版本上链接的,访问用户照片库的iOS应用必须静态声明这样做的意图。 在应用程序的Info.plist文件中包括NSPhotoLibraryUsageDescription键,并为此键提供目的字符串。 如果您的应用尝试在没有相应目的字符串的情况下访问用户的照片库,则应用将退出。 那是许多可可隐私密钥之一。 阅读更多 苹果开发人员。 打开主板 如何将元素添加到情节提要? 只需按: Shift + Command + L – 找到UIButton,将其拖动以在故事板上查看– 打开拆分模式 –在按钮上按ctrl并将光标拖动到代码 打开ViewController.swift文件。 修改文件中的代码。 选择图像并查看控制台输出。 图像尺寸:(4032.0,3024.0) 是的 我们有一张图片。 有什么用呢? 这是你的选择。 你完成了! 拍! 拍! 请记住,成功的秘诀是不断学习和与同事沟通,包括自我教育。 这是有关照片库隐私的小指南。 在Apple Developer网站上了解更多信息。 不要停止自我教育。 GitHub项目 订阅我的帐户以获取有关新故事的通知。 […]

苹果电视案例研究:我们如何保持领先地位,以及我们在此过程中学到的知识

今年早些时候,苹果公司在主题演讲中向全球观众分享了我们的PLUS7应用程序,以作为卓越典范,这是工程团队引人入胜的旅程的结晶。 当Apple宣布推出第四代Apple TV时,我们知道它将非常适合扩展我们的PLUS7产品。 Apple TV简单而优雅的体验非常适合以允许用户直接获得所需内容的方式进行设计。 基于我们对iOS和现有Apple框架的了解,开发tvOS应用程序的过程非常迅速,并且确实使我们的工程师能够在更大的屏幕上重新定义PLUS7观看体验方面取得突破。 迅速 随着Swift仍在不断发展,选择使用它并不是没有一定的风险和开销。 经过评估,我们认为它已经足够成熟,可以在生产应用程序中使用,这将是我们前进的道路。 尽管我们可以从iOS实现中重用Objective-C代码,但我们还是决定从头开始,并且tvOS构建中的代码是100%Swift。 我们现在认为这一决定是一个好决定; 甚至我们的测试版本也非常稳定,并且代码行比其iOS版本少得多。 此外,我们现在可以在iOS版本的未来版本中使用可以说更好的Swift代码。 建造 我们最初有一个应用程序的原型版本,该应用程序是在业余时间构建的,没有设计团队的投入。 最终,随着构建的进行,迭代了该版本。 我们遇到的主要问题之一是与tvOS或位码不兼容的第三方SDK。 有了一点点建议,我们就能解决其中的大多数问题,但我们用于视频广告的SDK除外。 广告 在iOS和Android上,我们使用Google的IMA SDK进行视频广告,目前与tvOS不兼容。 显然,在没有视频广告的情况下针对苹果电视推出PLUS7对我们的业务而言并不是可行的策略。 因此,我们决定自己在Swift中实施VAST规范。 我们看了一些(旧的)开源VAST实现,不幸的是结果证明不合适。 乍一看,VAST实施看起来相当简单。 但是,事实证明,这比乍一看要复杂得多。 视频包含“提示点”,这些提示指示何时播放广告时段。 有三种类型的广告集: 前片(在流之前播放),中片(每个视频在流中间播放几个)和后片(在流之后播放)。 每个提示点都映射到一个广告“ pod”。 广告连播由许多广告组成。 因此,第一个预卷可能包含一个15秒的广告。 第一个插播广告连播可能包含4个不同长度的广告(15到60秒之间),接下来的5个不同长度的广告,依此类推。 视频开始播放时,我们进行一次查询,该查询返回每个广告连播中的每个元素。 但是,每个广告都是对广告服务器的递归广告调用,您必须不断查询它,直到获得实际的广告素材。 第一台广告服务器可能没有内容,但会转到另一台广告服务器,依此类推。 另外,遍历的每个广告服务器将为播放期间可能发生的每个事件(例如,播放,播放,暂停,停止等事件的每个四分位数)添加自己的跟踪URL。 此外,沿着特定路径向下移动广告服务器可能会导致无限循环(!)或播放错误,在这种情况下,将应用特定规则。 正确执行VAST规范至关重要,因为我们的业务收入取决于此。 在1.0版的开发上花费的大部分时间都花在了这项工作上。 视频播放器 在向用户提供无缝体验的同时播放内容和视频广告(是独立的视频流)并不是一件容易的事。 每个视频广告都会提前获取,存储在列表中,然后传递给tvOS API提供的视频控制器。 在每个广告序列之后,在不同的控制器中暂停和恢复内容。 向前寻找一个或多个“提示点”意味着我们必须在广告连播中播放最后一组广告,依此类推:如果足够耐心的话,用户也可能会进入帖子列表。 我们会尽力提前获取所需的数据。 只要我们有足够的信息来播放预告片,我们就会做,然后继续执行对特定广告的其余请求,以使用户不必等待每次广告播放时就发生这种情况。 用户界面 由于遥控器的特性,Apple TV体验具有一些独特的功能。 我们的第一个迭代具有多个选项卡的网格视图和一个主视图/详细视图。 它起作用了,但是有一个明显的缺点,就是必须过度垂直滚动才能简单地浏览。 得到反馈(并亲自使用该应用程序)后,我们大大简化了导航,并在主屏幕上创建了多个水平滚动收集视图,并在“搜索”屏幕上快速过滤了已知内容。 […]

苹果收购BuddyBuild。 哦,我的Xcode服务器!

最初发布于XCBlog。 在这里阅读 我没想到这将是我2018年的第一篇博客文章。在假期里,我读了“ Apple Buys BuddyBuild”的推文,使我大为震惊,我眨了眨眼,再次阅读了这条推文。 我迅速检查了BuddyBuild的Twitter句柄,没有任何鸣叫,在Google上进行了搜索,发现Tech Crunch,CNBC和BuddyBuild博客确认了此消息。 考虑到我在iOS DevOps和CI / CD上所做的工作,对于我来说,这个消息无疑是令人振奋的消息。 我拿起电话并在Twitter上向丹尼斯表示祝贺。 不久之后,我亲自认识了BuddyBuild团队,并把一包T恤交付给我,以参加我在iOS CI Olympics 2017上的工作。 2017年10月的聚会。 我在运行iOS CI Olympics 2017时与BuddyBuild联系。我对iOS持续集成和持续交付充满热情,我用20种不同的标准对基于云的iOS 5前5名服务进行了Olympics,BuddyBuild成为了赢家。 您可以在此处阅读系列博客文章 介绍性博客文章中提到了iOS CI奥运会的目的和规则。 玩家表现之一:BuddyBuild 玩家表现二:Bitrise 玩家表现三:TravisCI 玩家表现四:Nevercode 玩家表现五:CircleCI iOS CI奥运会获胜者公告 最终的奖牌如下所示: BB = BuddyBuild BR = Bitrise TC = TravisCI NC = NeverCode CC = CircleCI 在评估过程中,我得到了BuddyBuild团队的大力支持,以了解BuddyBuild的关键概念和工作方式。 随着BuddyBuild成为获胜者,他们将奥运会的结果发布在BuddyBuild博客上iOS持续集成与部署比较 BuddyBuild给我寄了一些T恤,我把它们分发给Yoox Net-A-Porter的同事。 尽管我非常喜欢BuddyBuild,但由于我们使用TravisCI,所以我从未尝试将其用于正在处理的项目,并且我已经建立了完全自动化的端到端管道,以使用Fastlane将iOS应用程序直接部署到iTunes Connect。 […]

跨平台移动开发第三部分-iOS

现在,我们已经完成了在Android平台上设置和实现C ++代码的工作。 我们将从中断的地方继续,我们将尝试在iOS上运行代码! 如果您不知道Djinni是什么,请查阅第一部分的介绍和设置。 如果您想知道如何在Android上使用它,请查看第二部分以了解Android实现。 Apple的iOS一直使用Objective C作为主要语言来编写其应用程序,并且与C和C ++很好地集成在一起。 自从Swift语言发布以来,将Objective C代码集成到Swift还是相当容易的,反之亦然。 因此,即使没有Djinni,将C ++代码和Objective C链接起来也似乎很简单。 但是,我们仍然需要编写Objective C ++代码以将C ++链接到Objective C和Swift。 而且它仍然是相当复杂的代码。 Djinni消除了自己编写Objective C ++的痛苦。 动手 首先,我们将在项目根目录中创建一个名为iOSApplication的文件夹,如下所示: CPP计算器 | |-生成 | -src | -Android应用程序 | -iOSApplication * 之后,让我们启动Xcode并创建一个新的Xcode项目 选择单视图应用 将CalculatorApp设置为产品名称。 为了方便起见,我们将选择Swift作为首选语言。 并将您的项目放在刚创建的文件夹中。 我们将有一个空项目。 现在,您将必须在项目中创建几个组。 这是Bridge , Djinni和CalculatorImpl 。 第一组,我们将其命名为Bridge,用于生成的Objective C ++代码。 第二组我们将其命名为Djinni,以容纳Djinni支持库,第三组是CalculatorImpl,用于放置在第一部分中创建的所有C ++代码。 我们将从将Djinni生成的Objective C和Objective C ++代码复制到Xcode的Bridge组中开始。 将弹出一个对话框,询问我们是否要创建Bridging-Header.h文件。 […]

我刚开始学习iOS时希望有人告诉我的5条提示

由Johann Kerr | SWARM开发人员 考虑进入iOS应用程序开发领域,但不确定从哪里开始? 你不是一个人。 该过程可能令人生畏,尤其是在从多种语言,框架和最佳实践中进行选择时。 如果您需要一些建议以帮助您快速开始学习,或者需要一些鼓励以保持势头,那么这里有5个提示。 提示1:学习Objective C和Swift。 如果您想为iOS编程,但又不能决定要学习Objective C还是Swift,请不要浪费时间,不要仅仅因为它更简单而选择Swift。 虽然目标C已有25年历史,但现实是它不会很快消失。 许多公司仍然在Objective C中有代码库,许多iOS和OS X框架都是用Objective C编写的。如果仅学习Swift,就会处于不利地位。 此外,同时学习两者将使您成为更好的开发人员。 当我第一次学习为iOS编程时,我不必选择一种语言,因为Objective C是唯一的选择。 我记得很不情愿地步履蹒跚,发现它是一种丑陋,令人沮丧的语言。 Swift在2014年6月问世时,我立即为找到一种更快,更直观的语言而感到欣慰。 我爱上了Swift简洁明了的语法(即,不需要用分号分隔语句),并赞赏了它与Obj-C相比的许多优点,例如其简洁性,速度以及处理内存管理的能力。 Swift中的编码使我更容易学习和体验快速看到工作成果的快感。 不用说,我立即跳船,没有回头。 …直到我开始在SWARM工作并意识到目标C仍然很重要。 尽管Swift似乎是大多数项目的首选语言,但我们确实会使用现有应用程序来吸引客户,并且这些应用程序通常是用Objective C进行编码的。此外,遗留库也位于Objective C中。我发现自己按顺序浏览了旧教程赶上我原本会迷路的语言。 因此,请帮自己一个忙,同时学习Objective C和Swift。 您永远不知道何时需要它。 尽管Swift可能是未来,但我们还不能放弃ObjectiveC。 提示2:情节提要,笔尖或代码? 学习全部三个。 当我第一次学习如何为iOS编程时,我观看的每个视频教程都使用Storyboard来布局多个应用程序视图以及它们之间的过渡。 结果,我习惯了在每个项目中都使用Storyboard,并避免以编程方式创建视图,因为Storyboard似乎是标准。 甚至我也忽略了使用Nibs(或Xibs),因为Storyboard似乎囊括了所有使用Nibs的优点。 但是,当我从SWARM开始时,我很快就了解到故事板不一定是通过iOS应用程序以图形方式显示用户路径的最佳方法。 我必须努力学习这一点,因为刚开始我要负责开发新的Apple tvOS,并且每当我尝试触摸Storyboard时,Xcode beta都会崩溃。 我意识到我的团队没有使用情节提要,而是使用原始代码构建了几乎所有项目视图。 故事板非常适合小型项目以及处理诸如主从视图集或用于身份验证和注册的视图集之类的事情。 与团队一起处理较大的应用程序时,情况并非如此。 大型情节提要板可能难以浏览和维护,并且在多个开发人员需要处理同一文件时变得更加困难。 想象两个或两个以上的开发人员试图创建视图并同时提交? 考虑版本控制冲突。 kes! 现在,我在SWARM工作了近10个月,我开始欣赏以编程方式精心布置iOS应用程序所带来的美丽和简单。 尽管它可能需要一些额外的击键,但它使我可以完全控制自己的创作。 我的建议:学习故事板,笔尖和代码以创建视图。 它不仅可以为您遇到的任何类型的系统做准备,还可以使您认真思考布局视图的方式以及如何在不同屏幕上重用这些视图。 提示3:不要仅仅依靠椰子。 DRY“不要重复自己”是程序员之间为避免重复代码而使用的常见开发格言。 […]

斯威夫特预期为零,不是

我的单元测试失败。 它想要nil但得到了 。 我最初的反应是指责我的计算机愚蠢。 您是否期望我提供其他类型的nil ? 只有一个nil ,名字叫nil 。 但是请稍等。 电脑还不足以欺骗我们。 我做错了什么? 字典问题 这一切都很好,而且是预期的。 我遇到了问题,因为我将值类型设置为“ Any? 而不是Any 。 Swift让我的价值翻倍! 将键设置为nil 在“字典”中将键设置为nil ,它将为您删除该键/值对。 这就是上面第8行的行为符合预期的原因。 如果要在具有可选值类型的Dictionary中将值显式设置为nil ,则必须先将其包装。 当我第一次使用var dict: [String: Any?] = [“first”, nil]创建字典时,Swift会自动执行此额外步骤var dict: [String: Any?] = [“first”, nil] —它在后台为我包装了nil。 不要这样! 最后,我重构了Dictionary,使其值不使用可选参数。 必须记住的规则越少越好。 如果我对自己的代码感到困惑,那么另一个开发人员加入该怎么办? 如果您想进一步思考这个想法,请查看Tyler Johnson关于代码设计的文章。 代码应该像政治卡通一样呈现自己-充满了直率的隐喻,带有有用的标签,没有任何微妙之处。 肖恩判断 Livefront的 代码是什么样的 。

iOS开发人员进入React Native的旅程

像许多iOS开发人员一样,我对JavaScript也有不好的看法。 我记得JavaScript是一种怪异的,狂野的西方语言,其中没有两种环境是相同的。 我对JavaScript的记忆是在Xcode的本机工具远远优于Web工具的时候形成的-我们有很酷的东西,例如情节提要,自动完成,内置在开发环境中的大量反馈以及无处不在的集成库。 工装 从那时起,多年来,Web以惊人的速度取得了进步和成就,而Xcode基本上(在Swift中添加了Playgrounds)或更低(Swift重构工具)。 JavaScript语言和开发环境已经发展。 我们喜欢的Xcode的所有功能-IDE自动完成,内联文档,语法错误的即时反馈-基本上已内置于现代环境中。 故事书-基本上等效于Xcode Playgrounds-很棒(并且通过VSCode内置的Orta的扩展)。 测试中 JavaScript测试(通过Jest🃏)是另一个联盟。 它几乎是即时的,是自动的(它监视Git的更改并运行受影响的文件的测试),具有类似RSpec的语法,并且可以在每次保存时运行。 本机单元测试始终感觉像是事后的想法,以至于有些博客文章介绍了Apple发布的虚拟现代测试框架。 XCTest很棒,但是感觉就像是一个旧式测试框架。 它与JUnit几乎没有什么不同,仅限于一种setUp方法和一种tearDown方法,并且无法在保存时自动运行测试。 诸如Quick / Nimble之类的替代方案非常现代,但是,如果没有Xcode内置的第一方支持,基本功能(如运行单个测试)将丢失。 反馈回路 JavaScript的反馈循环比本地反馈快得多。 我从未从事过没有荒谬反馈周期的大型本地项目。 在某些项目中,从git clone到副本更改可能要花费整整30分钟的时间 。 增量构建可能在20秒到3分钟之间的任何时间-刚好足以失去焦点或被Twitter分散注意力。 模拟器重新启动,并且必须手动导航回控制器是很痛苦的。 输入:热重装。 最佳的反馈循环会对开发人员的工作效率和代码质量产生巨大影响。 当反馈循环很长时,编写代码的方法是如此不同 -我发现自己试图一次创建整个功能或整个屏幕,进行编译,并希望在我喝咖啡或散步时获得最好的效果。 如果以分钟为单位来计算编译时间,则无法实现真正​​的TDD。 在JavaScript允许的较短反馈循环中,我发现自己正在练习红绿重构,真正的TDD并进行实时设计迭代。 React Native的性能和“感觉” 甚至当我开始听说非本地开发环境中的改进时,我都sc之以鼻。 我记得PhoneGap应用程序感觉如何,使用Xamarin有多困难(多年来可能有所改善?)。 我记得用这些技术制作的移动应用程序感觉不对 , 他们如何缓慢滚动或过渡。 但是,尽管React Native肯定会增加一些开销,但它的性能足够快,以至于我很难知道我使用的是本机应用程序还是本机应用程序。 当涉及到需要高性能代码的事情时,您可以在React Native应用程序中本地编写该代码,这意味着您可以在99%的情况下使用更好的开发环境,更快的周期,热重装以及更好的测试。 对于其余1%的情况,很容易退回到您可能已经习惯的本机环境。 未来 React Native的未来并不像Swift的未来那样确定。 几乎没有人担心苹果会在明天,下周或明年放弃Swift,但谁知道React Native在五年内是否仍会是一个活跃的项目? 这些担心是公平的,但实际上考虑五年后的技术是没有意义的。 拉起手机。 分页浏览您的应用程序。 这些应用程序中有多少已经存在五年以上了,而在已经存在的应用程序中,最近有多少没有经过完整的重写或重新架构?

学习Swift和iOS开发第4部分:函数

函数是编程中的核心组件。 它们是构建功能应​​用程序的基础。 函数有助于使我们的代码更易读,更分隔并最终更高效。 我们可以编写一个函数来执行特定任务,然后在整个应用程序中随意重用它。 每天,大多数人都按照一套常规生活。 他们经常做的事情甚至没有考虑或意识到自己正在做。 想一想第一次醒来时的工作。 我自己知道,我滑下床,跌跌撞撞地走过房间,走到我嘈杂的电话旁,使闹钟静音。 仅此事件便包含了我每天以相同顺序执行的几个不同步骤(除非我忘记设置闹钟)。 1.唤醒警报声 2.滑下床,尽量不要意外唤醒我的妻子。 3.错开警报。 4.使我的闹钟静音。 上面的步骤是一个功能。 我一遍又一遍地(每天早晨)完成的一组步骤。 在伪代码中,这可能类似于: var awake = false var inBed = true var walk = false var alarmSilenced =否 func getUp(){ 醒着=真 inBed =假 行走=真 AlarmSilenced =真 } 函数以自上而下的方式在内部运行代码。 换句话说, awake设置为true , inBed设置为false , walking设置为true , alarmSilenced设置为true 。 但是,我的唤醒隐喻并不完美,因为我大概需要10到15秒钟才能完全醒来,走过去并使警报静音。 现代设备可以如此快速地处理函数内部的代码,即使它逐行地运行在每一行代码中,它几乎就像是立即在运行。 简单地说,函数是一种使用给定的集合或参数执行特定动作的方法。 您将在本系列稍后将完成的许多高级项目中使用它们。 但是关于功能的讨论已经足够了……让我们来写一些吧! […]

Swift iOS Pearls:广播消息

大家好,我最近开始全职使用Swift进行iOS开发,我想遵循与Android Pearls相同的系列,但是向您展示在特定时刻对我有帮助的事情,尤其是可以完成某些事情。 作为一个Android开发人员,我通常使用Helper类LocalBroadcastManager来使用Broadcast消息在活动和服务等解耦的对象之间发送消息,这些对象在不同的​​线程中运行,因此广播消息是它们之间进行通信的最佳方式。 因此,我们如何在iOS中做到这一点,特别是在Swift中…… 发送信息 为了发送消息,我们将使用帮助程序类NotificationCenter ,将获取该类的默认实例,然后使用方法post发送消息,如下所示: 让anyDataToSend = [“ full_name”:“ John Doe”] NotificationCenter.default.post(name:Notification.Name(rawValue:“ notification_key”),object:self,userInfo: anyDataToSend ) 在该示例中,我们将使用键userInfo发送notification_key ,还将参数或userInfo传递给它。 接收讯息 要获取该特定密钥的消息,我们需要订阅NotificationCenter ,并指定密钥。 首先,我们需要重写ViewController中的viewWillAppear函数,如下所示: 覆盖func viewWillAppear(_动画:布尔){} 在该方法内部,我们将预订订阅某个键的通知,并指定一个选择器以具有接收消息时的功能,请查看示例: NotificationCenter.default.addObserver(自身,选择器:#selector(handleNotification(withNotification :)),名称:NSNotification.Name(rawValue:“ notification_key”),对象:nil) 我们声明handleNotification方法如下: func handleNotification(withNotification通知:NSNotification){} 为了获得我们之前发送的数据,我们可以这样做: notification.userInfo?[“完整名称”] 您可以在与通知一起发布的字典中添加任意数量的值,这非常容易实现。 希望本文对您有所帮助。