Tag: 保留部分权利

如果您不知道使用Objective-C在做什么,则为React Native动态更新Javascript资源

对于正在工作的项目,我正在创建一个React Native应用程序。 React Native的好处是您可以从远程服务器加载javascript包(可以说是应用程序的大脑)。 这意味着您可以进行更新和更改,而无需经过App Store批准过程。 不利的一面是,在应用程序实际加载之前,需要一两秒钟的时间来加载捆绑软件。 除非您有一些花哨的Objective-C或Swift“加载”动画,否则它只会显示白屏。 我没有iOS编程方面的经验,所以我决定做第二件事-从设备本地加载捆绑软件。 我能够整理本指南中的大部分内容,但其中一些我必须自己弄清楚。 所以你想动态更新你的React Native App 在工作中,我们最近在应用程序中发布了第一个React Native组件,并且我一直在考虑如何(以及是否… medium.com) React Native为您提供了将JS捆绑软件存储在应用程序捆绑软件中的选项,这几乎为您提供了即时的加载时间。 我可以使用该机制来做我想要的。 首先,我需要检查是否有下载的JS捆绑包,或者是否需要使用应用程序的捆绑包: //这是应用程序本身的文档目录。 NSString * documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)firstObject]; // filePath代表下载的包所在的位置。 它位于应用程序的documents目录中。 NSString * filePath = [documentDir stringByAppendingPathComponent:@” main-loaded.jsbundle”]; NSURL * codeLocation = [NSURL URLWithString:filePath]; //如果执行路径中没有文件,则使用应用程序包 如果(![[NSFileManager defaultManager] fileExistsAtPath:filePath]){ //加载应用程序包的javascript jsCodeLocation = [[NSBundle mainBundle] URLForResource:@“ main” withExtension:@“ jsbundle”]]; […]

将GitLab CI支持添加到iOS项目

我最近发表了一篇文章,详细介绍了几个持续集成系统以及我最终决定使用的系统:GitLab CI。 今天,我将我的另一个项目转移到了新服务中,我认为我将逐个演示如何使用GitLab CI构建和部署该项目。 关于该项目 有问题的项目是iOS的Scrawl Notes。 这是一个相对简单的应用程序,具有相对简单的要求。 它具有单个依赖项¹,由Carthage管理。 有两个测试目标(UI和单元测试)²,每当我推送到GitLab服务器时,我都希望同时运行它们。 最后,我通过Apple的TestFlight将此应用程序部署到Beta测试人员,因此当我推送到master分支时,我想自动将构建版本上传到那里。 快车道 Fastlane使在其他项目上进行所有这些设置变得更加容易,因此我将在这里再次使用它。 Scrawl Notes尚未使用Fastlane,因此将其添加为第一步。 $ fastlane setup 在设置过程中,Fastlane要求我提供我的Apple ID。 我有一个单独的Apple开发者帐户,仅用于我的持续集成系统。 这主要是因为,如果它完全变成了麻烦,至少它仅限于我的工作,而不是我的雇主或我们的任何客户的工作。 安装完成后,Fastlane为我创建了几个文件: $ git status On branch 1.2-release Changes to be committed: (use “git reset HEAD …” to unstage) new file: fastlane/Appfile new file: fastlane/Deliverfile new file: fastlane/Fastfile … 我在这里关心的主要是Fastfile ,它描述了我希望Fastlane运行的所有任务。 默认生成的文件中包含大量内容,我现在不想要所有这些。 这是我得到的: min_fastlane_version(“2.73.0”) […]

Swift 2.2中的面向对象设计原理– Christian Tietze –中

要真正掌握设计模式(如MVVM)和架构模式(如VIPER)的使用,了解Bob叔叔的面向对象设计原理(产生了SOLID原理)非常重要。 就像制作适当的面向对象软件的语法一样。 现在这是个好消息:这里有一个Swift游乐场(和Markdown文件可在线阅读),其中阐明了Bob叔叔的所有原则: Swift 2.2中的OOD原则 检查一下,做笔记,并让原则贴近您的内心。 他们有一天可以挽救您的生命。 通过Christian Tietze的工作日志 http://ift.tt/1U9tOay

