Tag: Swift编程

Swift Vs C ++:速度

如果您决定在使用Swift和C ++之间进行选择,那么性能可能就是您要考虑的一件事。 这篇文章将向您展示这两种语言的快速基准测试,以便您做出自己的决定。 免责声明! 这是一天之内用一个程序进行的一项测试。 在其他情况下,这种差异很有可能会有所不同。 另外,如果您从撰写本文之日(2019年3月6日)开始阅读此书,这两种语言的性能可能会由于更新而有所改善。 有了这一点,让我们开始吧! 测试方法 为了进行此测试,我将使用我最喜欢的程序:查找质数。 基本上,我将使用相同的算法创建一个简短的程序来确定数字是否为质数。 然后,我将使用for循环遍历从0到1,000,000的所有数字,并确定哪些数字是质数。 为了最大程度地确保准确性,我将把输出通过管道传递到wc -l以注意发现的数量上的任何差异。 迅捷程序 func isPrime(_ num:Int)->布尔{ 如果num <= 1 { 返回假 } 如果num == 2 { 返回真 } 对于2中的i .. <Int(Double(num).squareRoot()+1){ 如果(num%i == 0){ 返回假 } } 返回真 } 为我在0 … Int(CommandLine.arguments [1])中! { 如果isPrime(i){ 打印(i) } } C ++程序 #include #include 使用命名空间std; […]

在iOS第1部分中保存数据

用户默认数据库的接口,您可以在其中存储应用程序启动期间的键值对。 User Defaults类提供了用于与默认系统进行交互的编程界面。 所有iOS设备都有一个名为默认数据库的数据库,以提供用于永久保存应用程序相关数据的功能。 这样,应用程序可以访问存储的值,然后根据这些值执行逻辑。 在运行时,我们使用用户默认值对象从用户的默认数据库中读取应用程序使用的默认值(存储的首选项或值)。 用户默认值会缓存信息,以避免每次我们需要默认值时都必须打开用户的默认值数据库。 此处引用的缓存是内存中缓存,这意味着存储在“ 用户默认值”中的所有内容都会在应用启动时加载到内存中,并在应用运行时保留在内存中。 根据存储的数据量,这或多或少会影响设备性能。 当我们设置默认值时,它将在我们的流程中同步更改,并异步更改为持久性存储和其他流程。 只需在运行时更改任何存储的默认值的值,它就会从缓存同步更改其值。 从那里将其异步保存到磁盘(数据库)中,因为这类I / O(操作)有点昂贵。 →存储为默认值: User Defaults类提供以下方便的方法来访问常见类型,例如浮点数,双精度数,整数,布尔值和URL。 func set(_ value:Any ?, forKey defaultName:String) func set(_ value:Int,forKey defaultName:String) func set(_ value:Float,forKey defaultName:String) func set(_ value:Double,forKey defaultName:String) func set(_ value:Bool,forKey defaultName:String) func set(_ url:URL ?, forKey defaultName:String) 要使用具有用户默认设置的对象,该对象必须是Propertylist类型或Json类型。 例如字符串,数字,数据,日期,数组/字典。 如果我们想将自定义对象与userdefaults一起使用,则需要将它们转换为data(object)类型。 即使我们将可变对象设置为值,从UserDefaults返回的值也是不可变的。 例如,如果我们将可变字符串设置为“ MyStringDefault”的值,则稍后使用string(forKey:)方法检索的string(forKey:)将是不可变的。 如果我们将可变字符串设置为默认值,然后再对该字符串进行突变,则除非再次调用set(_:forKey:) ,否则默认值将不会反映该突变的字符串值。 例如, […]

在Swift中测试网络层-第2部分

使用XCTest框架编写单元测试用例 在上一篇文章中,我们讨论了如何编写可测试网络层。 在本文中,我们将讨论如何为该网络层编写单元测试。 基本上,要执行单元测试,我们必须知道给定输入的预期输出。 请记住,我们从来没有真正在物理服务器上运行过测试,因此我们无法测试所有可能的情况。 对于每个APIHandler,我们都有两种方法来执行测试,如第1部分所述 。 func makeRequest(来自参数:[String: Any ])->请求 func parseResponse(data:Data) 抛出 -> LoginResponse 测试API请求: 对于LoginAPI ,我们可以通过检查所有请求参数(例如http方法,http正文,url,标头字段等)来确认请求已正确准备。 测试API响应: 响应可能是成功,也可能是服务器返回的错误。 对于LoginAPI ,以下是成功响应测试用例。 我们可以如下测试服务器错误,例如状态203、400等,它们将返回ServiceError对象。

通过委托和协议在ViewController之间传递数据

