宠物小精灵GO之后,疯狂的人跟随着Prisma!

全世界的人们都在通过另一个依赖AI创新的病毒应用程序“ Prisma”将自然照片转换为详细的艺术品,从而使用户能够在一瞬间将不起眼的图片转换为毕加索的艺术品。 截至周四,Prisma这个应用程序每天吸引了100万用户,该公司正在重新考虑通过创新将照片分开的想法。 尽管为照片添加频道的想法已经存在了相当长的时间,但Prisma iOS应用程序的卓越之处在于它依赖于“神经系统和人为混合的大脑”来重做图片。 好吧,这就是此应用程序背后的机械过程的全部内容。 “人们想创造一些东西,然后我们允许他们进行实验-Prisma联合创始人Alexey Moiseenkov! Prisma不是Instagram用于复制其他应用程序某些过滤器的艺术过滤器,而是它改变了您想象艺术力量的方式。 它从头开始创建照片,App开发人员的基地位于莫斯科。 Prisma 联合创始人阿列克谢·莫伊森科夫(Alexey Moiseenkov)在星期四的一次采访中说: “我们重新 塑造 了形象 。” “它与您刚刚分层的Instagram过滤器不同。 我们像真正的画家一样画画。” 用户可以拍照或从相机胶卷中选择。 将要求用户根据Prisma的尺寸限制来裁剪图像。 然后,他们最多可以选择33个滤镜,例如印象,马赛克,哥特式图层或其他滤镜。 “ PRISMA将继续在即将到来的一周中增加新的滤清器-Moiseenkov! 莫伊森科夫(Moiseenkov)在Facebook上发布了360度图像,实际上提供了Prisma编辑过的照片的概况,以及关于如何轻松将滤镜添加到照片的会议。 他说,视频很容易表达自己,但是艺术品的筛选非常复杂。

使用SVG在iOS应用中实现分辨率独立性

拥有各种尺寸的设备非常适合允许用户选择适合自己的设备,但是支持分辨率和像素密度的所有这些组合可能很麻烦。 即使您以某种矢量格式开发所有原始图稿,通常也必须以各种尺寸和密度将其导出为PNG格式。 如果您的应用程序中只有几个图像,这可能是可管理的,但是随着图像数量的增加,它很快就会变得笨拙而乏味。 另外,如果您有任何全屏(特别是iPad尺寸)图像,则以多个密度包含同一图像的冗余副本将迅速增加应用程序的总体存储空间需求。 另外,您也可以直接在应用程序中使用矢量图像。 此时,Xcode支持的唯一矢量格式是PDF。 您可以将PDF添加到资产管理器,它会按预期显示在Interface Builder中。 但是,在构建应用程序时实际发生的事情是,这些漂亮的矢量图像在编译时就被光栅化了。 因此,在运行时,您仍在处理固定大小的PNG图像。 这意味着您仍然受制于多个冗余映像的空间开销。 而且,如果您的应用在运行时对图像大小执行任何操作,您仍然会注意到一些像素化。 这就是SVG出现的地方。 救援的SVG 如果您还不熟悉SVG,它是一种基于XML的矢量图像格式,这意味着即使与PNG相比,它的文件大小也相对较小。 作为矢量图像,它仅包含用于重绘图像的指令,而不包含实际的图像位图数据。 只需说一句,您只需在应用程序中包含一个SVG副本。 这可以大大减少应用程序的存储需求,并简化应用程序图稿的管理。 由于Xcode不支持SVG,因此您需要找到第三方库才能将SVG支持添加到您的应用中。 我在最新的iOS项目中一直使用的是SVGKit。 它具有一个缓存系统以减少解析SVG文件的开销,并且它使用CoreAnimation层进行渲染以避免大多数性能问题。 使用Interface Builder进行布局 如果要使用Interface Builder设计布局,则可以为SVG添加图像视图,但是直到运行时才能看到图像。 由于Xcode和Interface Builder不直接支持SVG,因此,我们将不得不采用一个小的解决方法。 1.在Interface Builder中,将新的View对象添加到您的界面中(这在可用对象列表的结尾附近)。 2.像往常一样将此新视图约束到其他视图。 使用矢量图像的好处是您可以灵活选择尺寸。 但是,我仍然建议添加与源图像的宽高比匹配的宽高比约束。 这将防止图像因其他约束而失真。 3.将视图的类更改为SVGKFastImageView 。 这不会影响其在设计时的外观,但是当在运行时加载笔尖时,视图将是此类的一个实例。 4.将IBOutlet添加到视图控制器类,并将其连接到在步骤1中添加的视图。 5.用代码将所需图像加载到视图中。 例如: 请参阅完整文章中的代码。 使用代码进行布局 如果要通过在代码中构造视图对象来设置界面,则该过程可能与您已经在做的事情有点相符。 这样的事情将为您提供SVG图像视图并将图像加载到其中: 请参阅完整文章中的代码。 尽管上面的代码可以工作,没有任何限制,但是图像将根据SVG的内部尺寸进行调整。 因此,您仍然需要添加一些约束来控制图像大小。 如果您要添加更多其他相同的具有不同大小的图像视图,则可以看到图像可以缩放而不会降低质量: 其他提示 如果发现加载SVG图像时布局变得混乱,请尝试使用抗压缩性和内容优先的图像视图。 通常可以将它们设置为1(最小值),以确保图像视图仅从其他约束中获得其大小,而不从其固有大小中获得。 最后,由于我项目中的SVG混合了明暗,大大小小的等等,因此尝试在Finder中预览不是一件容易的事。 因此,我使用以下脚本来生成一个HTML页面,其中包含当前目录中所有SVG图像的预览。 随意使用它,并根据需要对其进行调整! 请参阅完整文章中的代码。