直到您可以取消排队的GCD块– Christian Tietze –中

今天,我了解到您可以使用新的dispatch_block_cancel(从OS X 10.10 / iOS 8.0开始提供)取消延迟的dispatch_block_t。 感谢Matt的帖子—这是一个Swift示例: 让工作= dispatch_block_create(0){print(“ Hello!”)} #10s后执行 让delayTime = dispatch_time(DISPATCH_TIME_NOW,Int64(10 * Double(NSEC_PER_SEC))) dispatch_after(delayTime,dispatch_get_main_queue(),工作) dispatch_block_cancel(工作) #永远不会打印“你好!” 注意:如果正在执行该块,取消将不起作用。 如果我知道此API存在,那么我可能不会在Move!中使用下面非常麻烦的方法。 可取消延迟块的超古旧版本 出于历史目的,这是可取消调度块的改编,您可能会在互联网上找到我曾经为Swift改编的代码: typealias CancelableDispatchBlock =(取消:Bool)->虚空 func dispatch(cancelableBlock块:dispatch_block_t,atDate日期:NSDate)-> CancelableDispatchBlock? { //对同一块句柄使用两个指针 //块引用本身。 var cancelableBlock:CancelableDispatchBlock? =无 让delayBlock:CancelableDispatchBlock = {在 如果!cancel { dispatch_async(dispatch_get_main_queue(),阻止) } cancelableBlock =无 } cancelableBlock = delayBlock 让间隔= Int64(date.timeIntervalSinceNow) 让延迟=间隔* Int64(NSEC_PER_SEC) dispatch_after(dispatch_walltime(nil,delay),dispatch_get_main_queue()){ 守卫let cancelableBlock […]

推出iOS版ScrollingCardView

对于Project Prox,我们被要求实施这样的设计¹: 具体来说,这是一个卡片视图: 拥抱内容,当内容出现时动态扩展高度 如果内容比卡片高,将滚动其内容 经过一番搜索,我们发现不存在这样的小部件! 希望我们的努力对其他人有用,我们创建了ScrollingCardView库。 用法 ScrollingCardView的用法与其他任何视图一样。 首先,创建视图,启用自动布局,然后将其添加到视图层次结构中: 然后像其他任何视图一样约束卡片视图: 最后,指定卡片视图的内容: 卡视图具有智能的视觉默认设置(包括阴影),但是您也可以自定义它们: 想要它? ScrollingCardView在CocoaPods上可用:您可以在GitHub上找到安装说明和源代码。 有什么问题吗 功能要求? 提出问题或在#mobile上找到我们。

滑动过渡和快速浏览– Christian Tietze –中