我们都知道如何通过prepareForSegue方法在ViewController之间传递数据。 它有其自身的局限性和优势。 好消息是,这不是在ViewController之间传递数据的唯一方法。 在ViewController之间传递数据的最流行和最常用的方法之一是通过Delegate和Protocols。 在开始本教程之前,如果尚未开始,请阅读我关于协议的文章。 如果您了解协议,那么本文将更有意义。 与其说太多,不如让我们看一个例子,看看它是如何完成的。 让我们创建一个名为“间谍和基础”的单页应用程序。 现在删除默认的ViewController.Swift,然后再创建两个名为“ HomeBaseVC”和“ EnemyBaseVC”的ViewController。 创建ViewController之后,它应该如下所示。 现在是在StoryBoard中进行一些更改的时候了。 让我们打开情节提要,并将现有ViewController的类名称更改为“ HomeBaseVC”。 现在是时候向故事板添加另一个Viewcontroller并将其与ViewController类“ EnemyBaseVC”相关联了 现在是时候通过segue连接两个VC了。 我们将在“ HomeBaseVC”中添加一个名为“将我们的间谍发送到敌人的基地”的UIButton。 点击此按钮后,我们将进入“ EnemyBaseVC”。 (我将保留“自动布局”约束部分,因为它不是本教程的一部分) 我们将EnemyBaseVC显示为Modal(又名弹出窗口)。 还要确保segue标识符为“ sendSpySegue”。 查看下面的gif图片,了解如何完成此操作。 凉! 现在我们可以从我们的基地向间谍基地发送间谍了。 假设我们的间谍渗透了敌人的基地。 因此,现在该给他一个UIButton了,该按钮将使他能够入侵敌方通信系统并将数据传递回Home Base。 所以我要在“ EnemyBaseVC”中添加一个UIButton作为“ HACK AND SEND MESSAGE HOME” 因此,情节提要板应类似于以下内容。 在离开情节提要之前,让我们连接“ HACK AND SEND MESSAGE HOME”按钮,并创建一个IBAction。 是时候用数据设置“ EnemyBaseVC”了。 我将如下更新VC。 我希望这是自我解释。 另外请注意,我已经从VC中删除了所有样板代码,以提高可读性。 凉! 可以吗? 很棒,让我们做一些最后的调整。 发送消息时,首先关闭EnemyBaseVC。

别动摇了。 威格拉? Zaczynam wreszciekodowaćw Swift

Muszęsięprzyznać,nie est jest miłatwoz projektem,którymamstworzyćw ramach wyzwania“ Dajsiępoznać”,czyli aplikacji pod roboczymtytułem“ Domowa Apteczka”。 Mamjakiśwewnętrznyopór,byodpalićXCode和zacząćpisaćcośw Swift。 在iOS上使用nakizyćpisać进行编程,可以使用jazero教程przerobię。 Myślałem,to gdyopiszę到publicznie,pomożemi到naprawdęgorozpocząć,boprzecieżinnibędąwidzieli,żpowinienemcośrobić! Potem,dalejodwlekająckodowanie,staworzyłemnawet papierowy原型przyszłejaplikacji。 很快,您就可以在Wiszystko na nic商店购物,而在Swiftst商店购物时,您可以在Swift商店购物。 Gdynadszedłtrzecitydzień,uznałem,koniecściemniania。 Trzeba wreszciecośzakodować。 Jakzhakowaćwewnętrznyopór? Pomysł,naktórywpadłem,polegałna nie rzucaniusięod razu nagłębokąwodęi pisaniu w nowymśrodowisku(XCode),nowej platformie(iOS)i nowymjęzyku(Swift)。 Ale na stworzeniuczegośprostego,cobędziew okolicach projektu,ale pozwoliwykorzystaćteżmoje kompetencje iumiejętności。 Tympomysłembyłopoznanie podstawśrodowiskai nowegojęzyka,ale podczas pisania miniprojektu,któregozadaniembędzie: Pobranie z serwera pliku […]

通过Swift中的深层链接运行其他应用的Siri快捷方式