团队合作使梦想成真

或者,是编译C程序的四个阶段。 编译C程序是一个多阶段的过程。 该过程可以分为四个单独的阶段:预处理,编译,组装和链接。 传统的C编译器通过调用其他程序来处理每个阶段来协调这个过程。 由于眼见为实,因此我将使用以下程序来说明该过程的每个步骤: #include 整型 主(无效) { puts(“你好,霍尔伯顿!”); 返回0; } 该程序将称为hello.c。 预处理 编译的第一阶段称为预处理。 在此阶段,预处理器将以#字符开头的行解释为预处理器命令。 在解释命令之前,预处理器会进行一些初始处理。 这包括连接连续的行(以\结尾的行)和去除注释。 要打印预处理阶段的结果,请将-E选项传递给cc : gcc -E hello.c 在此步骤中,预处理器转到上面程序顶部一行中提到的头文件,并将其与hello.c文件的内容连接在一起。 #1“ hello.c” #1“ ” #1“ ” #1“ /usr/include/stdc-predef.h” 1 3 4 #1“ ” 2 #1“ hello.c” #1“ /usr/include/stdio.h” 1 3 4 #27“ /usr/include/stdio.h” 3 4 #1“ /usr/include/features.h” 1 3 4 #374“ […]

我最喜欢的GIF应用功能:Vhoto(iOS)

Vhoto是应用程序中的一颗明珠,原因有很多,但我最喜欢的功能是它声称如何拉动某些静止图像或“亮点” 从您的视频中。 尽管这不是直接创建GIF的功能,但它确实是一项有用的功能,并且可以很好地在我测试过的视频中使用。 这个应用程式的另一个我最喜欢的地方是,它会自动产生几种不同的媒体,从所谓的“顶级GIF”到更快,更慢的视频版本,当然,该应用程序最初的承诺是找到大量静止图像。视频中的精彩片段。 由于野外的GIF类型动画很少采用GIF文件格式(例如Instagram),因此我感谢Vhoto允许将您的作品既作为视频文件又作为GIF文件保存到相机胶卷中。 但是,当您另存为视频时,您显然会丢失可能已进行的任何播放调整…即,您刚刚制作的超级慢动作剪辑只能在慢动作中以GIF格式查看。 视频文件将仅以捕获时的速度播放。 想到任何GIF创建工具都不允许您另存为视频似乎是幼稚的(或者比其时间😉早了很多),而在最坏的情况下彻头彻尾地考虑不足。 想到任何GIF创建工具都不允许您另存为视频似乎是幼稚的(或者比其时间😉早了很多),而在最坏的情况下彻头彻尾地考虑不足。 这种魔术 -策划大量您拥有的图像和视频-是许多服务的目标(例如Google Photos,Polarr的Picky应用,Magisto和Picjoy)。 但是,Vhoto的关注点仅集中在单个视频剪辑的精选集上,这一事实使该应用程序变得更加有用。 因此,只要Vhoto仍可在最新版本的iOS上运行,它将在我的主屏幕上始终占有特殊的位置。

使用CircleCI测试和部署iOS应用

