Tag: swift

不要使用Swift,YET编写框架/库。

仅供参考。 如果您的框架/库是开源的并且将作为源代码发布,则可以跳过此文章。 Swift是一种年轻而强大的语言,自从2014年WWDC宣布以来,发展迅速。作为iOS应用程序开发人员,我将使用Swift构建的应用程序提交给App Store后就从Objective-C切换到Swift。 但是用Swift制作框架而不是应用程序仅几个月,我遇到了一个严重的问题。 “使用Swift X编译的模块不能由Swift Y编译器导入:” 这是令我沮丧的问题。 我的框架是封闭源代码,因此我将代码编译并打包到框架中,然后移交给客户。 但是一些客户报告说由于上述错误,他们无法使用我的框架来构建他们的应用程序。 深入研究问题之后,我意识到除非应用程序的构建环境(Swift版本和Xcode版本)与Swift框架所构建的构建环境完全相同,否则无法对其进行编译。 那是因为Swift尚未在ABI上稳定。 Swift尚未在ABI上稳定。 ABI(应用程序二进制接口) 您听说过ABI吗? 坦白说,我还没遇到这个问题。 那么,什么是ABI? ABI是应用程序二进制接口。 您必须熟悉什么是API(应用程序编程接口)及其用途。 ABI是API的低级版本,它定义了两个二进制模块之间或通常在问题及其操作系统之间的接口。 与API相比,这是对ABI的很好解释。 简而言之,通过在OS中具有稳定的ABI,为较早版本的OS编写的程序仍可兼容并在较新版本的OS中运行。 但是Swift不是ABI稳定语言,这意味着Swift标准库没有嵌入OS中。 而是将它们嵌入每个应用程序中。 您可以在Xcode构建设置中看到“ Always Embed Swift Standard Libraries选项,如果在Objective-C项目中启用此选项,则应用程序的大小将增加几兆字节。 因此,通过要求在每个应用程序中嵌入Swift标准库,即使Swift不是ABI稳定的,iOS应用程序也可以避免兼容性问题。 Swift 5有望具有ABI稳定性 为什么Swift无法稳定ABI? 这是因为Swift仍然是一种过早的语言,它通过频繁的版本更新来进行许多更改和验证。 如果该语言在太早的阶段就定义了它的ABI,那么就不能以这种方式迅速地开发和改进它。 但是在今年,随着Swift 5的更新,它有望为ABI稳定做好准备。 之后,我们可以使用Swift自由编写框架,库和SDK! 好极了! 我的解决方案? 遗憾的是,我没有时间等待Swift 5🙁我可以做出3种选择。 为每个客户的构建环境构建框架 将其设为开源并按源代码进行分发 用Objective-C重新编写 我的选择是? 第3条。将Swift代码重新编写到Objective-C并不是一件繁重的工作,但是切换回旧的和缺乏安全性的语言感觉很糟糕。 实际上,我在翻译工作中没有犯错。 将为此写单独的帖子。 TL; DR Swift正在开发尚未稳定的语言。 因此,您不应使用Swift编写框架/库,因为它可能与客户的应用程序不兼容。 […]

使用Swift在iOS应用程序中使用Microsoft Text Analytics API的循序渐进指南

2.如图所示,单击“ 创建资源 ”。 3.之后,您将看到以下屏幕。 4.如图所示,选择AI + Machine Learning ,然后单击Text Analytics创建Text Analytics服务。 5.您应该看到Microsoft文本分析的创建页面。 5a。 我想解释几件事。 首先,订阅字段可能会有所不同。 如果您已经有MSDN订阅,则您应该具有与我相同的价值。 如果您是使用免费试用版的新Azure用户,则应在订阅字段上看到“ 免费试用版 ”值。 5b。 在位置字段中,选择离您最近的位置。 我的情况是东南亚 。 5c。 对于定价层,这非常重要,因为您不想选择付费的定价层。 确保您选择与我相同的值“ F0(每30天5K交易)”,因为这是一个免费的定价层,因为此应用程序只是一个演示应用程序。 5天 对于资源组,只需选择create new并使用与应用程序名称相同的名称,本例为“ MyFirstTextAnalyticsApp ”。 6.单击创建按钮创建此服务,一旦创建了文本分析服务,您应该会看到一条弹出消息。 7.单击导航窗格左侧的“ 所有资源 ”,如上图所示。 8.单击您刚刚创建的服务,如上图所示,即“ MyFirstTextAnalyticsApp ”。 9.单击左侧导航窗格中的“ 密钥 ”以访问您的API密钥。 10.记下“ KEY 1 ”,并将其存储在某个地方(例如记事本),因为以后需要使用它。 请注意,您的钥匙应该不同于我的钥匙。 在这种情况下,请使用您自己的API密钥,请不要使用上图所示的密钥,因为它将无法工作,因为我将撤销它们。 11.单击“ 快速入门 ”,如上图所示。 然后,记下您的API端点(如上图所示)突出显示并将其存储在某个地方(例如记事本)。 在这种情况下,您的API端点可能与我的API端点不同,因为我的端点是“ southeastasia.api.cognitive”。 如果您选择的位置是美国西部,则您的API端点应类似于“ […]