快捷方式结束后返回您的应用 运行快捷方式很棒,但是您可能已经注意到,深链接必须打开“快捷方式”应用才能正常工作。 快捷方式结束后,我们如何返回到我们的应用程序? 对我们来说幸运的是,“快捷方式”应用程序支持x-callback-url标准,这是您通过URL将数据发送到其他应用程序并以其他URL形式取回某些东西的一种标准化方法。 看起来像这样: shortcuts://x-callback-url/run-shortcut?name=[name]&x-success=[url] 当[name]快捷方式成功执行时,“快捷方式”应用程序将自动尝试打开传递给x-success参数的URL。 这可以是任何url,我们可以通过注册自己的URL方案使用它返回到我们的应用程序。 假设我们的应用程序正在侦听myapp:// URL方案,则可以通过运行以下myapp://使Shortcuts应用程序路由回到我们的应用程序: let shortcut = “shortcuts://x-callback-url/run-shortcut?name=Take%20Picture&x-success=myapp://” let url = URL(string: shortcut)! UIApplication.shared.open(shortcut, options: [:], completionHandler: nil) 除了x-success , x-cancel和x-error还可分别用于处理中断和错误。 其他深层链接 导入快捷方式 shortcuts://import-shortcut?url=[url]&name=[name] 对于此特定的快捷方式, url是.shortcut文件的URL,而name是要导入的快捷方式的名称。 您还可以将&silent=true传递到此深层链接,以防止快捷方式应用程序打开导入的快捷方式。 此深层链接还支持x-callback-url 。 打开(不运行)特定的快捷方式 shortcuts://open-shortcut?name=[name] 打开快捷方式应用 shortcuts:// 打开创建快捷方式屏幕 shortcuts://create-shortcut 打开快捷方式库 shortcuts://gallery 搜索快捷方式库 shortcuts://gallery/search?query=[query] 结论 由于您无法检索用户快捷方式列表,因此常规应用程序中的这些深层链接可能没有多少用处,但是它们对于诸如AirPods相机技巧之类的个人自动化项目非常有用。 您打算做什么? 在我的Twitter上关注我-@rockthebruno,让我知道您想分享的任何建议和更正。 参考书目和优秀读物 x-callback-url Apple Docs:快捷方式URL方案

玩今天的窗口小部件扩展第一部分

