Tag: swift

学习RxSwift(第1部分)

如今Rx蓬勃发展,我认为如果每个开发人员都使用RxSwift会更好。 Rx =反应式编程,这是一个与数据流和变化的传播有关的声明式编程范例,例如,在命令式编程中,将a = b+c设置a = b+c将a的结果赋给a b+c ,然后是b的值 和c 可以更改而不会影响a的值,但是在反应式编程中,a的值 只要b的值自动更新 或c 更改,而程序不必重新执行语句a:=b+c 确定a的当前赋值。 维基百科 ReactiveX是来自以下方面的最佳创意的组合 观察者模式,迭代器模式和功能编程。 ReactiveX不仅仅是一个API,它是编程的想法和突破。 它启发了其他几种API,框架,甚至是编程语言。 在ReactiveX中,观察者订阅了一个Observable。 然后,该观察者对可观察对象发出的任何项目或项目序列做出反应。 这种模式有助于并发操作,因为它在等待Observable发出对象时不需要阻塞,而是以观察者的形式创建了一个哨兵,随时准备在Observable以后的任何时间做出适当的反应。 在ReactiveX中,许多指令可能会并行执行,并且随后会捕获其结果,您以“可观察”的形式定义了一种用于检索和转换数据的机制,然后为它订阅了一个观察者,在此之前,当观察员站岗时,定义好的机制便开始行动起来,以随时捕获并响应其排放。 这种方法的优点是,当您有一堆彼此不依赖的任务时,可以同时启动所有任务,而不必等每个任务都完成才开始下一个任务-这样,您的整个完成任务捆绑包所需的时间与捆绑包中最长的任务一样长。 热点观察 在创建项目后立即发出项目,因此以后订阅该Observable的任何观察者都可以开始观察中间位置的序列。 冷观测 等到观察者订阅它之后才开始发射项目,因此可以保证这样的观察者从一开始就可以看到整个序列。 RxSwift功能强大且功能强大,可节省大量开发人员的生命和精力,可用于: 1-绑定 Observable.combineLatest(firstName.rx.text,lastName.rx.text){$ 0 +“” + $ 1} .map {“问候语,\($ 0)”} .bind(发送至:greetingLabel.rx.text) 2-代表 而不是进行乏味且无表情的操作: 公共功能scrollViewDidScroll(scrollView:UIScrollView){[弱自我] self?.leftPositionConstraint.constant = scrollView.contentOffset.x } …写 self.resultsTableView .rx.contentOffset .map {$ 0.x} .bind(发送至:self.leftPositionConstraint.rx.constant) […]

iOS初学者代表

iOS开发的大多数初学者在理解委托人时都有问题。 苹果公司说,委托是一个对象,当另一个对象遇到程序中的事件时,该对象代表另一个对象或与另一个对象协同工作。 为简化起见,委托是一个对象,它允许对象A和对象B使用函数或变量相互通信。 代表由程序中的事件触发(例如,按下按钮)。 让我在一个将数据从自定义视图传输到视图控制器的简单示例中为您解释一下。 让我们从创建一个新的Xcode项目开始; 所以打开Xcode,选择Create a new Xcode project 选择Single View App,然后按Next。 在产品名称字段中,输入DelegateExample,然后按下一步->创建。 好的,现在我们已经建立了一个项目,可以开始了。 现在我们需要创建一个代表对象B的自定义视图。我们的对象A将是View Controller,并且已经由Xcode创建。 因此,要创建自定义视图,请导航到Xcode窗口左侧的项目树,右键单击Delegate Example文件夹,然后单击“新建文件”。 选择Swift文件,然后单击Next。 在另存为字段中输入CustomView,然后按创建 现在,我们将为CustomView创建一个.xib文件。 为此,再次右键单击Delegate Example文件夹,然后选择New File…,但是这次选择View并按Next。 再次将文件命名为CustomView,然后单击“创建”。 现在,您应该在项目树中看到一个CustomView.xib文件,并且应该有一个类似于以下内容的屏幕。 好的,进入代码。 打开您的CustomView.swift文件并为我们的自定义视图创建一个类。 为此,只需在文件中键入此代码即可。 进口基金会 导入UIKit 类CustomView:UIView { } 现在,我们需要在.xib文件的视图中添加一个类。 导航到CustomView.xib,然后在“检查器”选项卡的顶部选择“身份检查器”。在“类”字段中,输入CustomView,然后按Enter。 现在,在屏幕上的某处添加一个按钮和文本字段。 我将像这样将它们添加到屏幕的中央。 现在回到代码,我们需要为文本字段和按钮创建出口。 为此,请将此代码添加到CustomView类。 @IBOutlet弱var textField:UITextField! @IBOutlet弱变量按钮:UIButton! 现在,将插座与.xib文件中视图内部的文本字段和按钮相连。 为此,请再次导航到“检查器”,然后选择“连接”检查器。 您将看到我们刚刚创建的两个出口。 要连接它们,只需在插座名称旁边的圆圈上按文本框和按钮,然后将它们拖放到视图中的文本框和按钮即可。 现在,让我们以相同的方式在View Controller中添加标签。 转到ViewController.swift文件,并将此代码添加到ViewController类中。 @IBOutlet弱var标签:UILabel! 转到Main.storyboard,向ViewController添加标签和按钮,然后使用检查器连接标签出口。 太好了,现在我们已经设置了对象A和对象B。我们的对象A将是ViewController,而我们的对象B将是CustomView。 […]