在设置应用iOS中将用户重定向到您的应用设置

如果您正在寻找将用户重定向到设置应用程序以启用位置服务,通知,siri或适用于您应用程序的任何设置,那么您来对地方了。 让我们看看如何用很少的代码行来实现这一点。 只需将以下代码复制粘贴到Swift 4.2的任何按钮操作方法中即可。 它所做的全部都是向UIApplication.openSettingsURLString打开的,UIApplication.openSettingsURLString是一个NSString,其中包含原始应用程序的捆绑包ID,在这种情况下为您的应用程序。 编码愉快!

TinySolution:解决枚举的限制

此文章同时提供中文版本: TinySolution:解决enum的限制 Swift的enum比Objective-C强大得多。 我们可以基于具有不同参数的各种类型创建案例值,这在不同状态或对象具有不同数据类型的情况下很有用。 例如, Result类型非常有用。 顺便说一句: Result类型将在Swift5中正式支持。 ( SE-0235 ) 尽管enum功能强大,但仍有一些限制。 例如,我们经常需要绘制两条具有自定义线宽的实线和虚线。 目前,我们可以使用enum来实现。 在实际项目中,事情从未如此简单 除线宽外,虚线还需要支持自定义的虚线宽度和空格。 当然,我们可以将Line更改为以下格式: 问题已解决,但是大多数虚线使用相同的虚线宽度和空格。 我们不想每次都手动传递相同的值,因此我们尝试使用默认参数: 不幸的是,编译器告诉我们enum不支持默认参数。 但是我们在Objective-C上长期存在这种限制,并且我们熟悉如何以其他方式实现默认参数。 所以我们改为: 编译器告诉我们一切正常。 三个case对象的创建也成功。 那么问题解决了吗? 至少看起来是这样。 怪现象 当您开始编写switch方法时,事情并没有按您预期的那样工作。 例如,我添加了output()方法,并出现警告: 似乎前一个case dash(…)包含后一个情况的所有情况。 考虑到这一点,让我们交换一下: 但是,仍然出现相同的警告。 似乎这两种case dash(…)与编译器完全相同,因此我们无法找到确切的case 。 如果这是所有问题,那么这种实现在某些情况下仍然有用。 不幸的是,事实并非如此。 让我们根据Line的最后一个实现编写一些测试: 您可以看到Line.dash(width:1)被判断为default ,并且不属于Line.dash 。 因此,这种工具已经是一个例外。 后一种case将覆盖前一种情况。 前者只能创建而不能由switch判断,因此基本上这种case是没有用的。 也许这是一个Swift错误? 请告诉我你是否知道。

Swift中的Singleton。

