Tag: 扩展

应用程序扩展-探索小部件

大家好,来到这里真是太好了! 好吧,如果您想知道我现在在哪里,请点击以下链接。 https://itechroof.wordpress.com/ 让我们开始吧。 iOS现在具有版本11.3(在撰写本文时),但我们将跳回到本文的版本8,并探讨引入的功能。 好吧,我们不要再拖下去了。 它称为应用程序扩展。 我们不会涵盖所有应用程序扩展,因为每种类型本身都可以是博客文章。 因此,我们将介绍“今日小工具”或最常见的“小工具”。 在这篇文章中,我们将介绍 什么是应用程序扩展程序? 它的类型 生命周期 受限制的API 今天扩展 创建Today扩展的步骤 应用程式扩充功能: 应用程序扩展提供了访问自定义功能或应用程序内容到其他应用程序(包括系统应用程序)的桥梁。 为了更好地理解,我们要说的是执行特定的任务,例如共享选项,以将内容/媒体从一个应用程序发布到另一个应用程序,或者将自定义键盘扩展名提供给其他应用程序/系统本身使用。 类型: 苹果提供各种应用程序扩展。 要浏览所有内容,可以导航至文件->新建->目标->应用程序扩展 。 生命周期: App Extension具有自己的生命周期和环境。 它与普通应用程序不同。 但是您需要了解有关“包含应用程序和主机应用程序”的知识。 包含应用程序是拥有扩展名的应用程序。 在我们的方案中,该应用将具有一个Today小部件。 因此我们的应用程序称为“包含应用程序”。 主机应用是访问应用扩展的应用。 例如,假设(包含)应用程序中有一个应用程序扩展。 现在,苹果照片具有共享功能,单击该功能会显示可以共享照片的应用程序列表。 在这种情况下,如果调用我们的应用程序扩展将照片与我们(包含的)应用程序共享,则“照片”应用程序称为“主机”应用程序。 在显示的应用程序列表中,通过单击我们的应用程序,请求将被发送到应用程序扩展。 应用扩展程序将处理请求,并在完成任务后终止。 对于上图,一旦用户按下共享按钮,主机应用就会调用应用扩展。 该扩展程序提供了将照片发布到我们的应用程序的功能。 在此过程中,应用扩展程序将在主机应用程序(在我们的情况下为照片应用程序)的上下文中具有自己的视图。 根据用户输入/请求,扩展程序会将结果返回到主机应用程序。 如果需要,扩展程序还可以执行后台处理。 请求完成后,系统将终止扩展。 由于扩展程序可以与主机应用程序通信,因此主机应用程序将向扩展程序发出请求,并且扩展程序将向主机应用程序发送响应。 应用扩展程序和包含应用程序的应用程序不直接通信。 应用程序扩展程序及其包含的应用程序通过私有定义的共享容器进行通信。 通常,当包含的扩展程序正在处理来自主机应用程序的请求时,包含的应用程序甚至无法运行。 受限制的API: 应用扩展程序无法执行长时间运行的后台任务。 限制可能因平台而异。 它可以通过AirDrop发送数据,但无法接收数据。 它无法访问sharedApplication对象。 应用扩展程序不能使用在NS_EXTENSION_UNAVAILABLE宏或类似的不可用性宏下标记的任何API。 它不能在不可用的框架中使用任何API。 它无法访问iOS设备上的相机或麦克风(iMessage扩展名除外)。 […]

在Swift中通过不同的方案在项目中实现不同的应用

在某些项目中,它们可能具有相同的骨骼,但使用不同的皮肤。 要构建这类应用。 我们可以使用这种方式来实现它们。 我们无需在实现中使用预处理器宏 。 仅使用扩展名就可以取代预处理器宏。 根据情况,它可以帮助我们的代码比以前更干净。 新建一个项目 1.创建具有单个视图的应用程序 只需创建一个您想要创建的项目即可。 对于本教程,我仅使用单一视图。 实际上我们可以创建任何类型的项目 2.与现有目标重复的目标 请记住修改我们刚刚复制的目标名称,否则该名称将带有后缀的副本 3.创建新计划 必须检查可执行文件是否遵循我们刚刚复制的目标,否则该方案将使用错误的目标 4.重命名捆绑包标识符和产品名称 修改捆绑包标识符,使我们可以通过代码库分发应用程序 5.单独的Info.plist 如果我们要进行其他设置,可以复制中继Info.plist,并根据需要进行设置 6.通过类型1实施 创建协议 // SchemeProtocol.swiftimport Foundationprotocol SchemeProtocol { var schemeTitle:字符串{get} func displayMonster() } 实现分支文件。 它从主干扩展了类,并遵循了我们刚刚创建的协议 // ViewController + SchemeA.swiftimport UIKitextension ViewController:SchemeProtocol { var schemeTitle:字符串{ 返回“方案A” } func displayMonster(){ 让imageView = UIImageView(框架:CGRect(x:100,y:100,宽度:200,高度:200)) imageView.image = imageLiteral(resourceName:“ SPROUT”) view.addSubview(imageView) […]