首先; “乐趣”在这里是主观的! 对我来说,什么是“乐趣”( 不 使用情节提要 本机进行iOS原生开发 …… ),对其 他人而言 可能是无聊的(或…… 折磨 ?)。 * Kanye耸了耸肩* ……实际上……现在或以后再也没有提及Kanye了。 免责声明 :本文假定您熟悉:使用 Swift 本机开发iOS应用程序 。 各种iOS框架,API和组件……或至少是; 安装了 XCode 。 与往常一样,您甚至没有义务阅读此书,您可能只想要源代码,就 在这里 。 因此,您可能想知道“ Today Widget到底是什么?” 简短答案:“今日视图”中的应用扩展程序,可让用户快速访问信息。 不确定那是什么意思? 好吧, 这是一个很长的答案 。 让我们通过创建一个新的XCode项目来开始。 接下来,添加应用程序扩展 时间到一些代码 现在,这是我完全删除所有情节提要的部分。 main和launchscreen(您不必完全删除它们,但是我不会使用它们),而是将AppDelegate配置为手动启动默认的ViewController 。 现在,您的项目应该在主应用程序和Widget扩展之间显示清楚的区别。 从现在开始,您基本上将专注于Widget扩展名称空间。 创建一个名为UserModel的快捷文件,此模型对象将具有一个名为’name’的字符串变量。 进口基金会 struct UserModel { 命名:字符串 } 创建一个新的Cocoa Touch Class,将其设置为UICollectionViewCell ,并将其命名为UserCell。 这将是自定义的collectionview单元格,其中将容纳将在小部件上看到的必要视图( […]

储存使用者资料

对于许多应用程序而言,一个真正重要的功能是能够存储用户数据。 您的应用在各个方面都可能令人赞叹,但如果它不记得用户做了什么,那就会很烦人。 您可能要存储数据的原因包括: 用户设置 游戏高分 档案信息 留言内容 还有许多其他。 幸运的是,这根本不是一件困难的任务。 使用NSUSerDefaults类可以非常容易地存储诸如Strings和Integers之类的简单项目。 NSUserDefaults类提供了与默认系统的接口,可以对默认系统进行自定义以匹配用户的首选项,例如度量单位。 要在其中设置自己的值,请使用以下代码行: NSUserDefaults.standardUserDefaults()。setValue(,forKey:) 举个例子: NSUserDefaults.standardUserDefaults()。setValue(“ red”,forKey:“ colour”) 在这里,我们将字符串“ red”存储在名为“ colour”的键下。 您可以存储任何标准类型,例如Float,Int,String。 要在下次运行应用程序时检索此密钥,我们只需要从给定密钥中索取值,例如: 让SavedColour = NSUserDefaults.standardUserDefaults()。valueForKey(“ colour”)设置为? 串 现在,请注意,您要查找的数据实际上并未显示在手机上。 也许用户已经删除了数据,或者这是该应用程序第一次运行。 不会创建任何密钥。 因此,当您使用此值时,应用程序可能会崩溃。 始终最好在此类声明周围加上保护性声明,例如: 如果让saveColour = NSUserDefaults.standardUserDefaults()。valueForKey(“ colour”)设置为? 字符串{ //在这里使用您提取的数据 } 其他{ //在此处设置默认值供您的应用使用 } 这一切都很棒,并且非常容易实现。 但这不适用于任何自定义类。 存储自定义类 假设您已经创建了一个Person类,该类存储了他们的名字和姓氏: 类人 { var firstName:字符串! var lastName:字符串! 初始化(第一个:字符串,最后一个:字符串) { firstName […]

服务器端Swift — MVC(单元测试)

在我的上一篇文章中,我描述了如何根据MVC模式(与ASP.NET MVC类似的构建)构建服务器端Swift应用程序。 但是,这里缺少一件事: 单元测试 。 没有单元测试,我无法想象认真的应用程序。 在本文中,我将介绍如何在Swift(和Per​​fect框架)中向我们的MVC应用程序添加带有单元测试的项目。 首先,我们必须重新构建一些应用程序。 我们无法为可执行应用程序创建单元测试。 这就是为什么我们必须将应用程序分为两部分: 可执行文件 -这部分应包含尽可能少的文件, 库 -该部分应包含整个业务逻辑-这部分我们可以连接到我们的测试库。 划分应用程序后,我们应该有一个如下所示的项目: 来源/ TaskerServerApp / 主Swift TaskerServerLib / 控制器/ * 楷模/* 仓库/ * 扩展名/ * 测验 TaskerServerLibTests / 因此,我们有TaskerServerApp可执行文件,其中仅包含一个文件(引导我们的服务器的主文件)。 我们有TaskerServerLib ,其中包含业务逻辑的主要部分(控制器,模型,存储库等)。 在单独的项目TaskerServerLibTests我们将进行单元测试。 要创建该项目,我们必须为Swift Package Manager准备Package.swift文件。 它看起来应该像这样: 现在我们必须考虑如何创建伪造的实现。 在像C#/ Java这样的语言中,我们可以使用功能强大的模拟框架,例如:Moq,Rhino.Mocks,mockito。 不幸的是,在Swift中,这项任务并不是那么容易。 Swift的反射/自省能力不足,无法在运行时生成动态类(在许多被称为代理的模拟框架中)。 我发现了一些模拟库,例如: SwiftyMocky-我们可以标记协议( //sourcery:AutoMockable ),然后适当的伪造实现将由Sourcery工具生成, Cuckoo —特殊的生成器( CuckooGenerator )和框架,generator负责基于配置文件生成伪造的实现, Mimus —框架,提供我们可以在人工生成的假文件中使用的方法(目前仅支持模拟), Dobby-与Mimus相似,但是在我们的虚假实现中,我们可以使用模拟和存根。 […]

Swift 4 Introduction系列1.6 — Swift数据类型可选

Optionals是一个后缀运算符,可以附加到任何数据类型。 可选项目以问号( ? )表示。 我们使用可选参数来指示变量所分配给的数据类型可以不包含任何值。 我们使用关键字( nil )分配一个没有值的可选内容。 只有声明为可选变量的变量才能分配nil值。 我们在某些情况下声明了可选变量,在这种情况下我们不知道输入源是否包含数据。 可选选项使程序更安全地进行编码。 例如,声明为( Int? )的变量; 告诉系统该变量可能没有任何值。 我们可以测试变量是否有值,如果有值,可以从变量中解包值。 用于指示或声明可选选项的语法如下: ? 例如,要声明一个可选变量,我们执行以下操作: var someOptional1:Int? var someOptional2:String? var someOptional3:Double? var someOptional4:Bool?someOptional1 someOptional2 someOptional3 someOptional4 请注意,在声明可选变量时,我们不需要初始化变量,因为可选变量数据类型变量会自动初始化为无值或nil。 但是, 自动初始化仅适用于变量,不适用于常量。 我们可以使用值设置可选选项,如果程序需要设置为nil,则将它们重置为nil。 例: //从先前的代码继续 someOptional1 = 766 someOptional3 = 7123.98 someOptional4 = falsesomeOptional1 =无 someOptional4 = nilsomeOptional1 someOptional2 someOptional3 someOptional4 请注意,在Objective C中找不到可选参数。尽管我们可以在Objective-C中将对象设置为nil,但在Objective-C中,nil指向空指针,而在Swift中,我们可以将任何数据类型设置为可选参数。 我们还可以同时声明和分配可选内容。 […]