什么是单身? 如何使用Singleton类? 为什么单身人士不好? Singleton是iOS应用程序开发中广泛使用的设计模式之一。 单例很容易理解,并且可以保证只创建一个类的实例。 尽管已被广泛接受,但由于某些陷阱,单例也被称为反模式。 苹果在框架本身内部提供了许多单例API,例如: UserDefaults,FileManager,AppDelegate,UrlSession等。 Swift为Singleton提供了一个非常简单的实现。 //在应用程序中初始化并使用singleton类。 不要忘记将init设为私有: 使用上面的实现,您可以创建单例类并在您的代码中使用,但是如果您看到上面的代码,则会注意到,我已经创建了一个实例,并使用相同的实例(而不是共享实例)调用了该函数。 使用以上实现,您可以创建违反单例概念的同一类的许多实例。 创建单例的正确方法:初始化程序访问级别需要更改,例如– //立即更改启动器访问级别 私人初始化 (){} 现在,如果您尝试创建相同单例类的实例,则编译器将抛出类似..的错误。 您的单身人士班级应该看起来像…… 为什么Singleton在ios应用程序开发中如此受欢迎: 苹果本身背后的主要原因。 苹果在API中使用了很多东西,因此作为开发人员,我们始终会研究并遵循苹果标准。 另一个原因是易于访问,因为基本上可以从任何地方访问单例对象。 为什么Singletons不好: 由于对象的全局可访问性,单例易于使用,但是具有对单例对象的全局访问权限不过是单例模式的副作用。 通过使用单例,您几乎总是为了方便而牺牲透明性,因此将单例与依赖注入相结合总是一个更好的主意。 结论: 现在,您已经了解了如何创建Singleton类。 它有一些优点和缺点 。 如果您在项目中使用更多的Singleton模式,则很难管理Singleton类的生命周期。 而且,它保持全局可变的共享状态。 尝试更好地避免过度使用Singleton模式,以使用依赖项注入。 我将介绍依赖项注入,以及为什么很快我的下一个主题中的单例很差。 谢谢阅读!

世界走向斯威夫特

作者:Tamir Avrahamov公司。创始人 Gini-Apps (linkedin.com/in/tamiraaa) 2014年6月2日,Apple宣布将Swift语言作为Apple操作系统的编程语言,当然,还宣布了IOS的本机语言,IOS是iPhone和iPad的操作系统。 Swift语言是这里取代以前的语言-Objective C的一种 ,它采用更安全的编程模式,添加了现代功能,使编程更轻松,更灵活且同样重要,它更加有趣。 苹果一直致力于开发快速编程语言,直到大约两年前才向开发人员发布。 重要的是要了解语言不会轻易死亡。 目标C仍然存在于Apple代码的许多部分中,并且将始终存在,但是受困并依赖于过去技术的应用程序和开发将变得难以维护并最终消失。 那么我们应该继续使用其他语言吗? 如果是这样,什么时候? 当然,与苹果一起前进总是值得的,并且不建议忽略苹果公司对开发环境带来的任何变化,并且在过去几年中带来了很多变化。 这些更改带来了对新设备中新分辨率的支持,更好的性能,应对图形挑战的工具以及界面,这些操作从一开始就很复杂,现在变得更易于实现。 在某些情况下,目标C功能已被弃用,Apple或任何其他第三方提供了更新和更快的方法/算法以供快速使用。 您可以看到Apple工程师进行的比较,并可以更清楚,更明显地看到性能: 没有简单或魔术的方法可以快速转移到Swift。 您必须投入大量的精力,采用更安全的编程模式,甚至还要考虑新的设计,因为唯一的方法是重写您的应用程序。 是的,是时候了,这也是Swift Ver。的好时机。 3.0被认为是稳定且安全的实施。 除此之外,我认为最重要的原因是程序员。 在过去的两年中,世界各地的大学都在教授Swift,从那时起,新的Objective C开发人员还没有进入工作岗位。 开发者社区非常喜欢swift,以下图表说明了Swift被爱了多少(堆栈溢出): 那你从哪里开始呢? 有很多方法可以实现和重写代码,因此正确地计划,升级应用程序功能,以习得的方式设计代码体系结构非常重要,因为Swift可以在这里保留很多年。

使用协议扩展管理网络状态