在Atomic启动新的新项目时,我们总是问自己有关测试和部署工具的问题。 CircleCI在移动和Web应用程序方面都非常幸运,因此当我发现CircleCI有适用于iOS的解决方案时,我很高兴能够利用它。 在这篇文章中,我将回顾如何在您的iOS应用程序中使用CircleCI,并说明如何处理CI和轻松部署道路上的一些障碍。 那么,CircleCI是什么? 简而言之,它是用于持续集成和部署的软件即服务平台。 我使用CircleCI的目标有两个: 持续集成测试,而无需自己维护服务器 使用TestFlight为我们的内部测试人员轻松部署 我跟随这篇出色的博客文章解释了CircleCI的启动和运行过程,并强烈建议有兴趣尝试CircleCI的iOS开发人员使用它。 接下来是关于我在CircleCI上部署新应用程序时的进度的分步日志。 1.创建一个帐户 登录到CircleCI并注册。 我们使用了最基本的OS X层服务器,每月费用为40美元。 您可以在此处找到完整的定价信息。 登录并将OS X存储库添加到CircleCI帐户。 他们与GitHub完全无缝集成。 2.分享您的Xcode方案 在Xcode中,确保您的方案是共享的,然后提交更改: 选择“产品>方案>管理方案”。 选择要共享的方案的“共享”选项,然后单击“关闭”。 推零钱。 对于大多数应用程序,您可以只共享您的主要项目方案。 如果仅共享一种方案,CircleCI将自动选择它。 3.创建并上传代码签名证书 CircleCI要求您上载配置文件和代码签名证书。 安装Fastlane工具套件可简化此步骤,并避免麻烦使用Xcode。 要创建签名证书,请运行: $ mkdir证书 $ cert –output_path证书 cert将创建三个文件,包括您需要上传的.P12文件。 同样,请参阅我上面链接的博客文章(我的指示直接来自于此)。 在这一点上,我遇到了第一个问题: 密码(对于foo@bar.com):*********** [09:05:29]:发送崩溃/成功信息。 有关更多信息:https://github.com/fastlane/enhancer [09:05:29]:未发送个人/敏感数据。 仅共享以下内容: [09:05:29]:{:cert => 1} [09:05:29]:证书 [09:05:29]:此信息用于修复失败的工具并改进最常用的工具。 [09:05:29]:您可以通过设置环境变量FASTLANE_OPT_OUT_USAGE = 1来禁用此功能 /Users/foobar/.rvm/gems/ruby-2.2.4/gems/spaceship-0.27.2/lib/spaceship/two_step_client.rb:39:handle_two_step中的[:]太空船目前不支持该推基于2步验证,请同时转换为基于SMS的2因子验证(RuntimeError) 这里发生的是Fastlane的Spaceship工具不支持Apple的基于推式的两步验证过程,因此当我运行证书时,它失败了,我在Macbook Pro上遇到了两步验证挑战。 原来这很烦人-错误消息建议切换到基于SMS的2因子身份验证,但我不知道如何使用AppleID进行此操作。 我采取了这样的方法暂时停用两步验证: […]

Apple Developer Enterprise程序设置