(在https://christiantietze.de/posts/2017/01/reswift-swipe-transitions/中阅读格式正确的故事) 在昨天的一次客户会议上,我们尝试找出当ReSwift是应用程序状态的唯一真实来源时,如何通过向左/向右滑动来为场景过渡设置动画。 应用进入什么状态? 您如何制作动画? 出于某种原因,转换百分比是否应该成为应用程序状态的一部分? (剧透:没有) 滑动首先具有挑战性,因为从视图控制器A到B的这种交互式过渡需要同时显示两者:滑动时,需要在视觉上“拖动” B。 添加自定义导航控件时,最终会得到一个主视图控制器,该控制器包含一个子视图控制器以显示实际的表视图(下图中的绿色框)。 这些表格视图应从左侧或右侧刷入并触发导航更改。 在此示例中,用户看到给定日期的数据。 她应该使用滑动和导航按钮自由导航到前一天和后一天,直到时间的开始或结束。 (或我们的数据限制,以先到者为准。) 让我们分析一下实现这一点。 单状态替换,无过渡 在没有过渡的静态世界中,只有导航栏的“上一个”和“下一个”按钮(以蓝色表示)会触发导航更改:您点击该按钮,请求来自服务器的新数据,也许您会显示一个加载指示器,然后替换UITableDataSource的内容。 现在,如果您使用ReSwift,则当前可见的数据集合将成为您应用状态的一部分。 保持简单,表格视图的单元格将显示文本。 状态看起来像这样: struct AppState:ReSwift.StateType { var内容:[String] } 想象一下,您有一些动作,减速器以及对导航更改做出的适当反应。 (这本身可能是一个挑战,并且可能是另一天的话题。提示:您将需要“更改日”操作来触发网络请求,并需要“替换数据”操作来更新内容。) 为了显示最新状态更改,您设置了一个Presenter,它是ReSwift.StoreSubscriber。 当您从服务器接收数据并替换AppState.contents时,将调用newState回调。 然后,此字符串数组将传递到用户界面进行显示。 我们将该方法称为updateView(linesOfText :)。 这是一个体系结构上的注释: updateView(linesOfText 🙂方法,我想要演示的调用者应该由主视图控制器公开。 反过来,这可以委派给其当前的子视图控制器,该控制器处理表的实际显示。 但是,从长远来看,将表示者(表示层(!)外部的服务对象)耦合到子视图控制器可能会对您造成伤害。 主视图控制器是整个组件的外壳,因此它负责公开可用的接口。 内部组件的数量和对其的委派是其他对象不关心的实现细节。 (您一会儿就会明白为什么。) 此设置非常简单。 AppState更改通过Presenter的流程,该Presenter会在必要时创建视图模型,然后将其传递到其视图组件。 结果,UITableView重新加载了新数据,您就完成了。 那是最准方法。 在添加交互式过渡之前,让我们首先使其具有更高的响应速度。 现在,每次点击按钮都会触发一个网络请求,该请求使用户的交互停止。 “走走走走”导航在孩子们中并不普遍,因此我们将在下一步中预取隔天的数据。 预取相邻天的数据 在表示层中,我想象情况会有所变化,如下所示: 从上面对简单方法的更改是: 主视图控制器具有3个子视图控制器,而不是1个。所有子视图控制器均已准备就绪,可以显示。 轻按按钮现在有两件事:像以前一样触发“更改日”导航操作, 并立即将正确的子视图控制器放在顶部。 为了使所有这些成为可能,Presenter组装了一个具有3个内容数组而不是1的ViewModel。 视图模型仍然非常简单: struct […]

始终注意技术建议的含义

这个周末,我浏览了Medium,发现了一篇有关“从模型到控制器传递数据的3种方式”的文章。 评论表明人们喜欢它,因为它谈到了重要的基础知识:如何传递信息? 这可能是有史以来最重要的面向对象编程问题。 您如何耦合组件? 提到的3种方式是: 回调, 代表团, 和通知。 实际上,这是耦合任何组件的3种不同方式。 了解这些技巧(以及其他技巧)对编写代码非常重要。 然后我想到这篇文章可能会误导新的Swift开发人员,因为这些示例几乎没有显示如何创建一个好的模型。 采取示例代码进行委派: 类DataModel { 弱var委托:DataModelDelegate? func requestData(){ //接收到数据并将其解析为String 让数据=“来自任何地方的数据” 委托?.didRecieveDataUpdate(数据:数据) } } 这是一个基于委托的回调的网络请求。 当然,它说明了代表团。 但这是网络控制器代码。 这不是模型代码。 您在这里看到任何代表实体的东西吗? 实际上,您将发现的唯一具有模型风格的东西是数据。 模型对象是本质上是某种东西的对象。 上面看到的是仅封装序列的服务对象。 除了委托属性,它是无状态的。 它本身几乎不是应用程序状态的一部分。 在简单的情况下,从模型代码中提取网络请求代码可能没有回报。 但这不会扩展。 而且,如果您将此示例视为起义的iOS或Mac开发人员的第一件事,那么您将产生误导。 假设您的代码已经具有模型对象,并且您想应用上面概述的委托技术。 因此,您采用了这个简单的代码段,您可以将其粘贴到其中而没有任何冲突,然后就可以完成了。 成功的申请似乎足以证明。 但是现在您的代码变得更糟了。 因为您的模型对象现在也是网络请求网关。 它做了两个非常重要但又非常不同的事情。 也许危害仅会在几个月后显现出来,并且,如果您一开始就全力以赴地使自己陷入这种情况,那么您可能不知道问题的根源,并且将无法自己修复。 当您阅读以代码为中心的“ X最好的Y方式”时,请弄清楚作者正在(不知不觉中)向您出售什么样的世界观或术语。 只有相距甚远,您才能获得建议,而不会盲目地改变自己的想法。 如果您找不到作者为什么如此做的令人信服的理由,也许她只是做事草率而已,并不在乎。 您必须对所学内容的质量负责。 作者无法从Genesis入手,也无法解释整个人类历史如何在这种超级编码技巧中达到顶峰。 在写作时,您必须将某些事情视为理所当然。 问题是:如果您(读者)没有自己的见解,那么您首先看到的东西对您的影响最大。 如果遗漏的东西是您工艺的重要概念,那么很难知道发生了什么。 您不能收集一些代码片段,除非收集一些作者关于如何正确执行操作的观点。 如果您的收藏夹中的各个部分发生冲突,而您没有注意到它或不明白为什么,那么将很难编写具有凝聚力的代码并应用任何这些技巧。 因为最终,没有任何事情是孤立的。 您(人类)始终是过程的一部分,您的困惑将在代码中体现出来。 […]

是否需要测量延迟和口形同步? 现在有一个应用程序!

如果您在某个时候从事任何类型的广播贡献路径或实时网络流工作,则将要同时检查延迟和口型同步。 在这种情况下, 延迟是指音频和视频经过压缩,编码,从发送端到接收端传输以及解码和解压缩后要花多长时间才能显示在屏幕,PC监视器或移动设备上。 有时称为“玻璃到玻璃延迟”,其中所讨论的玻璃是一端的相机镜头,另一端是您正在查看的显示器。 出于很多原因知道这一点很有用,但主要是这样,您可以准确地预测何时有人提示正在直播的节目。 这样一来,您就可以避免在开始实时捐款时出现长时间的停顿。 Lipsync正是您所期望的-当有人在视觉上讲话时,音频与视频同步吗? 他们的嘴唇在正确​​的时间运动吗? 观看口型同步何时结束是非常不受欢迎的,所以有一种简单的方法来检查它很有帮助。 有专门用于测量口型同步的专业广播产品。 它们工作得很好,但非常昂贵(一个链接的费用超过200英镑),因此它们的使用仅限于昂贵的广播设置,并且确保贡献链接结尾的每个人都拥有一个是不切实际的。 但是,请继续阅读,以了解仅使用iOS应用程序,如何以一种粗略而现成的方式(尽管在每秒精度的1/60之内)测量口型同步! CAVEAT:这些技术比仅仅试图“盯上眼球”要好得多,但是,如果您实际上是为大型广播用途而这样做,那么它们并不能代替适当的专业工具。 有一个应用程序! 所以,这是应用程序: CompuLabs的原子钟(Gorgy计时) 它的价格为2英镑,由MarkusGömmel开发 因此,首先,它是一个不错的时钟应用程序,可以模拟在世界各地的广播工作室和电视馆中发现的一些标志性时钟-您知道,带有数字和模拟扫描LED显示屏的时钟吗? 没有? 好。 继续… 其次,它使用NTP协议通过Internet同步到网络时间服务器,因此您知道该应用程序的所有正在运行的副本都已精确同步到某种荒谬的准确性水平。 这让我开始思考-如果该应用程序的所有副本都处于同步状态,那么这意味着在视频开始播放时(但在视频帧通过该帧时),文稿链接各端的副本都处于同步状态。链接将被冻结,并且过去的时间会非常短。 这就是我们要衡量的延迟。 最后,这款应用的价格仅为2英镑,其价格足够便宜,以至于每个可能位于捐款链接远端的人都可以默认将其安装在手机或平板电脑上,因此有机会找到有人将其举在相机前更高。 如何使用此应用测量延迟… 该应用程序已经非常适合使用我所谓的“两部iPhone和一个摄像头技术 ”来测量“玻璃到玻璃”延迟。 假定您已经具有类似于以下设置的内容: 偏远地区的专业相机。 一个IP编码器,能够将摄像机的视频和音频转换为数据,并将其流回到基础或云端。 您要测量其延迟的广播路径或IP / Internet连接。 合适的解码器和监视器,可以让您在解码后看到远程图像。 然后,您需要按以下方式部署智能手机(或平板电脑): iPhone 1运行Atomic Clock应用程序,并且必须位于“远端”,并且您要使用的摄像头指向它的实时流。 在本机上,您应打开“显示1/60秒”。 设置中第二个“视觉时钟样式”选项。 iPhone 2还运行Atomic Clock应用程序,并位于显示iPhone 1远程图像的电视或PC监视器旁边。再次,您应打开“显示1/60秒”。 设置的“视觉时钟样式”部分中的“选项”。 相机 (当然也可以是智能手机)只有一项工作-拍摄静态照片,其中包括监视器上智能手机1的图像和同一图像中智能手机2的实际屏幕。 您不一定非要这样,因为您可以盯着它看,但如果要精确,最好拍照。 拍摄照片时,它将显示捕获该视频帧的远端时间,以及接收,解码和显示该视频帧的近端时间。 通过从后者减去前者,您可以测量到延迟的1/60秒内。 当然,我跳过了有关世界不同地区不同帧率,可变延迟等的许多详细信息,因此您的确切结果可能会有所不同。 在确定结果之前,请记住这一点。 这是我捕获的一个示例:在这种情况下,我们使用的移动绑定编码器具有10秒的延迟设置(以使其能够恢复任何丢弃的数据包等),并且我们可以清楚地看到,远端恰好是11秒在本地端后面,因此两者之间有11秒的延迟。 现在,进行双向采访的时间很长,只有11秒,但这是我们在进行活动直播时设置的延迟时间的典型代表。 […]

Kos中的iOS

我应该检查一下我在所有当地时间拿到的纸条,以黑白相间的形式预订机票。 取而代之的是,我自然而然地屈服于技术的变幻莫测,并且将日历中的时间视为我应该乘飞机的时间。 在大多数情况下,这是可以理解的事情。 但是,在将时区变化的复杂性加到公式中时,要么再次检查那张纸,要么更好地配置我的电话设置,可能会阻止我在周日下午被卡在Kos上,而需要首先在办公室里第二天早上的事情。 在iOS中,日期和时间设置可以切换为自动更新,也可以保留为手动设置任何更改。 由于手动时间设置不正确,几周前几乎错过了通勤火车,所以我切换到自动日期和时间设置。 这意味着当我处于其他时区并下次在线时,我的设备将更新为当地时间。 一切都很好,几乎所有您想要从智能设备获得的东西。 我没有考虑的是,日历事件也会更改其计时,以反映设备处于不同的时区。 当我回顾过去的一周时,我注意到在伦敦发生的日历事件现在都准备好在几个小时后开始,并且在括号内的原始时间是BST(英国夏令时)。 我从科斯岛飞往雅典的航班没有附加BST指示器,但是在为时已晚之后我才意识到。 在希腊度假酒店休息了几天之后,参加了一次很棒的会议,我让自己放松了一下。 接下来,该回家了。 由于某种原因,在退房后等待出租车时,我有些a异的感觉是航班起飞时间可能与我期望的时间有所不同。 检查了纸上的飞行时间。 我很早就错过了第一次飞行,而且也错过了第二次飞行! 这样做的唯一目的就是去机场,并寻找任何可行的方式在同一天返回伦敦-最便宜的方式,最早的到达时间,最小的风险。 总而言之,一个很高的要求。 称为原始航空公司爱琴海。 419.15欧元,直到第二天早上11:15我才去希思罗机场。 托马斯·库克(Thomas Cook),Easyjet和Ryanair柜台断断续续地打开和关闭,但是经过所有的等待,我仍然无法在预算有限的情况下得到一些值得尊敬的东西。 绝对也不想为我的错误付出200欧元以上的代价。 移动的力量,移动的力量。 在尝试通过在线预订获得较便宜版本的Ryanair选件失败后,我启动了Kayak应用。 我说,我在科斯,今晚需要去伦敦。 现阶段伦敦任何地方都可以。 到我那里。 hir,wh,wh……’39英镑起的航班会让您与瑞安航空同时入住吗? 当然可以-更好。 可以利用多个远程预订系统的便携式设备的功能确实是一件大事。 还要感谢天堂,但也提供免费的机场无线网络。 我可以不用在科斯(Kos)机场多花12个小时,而不必再购买一张额外的机票就可以办得到,但是我想必须要有一个结果,以便有时能完全上一堂课。 另一个缺点是必须在目的地机场睡觉,然后直接去办公室。 不过,至少我将能够按时上班。 下次,我将在与航班相关的日历事件上启用“时区”设置。 最好确保也检查当地时间的纸! 当物理击败数字时…

iOS应用如何适应iPhone X屏幕尺寸

苹果在发布新设备或iOS版本时提供与现有应用程序向后兼容的良好记录。 应用程序经过信箱包装或缩放以适合更大的屏幕尺寸。 iOS的行为通常类似于早期版本,以避免打破任何关于较旧应用可能对其环境所做的假设。 Apple竭尽全力尝试使较旧的应用程序在更新的设备和iOS版本上正常运行。 应用程序开发人员隐式或显式声明其应用程序的前向兼容性方式不是本文的重点。 最重要的因素是构建应用程序时所用的Xcode版本(以及其目标iOS版本),启动屏幕故事板的存在以及某些Info.plist键。 我想在这里讨论的是新的iPhone X及其在运行旧版和更新版应用程序时的行为。 iPhone X iPhone X在很多方面与其他iPhone在物理上有所不同,但是其中只有一些对于从开发者的角度看应用对设备的看法很重要: 它是真正的3x设备:1点是屏幕上3×3像素的正方形 屏幕尺寸不同:375×812点(1125×2436像素)。 屏幕的长宽比有所不同:它的宽度与iPhone 6 / 6s / 7/8相同(以磅为单位,而不是实际的物理尺寸),但明显更高。 自2012年的iPhone 5起,所有iPhone的纵横比均约为9:16(以纵向宽度:高度衡量)。 较早的3.5英寸iPhone为2:3。iPhoneX约为9:19.5。 缺口:状态栏在容纳前置摄像头,听筒和其他传感器的切口区域的两侧分开。 iPhone X如何在其独特的屏幕上显示应用程序? 这取决于构建应用程序的Xcode版本。 Xcode 8 / iOS 10及更低版本 使用Xcode 8或更早版本(即定位到iOS 10或更早版本)构建的应用程序没有意识到iOS 11的大型导航栏标题和iPhone X的新屏幕尺寸的存在。但是请注意,将使用3倍资产, 如果可供使用的话。 作为参考,以下是iOS 10应用如何以其原始分辨率(即,禁用显示缩放)在iPhone 6 / 6s / 7/8设备上显示的方法: 这显示了4.7英寸iPhone熟悉的375×667点纵向屏幕尺寸,导航栏(包含20pt状态栏)和工具栏具有常规高度。 在风景中,状态栏默认情况下是隐藏的,并且状态栏的高度减小: 在新iPhone X上运行的同一Xcode 8 / iOS 10应用程序以纵向装箱,并带有稍微圆的角: 状态栏仍处于缺口上方,但应用程序看到的屏幕大小与4.7英寸iPhone 6 […]