内容? 载入中? 错误? 空吗 丢失… 今天早上,我打开了苹果的音乐应用程序,用一些歌曲抚慰了我的耳朵。 但是,当然,作为iOS开发人员,我更倾向于研究该应用程序的功能。 我发现的是应用程序处理状态更改的微妙方式。 因此,吸引我去寻找在应用程序中处理网络状态的最佳方法。 假设我们正在构建一个管理四个状态的应用程序,即: 1.内容:数据呈现给用户 2.加载:正在通过网络加载数据 3.错误:通过网络加载数据时遇到错误 4.空:无可用数据显示给用户 出现的问题是:我的代码可重用吗? 我是否遵循DRY原则? 如果我有不同的方法来管理不同类中的状态怎么办? 代码 重构容易吗? 如果您的回答是“否”,则可以参考“解决方案”,否则,请选择意大利面。 解决方案 在WWDC 2015上,Apple推出了面向协议的编程。 它具有最强大的功能: 协议扩展。 等一下你说什么 现在,到底是协议扩展 。 如果您不熟悉此概念,请参阅以下链接: https://www.raizlabs.com/dev/2015/06/protocol-extensions-swift-2-0/ http://machinethink.net/blog/mixins-and-traits-in-swift-2.0/ http://cutting.io/posts/stateful-mixins-in-swift/ 快速看一下演示 让我们从协议开始 我们有一个名为ViewStateProtocol的协议: 让我们来谈谈它。 我们有一个状态管理器类实例(管理添加和删除视图的类),加载,错误和空视图,错误消息和以States Type为参数的方法声明addView (包含各种状态的枚举) 现在,让我们对协议扩展进行一些魔术。 首先,我们创建了一个状态管理器类的实例,该实例负责添加和删除视图。 然后,我们创建加载,错误和空视图对象。 太棒了! 但是,我们仍然需要将这些视图添加到视图控制器的视图中。 那么,该怎么做呢? 没问题,我们有州管理人员来救援。 State Manager类将负责添加这些视图。 好极了! 我们做到了。 但是,等等,我们的State Manager类在哪里。 我们也来看看… 因此,我们拥有所有视图的默认实现。 但是我们如何实施呢? […]

使用Kitura在Swift中进行全栈编程

Swift成为了完全开放源代码(Apache 2.0许可)项目,并且走得更远,这使得Swift不仅可以在Darwin设备上运行,而且可以在Linux和其他平台(例如Android,raspberry-pi,大型机)上运行。 所有繁重的工作都是由Swift社区完成的,以使Swift可以在Linux和多个平台上使用,并且还在不断增长。 这意味着在大多数平台上都可以使用Foundation API,Swift语言,所有标准库以及用于并发的Dispatch。 现在大约有数十种可用的框架,包括IBM的Kitura,PerfectlySoft的Perfect,基于Swift语言的Q理论的Vapor。 为什么选择Swift? Swift是Java之类的高性能语言 Swift的内存使用率低 重用客户端代码,工作空间,工具和组件可以加快开发速度并提高生产率 IBM的Kitura Kitura是使用IBM开发的Swift语言编写的服务器端模块化框架。 Swift语言主要用于为Apple App Store创建基于iOS的应用程序。 开发人员必须为Java,Python,Ruby等后端编程选择不同的语言,基于Swift的客户端可以将其连接以进行CRUD操作。 Kitura使iOS开发人员更容易使用一种语言进行前端和后端编程,并创建完整的应用程序。 Kitura框架的重点 基于模块化和打包的Web框架 开箱即用,并利用Foundation API在macOS和Linux上创建应用程序。 Swift具有高性能,安全性和表现力,因此具有Kitura的特质。 轻松部署到IBM Bluemix和Watson集成等云平台,以创建Cognitive应用程序。 Xcode支持可实现更快,更轻松的开发 Yeoman生成器可在几分钟内创建和部署您的应用 全栈演示 使用ServerSide Kitura,IBM Watson和IoT平台控制由PI驱动的机器人 我们将为Raspberry PI驱动的机器人创建一个Remote,并使用服务器端Kitura作为中间件。 该机器人还将与Watson Text-To-Speech服务集成在一起。 遥控器将能够控制机器人的两件事: 输入文字让机器人说出来 选择一种颜色让机器人闪烁 建筑 遥控器使用swift构建并运行在iOS设备上。RobotRemote Control应用程序使用公开的REST API与基于Kitura的服务器进行通信。 该服务器具有CRUD API以及一个接受远程输入并将其发送到IBM IoT平台的API。 服务器上的API从远程应用程序接收JSON数据,并以MQTT消息的形式发布到IoT平台。 服务器使用Aphid MQTT客户端将消息发布到IBM IoT平台上的某个主题。 该机器人是使用raspberry-PI构建的。 LED和扬声器已连接到raspberry-PI。 PI运行一个nodejs应用程序,该应用程序正在侦听来自IoT平台的MQTT消息,该主题与基于Kitura的服务器发布消息的主题相同。 接收到MQTT消息后,将使用Watson开发人员云SDK将接收到的文本转换为语音,并将其通过管道传输到安装在raspberry-PI中的扬声器。 树莓派PI还运行Python代码,将正确的颜色信号发送到LED,使其闪烁。 创建远程机器人服务器 先决条件: […]