Apple Developer Enterprise程序(也称为内部分发)使公司无需前往AppStore并经过Apple的批准程序即可将其应用程序发布给用户。 这样可以确保公众或该公司以外的任何人都不会使用这些应用程序。 为此,您需要遵循一些步骤。 我将向您介绍我为您的客户发布此类应用程序的经验。 更多详细信息可以在这里找到。 要求客户创建一个Apple Enterprise Developer帐户,并为您提供用户名和密码,或者如果他们不愿意共享此类信息,则将您添加到该帐户。 根据我的经验,大多数客户都会向我发送他们的帐户信息,而我会尽一切努力来设置他们的帐户。 这通常是因为客户/客户经理的技术水平不足以处理创建帐户或在iTunesConnect的“用户和角色”下以及Apple Developer门户的“人”下添加用户。 要创建企业帐户,您可以在此处访问Apple的网站。 并非说企业计划的费用为每年299美元。 在您注册该程序之前,Apple从您/您的客户那里需要做的事情很少: 法人实体状态:基本上是为了确保您是合法/合法公司并且您是您的身份。 DUNS号:公司必须具有DUNS号,用于验证公司是否为法人实体。 此唯一编号是由Dun&Bradstreet分配给您的公司的,用作标准的业务ID。 法律授权:您或公司的某人应具有与Apple签订法律协议的法律授权。 例如,公司的创始人,项目负责人或具有公司高层人士授予他们法律权限的人。 Apple ID:您需要确定一个Apple ID才能登录并注册该程序。 此Apple ID是您稍后在登录开发人员帐户和iTunesConnect时所需要的。 客户端创建帐户并为您提供所需的登录信息后,登录到Apple Developer帐户和iTunesConnect,以确保一切正确,并且您具有正确的访问权。 完成所有步骤后,现在您将需要生成分发证书 ,并确保选择“ In-House and Ad Hoc ”。 之后,将要求您使用“钥匙串访问”创建证书签名请求(CSR),这与您要生成常规分发证书时使用的方法相同。 生成该代码,下载并添加到您的钥匙串中。 现在,当您要发布应用程序时,需要将其导出以分发到商店外部。 为此,请转到产品->存档,然后将存档导出为iOS App文件(.IPA文件)。 在客户端上单击导出按钮,选择“保存以进行企业部署”,从弹出菜单中选择一个团队,然后单击“继续”。 那将为您生成IPA文件! 为了发布该应用程序,您将需要3个文件,我们之前生成的IPA文件,一个应用程序图标(.png文件)和一个称为清单文件的文件。 清单是一个XML plist文件,设备本身使用它来查找IPA文件,图标以及有关应用程序本身的其他重要信息,例如您的Web服务器(IPA文件所在的位置)。 您可以在生成IPA文件本身时生成清单文件,然后将提示您输入所需的详细信息,例如“应用程序名称”,“应用程序URL”(应为HTTPS),“图像URL”(也应为HTTPS)。 完成此操作后,您便拥有了所需的所有文件,并设置了生成应用程序IPA文件所需要做的一切。 现在,您需要将应用程序上载到将要运行的服务器上,并将应用程序清单文件传递给用户,以便他们可以下载应用程序。 请确保将所有3个文件放在同一目录中,否则,请更新清单文件以反映每个文件的位置。 如有任何疑问,请随时发表评论,我会尽快回复! 祝你好运,分配愉快!

始终注意技术建议的含义

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

dispatch_sync()有陷阱