Swift中的扩展

我在以前的博客中使用过Extension for Label。 在那里,我在扩展中添加了所有代码,但是您为什么想在本章中知道为什么这样做,我将很清楚所有这些东西在您自己的项目中创建和使用非常容易。 什么是扩展? 扩展为现有的class , structure , enumeration , or protocol type添加了新功能。 这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模)。 扩展类似于Objective-C中的类别。 (与Objective-C类别不同,Swift 扩展没有名称。) 资料来源–苹果文件。 创建您的第一个扩展 通过写出类或Controller类(如extension和类名)的侧面, 扩展很容易创建 扩展UserModel { //您的功能 } 您可以将其用于符合协议 如果您在项目中使用表格视图,则需要使用这些方法来确认协议,但是,如果项目中以及其他协议中有很多方法,那么这将很难管理,并且大多数情况下,我们在查找代码时会遇到问题在我们班里。 在这个类中,您可以看到,这是每个这样开始开发的开发人员在开始阶段的基本代码。 如果您开始从事实际项目,这是一个很小的类,那么将有更多的功能和对象变得更加难以快速查找或检查您的代码。 现在,您可以非常清楚地看到您的代码被分为具有适当功能标识的组,其中Extension非常清楚地在此处定义了代码。 额外提示–“ MARK ”这将在文档编制过程中出现。 您可以访问此 ( NSHipster )链接以更好地理解Swift语言中的代码文档。 带扩展的代码分离 您可以借助扩展来编写属于特定协议的单独协议方法。 当您将来再次在同一个类中进行工作或进行修改时,它非常易于理解的代码。 芒果类: UIViewController { 覆盖func viewDidLoad (){ 超。 viewDidLoad () } } // MARK :-TableView数据源方法 […]

iOS分享扩展

在iOS 8版本中,引入了“共享”扩展名,它使您可以将内容共享到社交服务,例如Facebook,Twitter和其他实用程序。 在此博客中,您将学习2件事。 1.在主机应用程序和扩展程序之间共享数据 2.从扩展名打开主机应用 让我们启动基本的图像选择器应用程序,该应用程序从图库中拍摄图像并在视图中显示。 创建一个示例项目Image Picker。 现在,在Main.storyboard中,将视图控制器嵌入到导航控制器中。 将栏按钮从右侧对象库拖动到视图控制器的导航栏。 将按钮系统项目设置为“ 添加 ”。 设置按钮的选择器以查看名为“ openPhotos ”的控制器。 现在,将集合视图添加到视图控制器中,如上面的屏幕快照所示。 选择收集视图,然后在右侧选择尺寸检查器。 如图所示设置像元间距和截面插图 将其出口拖到名为“ imgCollectionView ”的ViewController类。 为名为“ ImageCollectionCell ”的集合视图单元格的自定义类添加一个新文件。 转到情节提要中,将可重用标识符设置为“ ImageCollectionCell ”,并设置自定义类“ ImageCollectionCell ”。 将ImageView从对象库中拖动到收集单元,然后将名为“ imgView ”的出口设置为自定义类“ ImageCollectionCell ”。 在“ ImageCollectionCell”中定义CellModel结构并按如下所示配置功能 重新运行应用程序,然后点击导航栏中的+按钮。 打开任何相册并选择图像。 选择后,您将关闭imagePicker并将图像添加到集合视图中。 您添加可能作为图像。 让我们继续添加共享扩展名。 要添加共享扩展名,请转至文件 > 新建 > 目标 将名称ImageShare添加到扩展名 现在,在MainInterface.storyboard中,添加一个收集视图并在单元格中添加图像视图。 设置单元格自定义类ShareImageCollectionCell并设置图像视图出口。 添加左右导航栏按钮,即: 取消和+ 。 现在,设置代表和数据源。 ShareViewController文件如下所示 […]

TinyExtension:增强固定的URL初始化

此文章同时提供中文版本: TinyExtension:优化固定URL创建 我相信当今大多数应用程序都使用网络请求,因为网络使一切变为可能。 因此, URL类应该是每个人都熟悉的。 我相信每个人都会有直接用固定字符串创建URL的经验。 毕竟,第一个请求的url地址必须直接写在代码中。 因此,我们可以像这样在我们的应用中声明第一个网络请求地址: 让媒介= URL(字符串:“ https://medium.com/@GalvinLi”) 很好,但是使用起来可能很不方便,因为URL(string:)方法返回URL? ,并且每次使用时都需要将其拆开。 URL(string:)设计为返回Optional对象,因为参数字符串不一定是有效地址,但是我们可以保证代码中固定的地址中格式的正确性,因此可以强制展开: 让medium = URL(字符串:“ https://medium.com/@GalvinLi”)! 强制拆包具有一个特征,即如果直接使用它,它就像展开的对象一样工作。 但是,当您将其分配给另一个对象时,对象类型将更改回Optional对象。 因此,稳定的方法是直接将其声明为非Optional对象: 让媒介:URL = URL(字符串:“ https://medium.com/@GalvinLi”)! 现在,我们可以轻松使用此URL对象。 减少强制展开 当定义了许多URL对象时,将有很多强制展开。 在现实世界的项目中,作为一种良好的编程习惯,必须减少强制展开。 当我们习惯于对URL(string:)进行强制解包时,可以强制解开服务器返回的某些url地址,特别是对于经验不足的程序员而言。 为了解决这个问题,我们实际上可以通过一个简单的extension实现它: 此extension仅添加了一个返回URL的初始化方法。 但是这里传递的参数有些不同,不是常规String而是StaticString 。 这是Swift标准库提供的一种类型,某些人可能不知道,所以让我们看一下文档中的定义: 简而言之, StaticString定义了一个在编译时就已知的字符串,即在我们的代码中不接受任何变量的固定字符串。 这是区分需要手动处理的URL地址和代码中的固定URL的好方法。 使用它的方法非常简单: 让媒介= URL(staticString:“ https://medium.com/@GalvinLi”) 消除力解开可以使代码更干净,更安全。 更好的实施 StaticString使代码更安全,但我们可以使其更好。 对于编译器, “https://medium.com”是一个字符串,而URL()是一个url对象。 但是对于我们来说,以https开头的字符串已经可以表示url对象。 为了使编译器也知道这一点,我们需要添加另一个extension : ExpressibleByStringLiteral是用于初始化的protocol ,专门用于=初始化。 当然,这仍然是用于StaticString初始化而不是String ,现在我们可以使用=来直接初始化url,如下所示: 让媒介:URL […]

使用扩展功能的iOS开发改进/技巧

我列出了一些小改进/窍门,可以在您的开发周期中为您提供帮助。 请随意提出您的方式,我很乐意将它们添加到此列表中。 用前缀名称的捆绑名称命名您的通知。 它始终可以帮助您避免以后出现任何名称冲突: 枚举通知{ 静态让NotificationOne =“ com.myapp”。 +“ NotificationOne” 静态让NotificationTwo =“ com.myapp”。 +“ NotificationTwo” 静态让NotificationThree =“ com.myapp”。 +“ NotificationThree” 静态让NotificationFour =“ com.myapp”。 +“通知四” } 在UIViewController和UIStoryboard扩展中添加方法以轻松访问和启动VC: 不要忘记在Storyboards的视图控制器中添加标识符。 扩展UIViewController { 静态函数onboardingVC()-> OnboardingVC { 让标识符=字符串(描述:OnboardingVC.self) 返回UIStoryboard.onboarding()。instantiateViewController( withIdentifier:标识符)为! 入门VC } }扩展UIStoryboard { 静态功能onboarding()-> UIStoryboard { 返回UIStoryboard(名称:“ Onboarding”,包:无) } } let onboardingController = UIViewController.onboardingVC() 添加方法以在两种颜色之间进行动画处理时计算中间颜色。 用例:如果用户将手指张开,并且您想根据其跨度位置为颜色设置动画。 (可以在该库中找到toRGBAComponents()和toHSLAComponents()方法,您可以编写自己的方法) 扩展UIColor { […]

Swift中的多功能名称空间

在Swift中,某些API(例如RxSwift)使用的技术将它们公开的代码限制在专用名称空间中。 在这篇文章中,我们将说明如何以最通用,最通用的方式完成此操作。 随时访问我的博客以阅读原始文章(语法突出显示更好) let myButton = UIButton() myButton.rx.tap.subscribe(…) // this is a RxCocoa kind of code 您是否想过在Swift中编写这样的代码行是怎么可能的? 这是.rx。 乍一看似乎很尴尬的部分,不是吗? 它的行为就像某种自定义名称空间。 这是变量吗? 这是内部阶级吗? 我们有一些线索可以弄清楚: 由于可以通过点符号访问。 它必须是UIButton类的成员 它作为tap等一些属性,因此它是一个数据结构 通过这两个线索,我们可以尝试创建自己的名称空间。 在以下示例中,我们将尝试向UIButton添加自定义名称空间,以显示单个函数hello 。 由于名称空间必须是数据结构,因此我们尝试使用Swift结构: struct ButtonNameSpace { func hello () { print (“Hello”) } } 到目前为止,一切都很好。 由于名称空间应该是UIButton的成员,因此我们将其添加为计算属性: extension UIButton { var nameSpace: ButtonNameSpace { return ButtonNameSpace() } } 现在,我们可以像这样使用它: […]

在Swift类扩展中使用Self

在扩展类时,将Self用作参数类型可能很诱人,但是Swift只允许在协议中或作为类方法调用的结果来使用它。 实际上,在大多数情况下,这是非final类在语义上正确的限制,除非我们要使用Self作为闭包的参数,例如考虑完成处理程序。 在这种情况下, Self用作另一个方法调用结果,这是绝对有效的选项。 我最喜欢的示例是Operation类的延续帮助器: 使用继续操作而不是完成块可以控制其执行上下文。 我倾向于在Operation子类中定义结果访问器,而我通常希望连续地访问它们。 从延续中访问操作不会引入保留周期,因为任何操作都已经拥有其依赖项。 因此,我们需要传递刚刚完成执行的块接收操作作为参数。 这在类扩展中是不允许的。 嗯,但是我们可以在协议中以这种方式使用Self ,对……救援协议! 计划是定义一个虚拟协议,使我们的类符合该协议,并扩展该协议而不是该类。 现在我们可以以类型安全的方式使用continue(on:with:)扩展和访问操作结果: 感谢您的宝贵时间,并希望本文对您有所帮助。 如果您觉得本文有用,请不要忘记to。

一个用于String和HTML的Swift扩展

收到的最常见的每日请求之一是从后端管理html字符串,以在UILabel中正确呈现它们。 在大多数情况下,iOS应用程序需要与Web应用程序共存,与UILabel相比,Web应用程序可以更有效地解析HTML。 在NSAttributedString彻底改变游戏规则之前,所有这些都是真实的。 UILabel对象还可以在其名为attributedText的属性中接受特定值: 让aLabel = UILabel() 一个标签。 attributedText = NSAttributedString(字符串:“你好,世界!”) 显然,仅将HTML文本作为此属性的值是不够的…否则就没有理由写这篇文章了。

Swift中数组的受限扩展

协议和扩展是快速发展的组成部分。 到目前为止,您可能已经使用了很多时间。 您可能出于各种原因为您的班级或结构创建了扩展。 这里我将给出一些示例,其中您可以为几个现有的类进行扩展。如果你们还记得在Objective-C上工作,那么您将与Catagories交叉。 在这里,约束扩展是一种类别,您可以在不知道其内部工作的情况下扩展现有对象的功能。 在这里,我将以数组为例,数组是同质元素的集合,在进行实时项目时,您需要处理很多需要不断操作的数组,您可以提出扩展一样的 字符串数组 让我们假设一个场景,其中您有一个字符串数组,并且需要事先存储少量数据,例如 总字符数 字数 每个单词中的字符数 让我们来看一个数组示例,如下所示 let arrayString:[String] = [“教父”,“肖申克的救赎”,“辛德勒的名单”,“愤怒的公牛”,“乱世佳人”,“绿野仙踪”,“阿拉伯劳伦斯”,“阿甘”] 现在,假设您在整个项目中具有与上述所需的实现相同的数组。 为了避免重复并扩展现有Array的功能,我们可以编写如下扩展 通过在Array上实施受约束的扩展,您可以轻松避免代码重复,并且Array操作很容易。 让我们继续测试实施 让characterCount = arrayString.totalCharacterCount() 让wordCount = arrayString.wordCount() 让eachCharacterCount = arrayString.elementCharacterCount() 打印(“ characterCount = \(characterCount)”) 打印(“ wordCount = \(wordCount)”) print(“ eachCharacterCount = \(eachCharacterCount)”)//这将打印characterCount = 128 wordCount = 22 eachCharacterCount = [13、24、16、11、18、16、18、12] 这是数字的另一个例子 这是数字数组的另一个例子 在上面的示例中,这里以计算为例 数组元素的总和 将数值数组转换为字符串数组 这可以在任何数字数组上无缝运行,但在数组中的其他元素上同样会出错。 […]