如何为快速Codable编写强大的模型并再次使用该模型。

在这篇文章中,我将不写什么是可编码协议以及如何使用它! 取而代之的是,我将在一个很短的故事中告诉您如何用快速的语言为其编写最佳模型。 所以走吧… 如果您对编码技术不熟悉,我强烈建议您对其进行详细了解,然后再回到这里阅读其余内容。 你们中的大多数人都可以使用可解码来反序列化JSON文件。 但是如果您想在项目中再次使用该模型作为列表或数组又如何呢? 或者只想从您的项目中的模型创建一个全局实例数组,并进行很多次映射。 不幸的是,许多初级开发人员将创建另一个模型结构并使用该模型结构。 但是它们可能会遇到可选选项或强制展开的问题。 假设此JSON文件为: { “ name”:“ John”, “ lastName”:“ Doe”, “年龄”:27 } 在此JSON文件中,我们有一个简单的用户数据。 所以我们从简单的模型结构开始: struct user_Model:Codable { 让名字:字符串? 让lastName:String吗? 让年龄:int? } 在此模型中,我们使用“ let” ,并且必须在每个参数的末尾添加可选的“?” ,以避免反序列化错误。 如果该参数在该JSON文件中不存在,它将返回“ nil”而不是该参数。 因此,我们应始终处理“无”。 another另一方面,您无法通过安全展开来制作该模型的另一个实例。 这将发生: (testUser?.name)! 这太错了。 也许您说我们可以使用Class而不是struct,然后使用: 必需的init(){ } 并在那里初始化每个参数。 像这样 : class user_Model:Codable { 变量名称:字符串 var lastName:String var age:Int 必需的init(){ self.name […]

AR之旅-第2部分

因此,在经过非常紧张的前两个晚上之后,老实说,我对我们参与该项目的机会感觉好多了。 头一天晚上都花大量时间研究Swift,以使用语法,数据结构和控制流。 鉴于我在选修期间从事Java和Go的工作,因此转向强类型和面向对象的语言并不是外国的经验,以我的愚见,对于任何有Javascript背景的人来说,这都是相对容易的选择。 第二天晚上和第二天,我们更多地关注我们项目(Jenga游戏的AR版本)-苹果的ARKit。 值得庆幸的是,这里有大量的资源,我目前正在一门Swift通用课程上取得进展,该课程包括ARKit和ML Core以及ARKit专用课程。 今天发生的惊人的事情 构建有效的AR演示应用程序-当前,我们有两个不同的应用程序,它们显示了ARKit的大部分主要功能。 一种是允许您在场景中放置骰子,并根据点击或电话震动来模拟滚动,第二种是测量距离(如上所示)。 尚未完全为Appstore做好准备,但感觉像是要承受很大的负担。 找到了一个与创建的对象进行用户交互的演示-我当前的技术关注点是如何启用移动AR Jenga块所需的手指跟踪。 值得庆幸的是,我遇到了有关Toptal的精彩教程,看起来就像我们所需要的。 它也应该允许我们尝试自己的跟踪,而不必转向Vuforia或ManoMotion。 是在德克萨斯中央食品银行(Central Texas Foodbank)自愿参加的-是的,它与该项目完全无关,但这是一个很好的机会,可以停止思考下周我们需要做的一切,并回馈社区。 对我来说,专注于这个项目同等重要,对我来说一点一点地断开电源并以回馈的方式表示感谢也对我来说同样重要。 下一步是什么 完成关于Udemy的第二个ARKit课程-巩固基本概念并更熟悉API,以至于它不再像看教程那样多,而是更多地利用我们学到的技能 获得用户与创建的对象进行交互的有效演示 玩弄物理学-这是我其他队友的重点,但我仍然想对此有所体会 感谢阅读本文的任何人! 如果您处于与开始进入iOS和Swift或ARKit相似的职位,我将乐于接受任何反馈或意见,并愿意(尝试)回答您可能遇到的任何问题!

使用Sourcery在iOS中自动生成委托存根

代表们,代表们! iOS喜欢代表。 它们在Apple的大多数框架中都使用过,我对您一无所知,但最终我在自己开发的每个应用程序中一遍又一遍地编写自己的应用程序。 在测试代​​码时,您必须编写许多手动存根和样板来测试调用委托的类,谁愿意编写比他们需要的代码更多的代码! 任何额外的工作都会使测试在整个团队中进行的可能性降低,并且在进行测试时会变得越来越精明。 每当您定义代理人BAM时,Sourcery都可以在此提供帮助。 在下一次编译时,会生成一个存根并将其添加到您的测试目标中,所有内容都会充实并准备就绪。 如果您不知道Sourcery是什么,它是一个元编程工具包,可以“ 扫描源代码,应用个人模板并为您生成Swift代码,从而使您可以使用元编程技术来节省时间并减少潜在的错误。” 这太疯狂了。 这篇文章不是Sourcery的完整介绍(尽管我们将在您的项目中进行设置)。 如果您想查看一个好的介绍,请转到Ray Wanderlich的教程。 它很好地解释了它并引导您完成它。 这是我们将做的一个例子: 代表定义: 协议AutoStub {} 协议OnboardingViewDelegate:AutoStub { func tappedLogin(用户名:字符串,密码:字符串)->布尔 func tappedRegister(用户名:字符串,密码:字符串) } 生成的存根: //使用Sourcery 0.7.2生成-https://github.com/krzysztofzablocki/Sourcery //不要编辑 类OnboardingViewDelegateStub:OnboardingViewDelegate { var namedTappedLogin:Bool = false var称为TappedLoginWithParamUsername:字符串? var namedTappedLoginWithParamPassword:字符串? var tappedLoginReturnValue:布尔? func tappedLogin(用户名:字符串,密码:字符串)->布尔{ self.drawnTappedLogin = true self.CalledTappedLoginWithParamUsername =用户名 self.CalledTappedLoginWithParamPassword =密码 返回self.tappedLoginReturnValue! } var namedTappedRegister:Bool = false […]

使用Swiftify更好地发送消息

许多开发人员在初次尝试使用该语言时就对Objective-C的消息发送语义感到困惑。 消息发送的语义使得可以“调用”空对象上的方法。 您实际上并不是在调用方法,而不是将消息发送到没有地址的地方。 如果您是在Swift中构建应用,则不必担心理解Objective-C消息发送。 这就是为什么最新版本的Swiftify的Objective-C至Swift Converter大大改进了我们处理消息发送的方式。 在Objective-C中,属性只是方法周围的语法糖,可以像调用方法一样调用它。 @implementation TestViewController:UIViewController-(IBAction)graphButtonClicked:(id)sender { GraphViewController * graphViewController = [[[[self splitViewController] viewControllers] lastObject]; }@结束 注意对[self splitViewController]而不是self.splitViewController 。 在Swift中,您不能引用self.splitViewController()因为该方法不存在。 我们的转换器按预期处理此问题: 类TestViewController:UIViewController { @IBAction func graphButtonClicked(_ sender:Any){ 让graphViewController = splitViewController?.viewControllers.last as? GraphViewController } } 对[self splitViewController]属性getter的调用将替换为Swift中适当的属性调用。 甚至splitViewController的可选性都是正确的! 您可以在此处测试示例。 Objective-C如何处理方法和消息还有另一个有趣的方面。 Objective-C方法的参数名称不是方法签名的一部分。 @interface TestViewController:UIViewController -(NSString *)greetPerson:(NSString *)personName; @ end @ implementation TestViewController:UIViewController-(NSString *)greetPerson:(nonnull NSString […]

自学系列| iOS Swift | 第二课:介面开发(UIKit)第2部分

这篇文章承接第1部分 ,继续Udacity iOS App Nanodegree第二课的导读。 3.其他UI元素 UIImagePickerController 当App需要取用手机的相簿时,就可以使用UIImagePickerController让App跳出选择相片的画面,如左图。它需要遵循的Protocol有UIImagePickerControllerDelegate以及UINavigationControllerDelegate。 UIActivityViewController UIActivityViewController(如中图)经常在分享照片,或分享URL链接的时候,我们透过想要要分享的东西传到其他App上。 UIAlertController UIAlertController有某种形式,常见的有上右图那种从底下冒出来的选单,也有从萤幕中央跳出来的罢工(在左下图),它也可以结合UITextField构成简易的资料输入,例如下面右图。 4.多页画面 UINavigationController / UITabBarController 画面上方的是NavigationController,我们在第一课有使用过(可以看这篇),通常左边的按钮负责回到前一页,右边的按钮则可以实作不同需求,像是分享,跳出选单…等等。画面下方的是TabBarController,用于在不同页面之间切换。详细的实作Udacity课程影片讲了很多,这边就不多说了。 学完第二课,我们已经熟悉UIKit当中最常见的几个元素, 包含几乎所有App都会用到的UITableView,UICollectionView,可以在多页面之间转换的UINavigationController,UITabBarController,还有一些小工具如用来输入文字的UITextField,使用挑照片的UIImagePickerController,会跳出选单或警示的UIAlertController。 还有最最重要的 准备好前往下一课了吗? 第三堂课:网路资料传输处理(网路) 第四堂课:手机上的资料储存(核心资料) 第五堂课:从发想到上架的方法论 如果喜欢这样的自学系列,请帮我拍拍手👏另外,我把之前写的程序学习相关文章集结在底下的列表,有闲来坐🤗 艺一网—文章列表 我们的【学程序&软体创业】学习之路 medium.com

驯服iOS中的大量控制器(第1部分)

更新:第2部分现在可用 无论您的iOS应用多么简单,您仍然必须遵循MVC软件架构模式。 MVC模式将应用程序的职责分散在模型,视图和控制器之间。 不幸的是,大多数时候,责任最终落在了控制者的肩膀上。 这种做法导致了所谓的大规模控制器 。 我在IndieDevStock上介绍了“在iOS中驯服大量控制器”。 如果您想观看我的会议视频,请购买远程通行证。 大型控制器是不遵守单一职责原理的视图控制器。 这些控制器可能正在访问数据,调用Web服务,创建UI元素以及执行与控制器没有直接关系的其他任务。 这导致了技术债务和维护方面的噩梦。 这篇文章的主要重点是向您展示一些可用于驯服大型控制器的技术。 我们将从一个非常简单的应用程序“ Grocry ”开始。 杂货应用程序负责跟踪购物清单。 Grocry应用程序的界面如下所示: 即使该应用程序非常简单,但指定的控制器中的代码仍然很繁重。 这是段中的代码片段。 覆盖func viewDidLoad(){ super.viewDidLoad() initializeCoreDataManager() //获取请求 let request = NSFetchRequest(entityName:“ ShoppingList”) request.sortDescriptors = [NSSortDescriptor(key:“ title”,ascending:true)] self.fetchedResultsController = NSFetchedResultsController(fetchRequest:请求,managedObjectContext:self.managedObjectContext,sectionNameKeyPath:nil,cacheName:nil) self.fetchedResultsController.delegate =自我 尝试! self.fetchedResultsController.performFetch() } 下面实现了负责初始化CoreData的initializeCoreDataManager: 私人函式initializeCoreDataManager(){ 警卫让modelURL = NSBundle.mainBundle()。URLForResource(“ GrocryDataModel”,withExtension:“ momd”)else { fatalError(“未找到GrocryDataModel”) } 警卫队,让ManagedObjectModel = NSManagedObjectModel(contentsOfURL:modelURL)else { […]

UILocalNotification iOS

本地通知使您的应用可以通知用户有关不需要使用服务器的内容的信息。 与从服务器触发的远程通知不同,本地通知是在应用内安排和触发的。 通常,通知的目标是增加用户与应用程序的交互,从而邀请或诱使用户打开并与其交互。 iOS 10中已弃用UILocalNotification。请改用UserNotifications框架。 安排本地通知 确保您看到注册本地通知以使其正常运行: 迅速 让通知= UILocalNotification() notification.alertBody =“您好,本地通知!” notification.fireDate = NSDate()。dateByAddingTimeInterval(10)// 10秒后 UIApplication.sharedApplication()。scheduleLocalNotification(通知) 目标C UILocalNotification * notification = [[UILocalNotification alloc] init]; notification.alertBody = @“您好,本地通知!” notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10]; //现在10秒钟后[[UIApplication sharedApplication] scheduleLocalNotification:notification]; 要在iOS模拟器中查看通知,请键入^⌘H(control-command-H)返回首页,然后键入⌘L(command-L)以锁定设备。 等待几秒钟,然后将出现通知(此外观将根据“注册本地通知”中讨论的通知类型而有所不同): 在通知上滑动即可返回到应用程序(请注意,如果您在第一个视图控制器的viewDidLoad,viewWillAppear,viewDidAppear等中调用了此方法,则会再次安排该通知)。 立即显示本地通知 如果要立即显示本地通知,请致电: 迅捷3 UIApplication.shared.presentLocalNotificationNow(notification) 迅捷2 UIApplication.sharedApplication()。presentLocalNotificationNow(通知) 目标C [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 使用此方法的一个优点是您不必设置自己的fireDate和timeZone属性。

IOS面试常见问题解答(2018年8月)

2018年8月iOS最新面试题 在本文中,我将介绍在最近的采访中(2018年8月)向iOS工程师询问的一些问题。 那些正在准备的人一定会对他们有所帮助。 Q1。 swift和目标C有什么区别? Q2。 什么是手动保留周期? Q3。 Swift中的内存管理如何工作? 我们首先看一下Swift中的内存管理基础知识。 ARC(自动引用计数)为您完成了大多数内存管理工作,这是一个好消息。 原理很简单:默认情况下,每个指向类实例的引用都是所谓的强引用。 只要有至少一个强引用指向一个实例,该实例就不会被释放。 如果没有足够的参考指向该实例,则该实例将被释放。 让我们看下面的例子: class TestClass {init(){print(“ init”)} deinit {print(“ deinit”)}} var testClass:TestClass? = TestClass()testClass =无 创建实例后,情况如下所示: testClass对TestClass的实例有很强的引用。 如果我们现在将此引用设置为nil,则强引用将消失,并且由于没有强引用,因此TestClass的实例将被释放: 顺便说一句,如果您看一下控制台,您会发现一切工作正常,因为只有在释放实例时,系统才会调用deinit方法: 如果TestClass的实例未释放,则不会出现“ deinit”消息。 正如我们将在后面讨论的那样,在deinit内放置一条日志消息是观察对象释放的一种很好的方法。 Q4。 拥有所有权的方法有哪些(保留数增加1)? alloc / init —创建一个对象并声明其所有权 保留—用于声明该对象的所有权 复制—复制对象并声明其所有权 Q5。 什么方法用于声明所有权(将保留计数减少1)? release —声明对象的所有权。 自动释放—声明对象的所有权。 Q6。 什么是面向协议的编程及其好处? Swift的设计核心是两个非常强大的想法:面向协议的编程和一流的值语义。 这些概念中的每一个都有益于可预测性,性能和生产率,但是它们一起可以改变我们对编程的思考方式。 了解如何应用这些想法来改进编写的代码。 快速进行面向协议的编程 Q7。 如何检查协议的可选方法在继承的类中实现? […]