每个文档: 作为一种优化,此函数在可能的情况下在当前线程上调用该块。 如果您尝试提供其他队列并在主队列上调用此函数,则这是一个陷阱,它实际上会将所有帧从主队列堆叠到目标队列中,如下所示: dispatch_sync(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ [RestAPI registerDevice:^{ }]; }); 致电之前: 块内: 请注意,属于主队列的帧现在堆叠在后台队列中。 当您尝试在块中添加信号量时,这会变得混乱,例如: + (void)registerDevice:(void (^)(void))completionBlock { while (true){ __block BOOL success = NO; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [[AFHTTPSessionManager sharedInstance] POST:@”register” parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) { success = YES; DDLog(@”[REGISTER SUCCESS] %@”, responseObject); dispatch_semaphore_signal(semaphore); } failure:^(NSURLSessionDataTask *task, NSError *error) { DDLog(@”[REGISTER FAILED] %@”, […]

解决编码挑战

模糊#2 可能的解决方案 简介:从模糊1移至模糊2 模糊1是Firehose软件工程程序中对面向对象编程(OOP)的介绍。 模糊1只不过是简单地输出由阵列阵列组成的图像(黑白),该阵列用于表示图像的各个像素。 这并不难。 为了清楚起见,您需要使计算机输出以下内容: 要在“模糊1”中做到这一点,您需要做的就是一起擦几根棍子,瞧,你起了火。 不,但是认真,这是关键成分 您需要一个带有参数的类。 Image类本质上是特定对象的方法和变量的模板定义。 Image类本质上为我们正在做的事情起了个名字。 但是,由于在这种情况下,我们要处理一组像素,因此需要找到一种方式来存储和表示计算机可以理解的方式。 因此,对于我们的情况,最简单的操作是创建一个数组数组。 您将需要一个使用该参数的初始化器 从那里您只需要应用一种将输出参数的方法类型 这些是这样的: 这就是它的长短。 但是,模糊2所需要的远不止于此。 经过大约1个月的时间,实际的解决方案似乎比我想象的要容易。 同时,我学习了很多有关如何编写代码的知识。 什么是Blur2? 模糊2要求您采用给定的阵列数组,并对单个像素(单元)进行模糊处理,并对紧接其周围的像素进行模糊处理。 为了更清楚地了解这一点,请看以下图片: 因此,作为编码人员,您需要查看代码,然后解密它所需要的内容,以及如何将您的想法转化为一系列代码,这些代码序列将输出使模糊原始图像周围单个像素的图像。 因此,如果以上面的两个像素转换为例,您可以看到您的代码最终应该输出与右侧图像相同的结果-您将从左侧的图像开始,但是随即完成右边的内容。 这是我首先要做的 起初我冻结了。 只是冻结。 “这到底意味着什么?” 如果您以前曾经有过这种感觉,那么您将确切地知道这是什么样的。 但是,从那时起,我花时间尝试将问题分解为合理的步骤序列,这些步骤可以根据我现有的代码知识以及其他开发人员的经验来解决。 这是我冷静下来后所做的事情 规则1:总是用简单的英语写出你想做的事情。 由于这样做之后才有意义,因此首先想出一个解决问题的计划即可为您提供参考。 显然,接下来的工作将是您需要阅读的所有代码,但是查看您想做什么并检查推理中可能存在的差距是一个不错的起点。 所以这是我的原始想法: 所以我得到了需要模糊处理的图像。 大。 我已经将我的数组连接在一起以组成一个数组数组,所以现在我需要弄清楚要模糊的实际像素在哪里 我想遍历所有像素和所有行以确定这些实际像素在哪里并将坐标存储在某处 从那里,我需要找到一种方法来模糊所标识位置的上下左右像素。 这是我犯的错误 :我在互联网上查看了其他人对此的想法,而自己本人并没有全力以赴。 这可能会更快,并且可能会在短期内带您到达目的地,但稍后会遇到问题。 对我来说,我并不完全理解其他人使用的所有代码。 我最终花了很多时间测试和检查他们的代码,而不是尝试自己开发代码。 这让我放慢了脚步,因为我没有专注于寻找对我有用的东西。 第一步 我需要先让我的代码遍历每个单元格和每一行,因此我建立了一个允许这样做的系统: 此方法有一个目标:找出1的坐标,这需要几个步骤。 换句话说,这是在寻找已经模糊的实际像素的坐标。 您会注意到, 如果cell == […]

具有构建模块化SDK的经验

在conichi中,我们正在努力改善酒店的客人体验:加快入住和退房流程,带来移动支付的可能性等。 为了构建此基础架构,我们一直在研究三个主要项目,其中最重要的一个是我们的移动SDK,我们正在将其集成到合作伙伴的应用程序中。 我们一直在构建SDK时,要牢记它应该是模块化的。 所谓模块化,是指每个合作伙伴都应该可以使用他们所需的唯一功能来构建其SDK。 我们如何使代码成为可能 首先,我们分离了核心功能,并基于对配置对象的依赖注入进行了初始化过程: @interface CNISDKConfiguration:NSObject @属性(非原子,副本,只读)NSString * apiKey; @属性(非原子,副本,只读)NSString * apiSecret; @property(非原子,赋值,只读)CNISDKLogLevel logLevel; +(instancetype)configurationWithBlock:(void(^)(id 配置))configurationBlock; @结束 该对象允许基于块的可变初始化,并且遵循NSCoding协议,以避免任何引用的相关问题。 我从Parse框架实现中汲取了这个想法。 下一步是为“工具包”创建统一的界面: @protocol CNISDKKit +(void)enableWithConfiguration:(CNISDKConfiguration *)配置; +(instancetype)sharedInstance; -(无效)开始; @结束 该协议要求使用以下方法来启用Kit并对其进行配置,启动基础Kit的任务以及能够访问共享实例。 每个Kit都有自己的初始化参数,开发人员还可以在初始化期间将其作为依赖项注入传递 @protocol CNISDKKitConfiguration @结束 不幸的是,我还没有为Kit的配置对象提供任何统一的属性或方法,但是这个简单的协议至少可以为我们提供类型安全性和有关此对象外观的高级信息。 由于唯一的核心模块应该初始化Kit,因此我们创建了一个对象,该对象表示Kit及其配置之间的一对一关系 @interface CNISDKKitBundle:NSObject @property(非原子,强,只读)Class 套件; @property(非原子,强,可为空,只读)id 配置; +(instancetype)bundleWithKit:(Class )工具包配置:(nullable id )配置; @结束 并为核心配置添加了一个新属性-一系列工具 @interface CNISDKConfiguration:NSObject 。 。 。 @property(非原子,强,只读,可为空)NSArray * […]