Swift解决方案:装饰器模式

Swift Solutions是涵盖设计模式的一系列文章。 在每篇文章中,我们讨论该模式是什么,何时应用以及如何以Swifty方式实现它。 在Swift解决方案的此迭代中,我们将在Swift中实现Decorator Pattern。 该模式提供了一种向应用程序添加功能的有用方法,并且是每个开发人员都可以在其套件中使用的出色工具。 我们将在方法上做到周密,以免材料发粘。 我们将在Swift中定义,说明和编码模式。 最终,您将了解该模式是什么,何时应用以及如何编码。 让我们直接进入定义! 限定 装饰器模式可动态修改核心对象的行为,而无需更改其现有的类定义。 装饰器模式有两个主要组成部分:一个将修改其行为的核心对象,以及一个在核心对象中带来更改的行为的装饰器对象。 这两个组件可以共同实现两个主要目标: 行为修改 …动态实现 行为修改 该模式的目的是在不修改其现有类实现的情况下更改核心对象的工作方式。 这是通过用装饰器包装核心对象来实现的,装饰器可以增强核心对象的默认行为。 装饰器从字面上完全“装饰”(修改)了它们包装的对象。 装饰器增强了核心对象中已经存在的行为。 它们与核心对象共享相同的接口,但提供不同的实现。 结果,客户端无法区分是使用装饰器还是使用核心对象:它们在两者上调用完全相同的函数/属性。 此共享接口允许装饰器充当中间人,拦截对核心对象的调用并为客户端提供自定义行为。 动态修改 装饰器不只是简单地修改行为,而是动态地修改行为。 换句话说,它们更改了对象在运行时(而不是编译时)的工作方式。 编译时行为修改很简单:只需要​​直接更改对象的类定义或子类并覆盖其默认实现即可。 但是,由于以下原因,可能不希望使用这些选项: 可以将核心对象类声明为final ,这可以防止子类化。 该类可以在第三方框架中定义,对它的任何更改都将在下一次框架更新时丢失。 可能存在许多所需的修改,并且可以将几种行为链接在一起以产生复杂的组合。 为每种可能的组合创建一个子类将导致类爆炸。 对现有类的更改可能会导致意外的副作用,从功能中断到崩溃。 当继承脆弱且未完全理解的旧版代码库时,尤其如此。 所有这些缺点使动态方法成为有吸引力的替代方法。 我们没有将具有不同行为的核心对象的多个变体硬编码,而是将每个行为分成了自己的专用包装器类。 然后,通常在用户输入期间,将这些专用包装器在运行时应用于核心对象。 用户选择他们的自定义项,然后我们应用包装器以产生所需的结果。 这是一种灵活的方法,因为行为的组合是通过根据需要增量应用包装器来实现的。 说明 我们将使用赛车游戏作为插图。 在此游戏中,玩家在每次比赛前选择车辆。 选择后,他们可以自定义车辆的轮胎,变速箱,发动机等。 这些自定义通过更改其统计信息来影响车辆的行驶方式。 在我们的示例中,统计信息将是速度和牵引力。 玩家可以选择更换零件以更好地适应他们的喜好。 例如,玩家可以选择将默认轮胎更改为越野轮胎,这些轮胎的抓地力更好,但速度却有所降低。 实行 让我们使用赛车插图来实现该模式。 protocol Transporting { func […]

消除iOS WebView中“输入文件”标签的错误

当使用 html标签在WebView中打开系统照片库时,存在一个SDK错误将dismiss当前显示的视图控制器。 当您单击系统提供的警报控制器时,出于某种原因(可能是SDK错误),将调用两次dismiss功能。 因此,如果显示WebView或根视图控制器而不是将其推送,则可以通过navigation推送将其关闭。 怎么解决 使用push而不是present 使用自定义navigation嵌入WebView并override dismiss方法