快速浏览类型擦除

如果您正在编写Swift,那么您可能已经听说过类型擦除。 也许您甚至在使用它。 但是,即使您属于这两个阵营中的一个,也有可能实际上不知道为什么类型擦除有效。 ♂️ 与其给您提供有关如何擦除类型的方法,不如让我们实际研究问题所在并逐步解决。 问题 假设我们正在制作一个通用网络会话类,该类必须支持各种JSON反序列化器,这些反序列化器返回的对象与网络会话的关联类型匹配。 像这样: 这很烦人,但确实有道理。 我们的协议JsonDeserializer是抽象类型,因此Swift编译器无法推断其引用的具体类型,也不能假设其在编译时由其associatedtype提供的类型。 Hector Matos在他的博客KrakenDev : 简短的答案是:Swift希望是类型安全的。 再加上它是一种提前编译的语言,并且您有一种需要NEEDS能够在编译期间随时推断具体类型的语言。 我不能太强调。 在编译时,不是函数/类约束的每个类型都需要具体。 协议中的关联类型是抽象的。 这意味着它们不是具体的。 他们是假的。 没有人喜欢假货。 因此,尽管此错误令人不快,但确实有道理-并且该错误告诉我们一些重要的信息。 指出,该协议只能用作通用约束 ,即在尖括号之间。 尝试1 我们知道,将JsonDeserializer用作类型约束的唯一方法是在使用它,但是出于参数的考虑,我们决定使用协议约束来指定一种类型,就像我们对泛型类的处理方式一样。 结果如何? Cannot specialize non-generic type ‘JsonDeserializer’ ❌ 虽然这是预期的。 正如我们前面所讨论的,该协议是一种抽象类型,尽管它可能具有通用要求,但它本身并不是通用类型。 不是class SomeType { … }方式。 尝试2 好吧,让我们尝试使用JsonDeserializer作为一般约束,并将反序列化器放入一个代理对象,我们将其称为DeserializerBox (此处使用Box是为了与以后的类型擦除命名约定保持一致)。 这个错误告诉我们我们需要提供一种类型来满足DeserializerBox的通用类型要求。 不幸的是,这意味着要指定一个JsonDeserializer 。 但是,我们想使用任何为我们提供Payload类型对象的JsonDeserializer ,因此指定特定的反序列化器具体类型将无法达到目的。 这与仅将具体类型用作Session的deserializer属性的类型约束没有什么不同。 令人沮丧的是,这是进步。 尝试3和3.5ish 为了弥补我们缺乏必要的类型争论,我们还需要DeserializerBox成为JsonDeserializer的真正代理对象,这意味着它应与JsonDeserializer 。 这意味着我们应该能够将代理与JsonDeserializer一样对待,并且它应该公开相同的接口。 为此,我们必须坚持使用JsonDeserializer […]

Xcode 10的构建系统和代码生成(R.swift)

Xcode 10包括一个默认启用的新构建系统,该系统可提高构建性能。 这是非常令人欢迎的改进。 R.swift是一个开放源代码库,它使使用图像,字体和segues之类的资源变得更加容易且类型安全。 这是一个非常酷的库,我们已经在Zendesk上成功使用了一段时间。 然而… 当构建使用R.swift和Xcode 10的项目时,构建将失败,并出现以下错误: 错误:找不到构建输入文件:/LOCATION/R.genic.swift R.swift使用Xcode构建脚本阶段集成到项目中。 此阶段生成一个Swift文件R.generated.swift ,该文件在构建项目时进行编译。 生成失败,因为具有新的并行生成系统的Xcode 10试图在创建R.generated.swift文件之前先找到它。 Xcode 10允许我们为构建脚本阶段指定输出文件。 我们可以将R.generated.swift文件添加为输出文件,如下所示: 这样可以成功构建。 太棒了! 🎉 额外 最初遇到此问题时,我们使用R.swift打开了一个错误。 但是,如上所示,该问题是由于Xcode的构建系统中的更改引起的。 而已! 📱🚀👍🏽 也可以在petethedeveloper.com上获得

UIKit:查看阴影

上次我们讨论了如何使视图的角变圆。 今天,按照承诺,我将向您展示如何使用layer.shadowX属性,以使视图看起来像Card,并获得其他炫酷效果。 让我们从简单而永不过时的Card View开始。 我知道你需要这个 myCard.layer.cornerRadius = 10 myCard.layer.shadowOpacity = 1 myCard.layer.shadowColor = UIColor(名称:“ Swift Orange”)!. cgColor myCard.layer.shadowRadius = 4 myCard.layer.shadowOffset = CGSize(宽度:4,高度:4) 该代码是不言自明的: 我按照上cornerRadius UIKit Rounded Views中的描述设置了cornerRadius属性。 我将阴影不透明度设置为从0到1的值,以将其应用于阴影颜色。 我设置阴影颜色。 我设置代表模糊半径的阴影半径。 如果您不愿意像我一样阅读,则只需要知道该值越高,图像就会越模糊。 如果您想学习,请单击此处。 最后,我设置偏移量,该偏移量是阴影相对于以点表示的图层的偏移量。 注意:要使阴影可见,请不要将layer的属性masksToBounds设置为true,否则它将被裁剪。 这还没有结束……还有一个阴影属性可供我们使用,以产生一些很酷的效果: shadowPath。 让我们看看如何制作一个像漂浮在设备屏幕上的视图。 让cardWidth = myCard.frame.width 让cardHeight = myCard.frame.height 让distanceFromCard = 15 myCard.layer.cornerRadius = cardWidth * 0.5 myCard.layer.shadowOpacity = 0.1 […]

乐观的后来者! 使用我的工作流程,准时! (针对居住在韩国的人)

标题可能有些古怪。 是。 我将在本文中向您介绍的App(实际上是工作流程)仅对居住在韩国的人有用。 但是,即将发布的帖子将解释细节,这对于也渴望进行类似工作流程的人员将非常有用。 如果您现在不在韩国,我将很高兴等待下一个将在2周内上传的帖子。 对不起伙计,迟到10分钟! 每天醒来时,我都会向自己保证。 “今天,我永远不会迟到任何约会。”但是,当我与朋友们玩得开心或我的工作快要结束时,我强烈希望能在适当的时机结束这项工作,我的早晨誓言逐渐消失远。 是。 我给朋友们发短信“对不起,费拉斯,我来晚了。”我已经活了26年了。 所以,让我给自己一个超时时间。 我不是醒得很晚。 我可以很容易地调整睡眠时间。 我也不是住在交通十分稀疏的农村。 我住在城市里。 “那么,我迟到的情况是什么?” 我为什么迟到? 我认为这是因为我是乐观的后来者之一 。 有时,我迟到了,因为我不知道到达那里所需的确切时间。 我对距离感没有信心,所以我只是猜测要花多长时间而不是寻找google map应用程序。 同样不幸的是,虽然我知道要花多少时间和时间,但有时约会迟到了。 这是因为我希望现在就在这里完成当前的工作。 尽管我知道我会迟到,但我推迟了离开的时间,相反,我为自己辩解说,乘坐出租车或其他东西会准时赴约,这是错误的。 解决方案 总而言之,该处方应满足以下三个条件。 首先,我应该知道到达约会所需的确切时间。 其次,即使在规定的最短时间之前,至少应该在15分钟之前,我都应该给自己报警。 需要额外的时间来搁置我的作品。 最后,我应该跟踪自己的迟到情况,以监控自己的表现。 只是一种反馈。 我花了一些时间执行上述三个规则。 我在iPhone上做了一个小的工作流程,以使用Workflow App遵循上述条件。 它不符合我上面提出的所有三个规则,但它保留了关键值,即条件1和2。 有什么价值? 这个微型应用程序不仅计算移动时间。 还要花时间。 每次公交10分钟。 每次地铁4分钟) 另外,这个应用程式还比我要求的最短时间提醒我15分钟。 最重要的价值是, 此工作流程自动集成了您的google map应用和apple calendar应用。 因此,如果您输入目的地和约会时间,此工作流程不仅会告诉您将花费多长时间,而且还会在日历应用程序上进行活动,并在适当的时间向日历应用程序发出警报。 因为我住在韩国,所以此工作流程应用程序仅针对Korea Environment进行了优化。 您如何使用它 [安装] (1)单击此链接(Workflow App)并在iPhone上下载Workflow App。 不幸的是,Android不提供此应用程序。 […]

您的热敏打印机工作正常吗?

蓝牙热敏打印机与Apple iPhone,iPad,iOS和Android设备完全兼容。 例如,BIXOLON SRP-350热敏POS打印机已成为市场上基于移动的销售点系统的最通用的打印机。 它可以以最佳的价格和可靠性水平在市场上轻松获得。 您可以通过蓝牙将其连接到iOS或Android设备,并且只需很少的电线即可轻松进行设置(如果需要,只需电源和现金抽屉电缆)。 适用于任何酒吧,餐厅或零售场所以及贸易展览的完美解决方案。 另一台打印机, Citizen CT-S651 热POS打印机系列也属于具有惊人打印速度的同一系列。 每分钟可打印60张收据(300毫米/秒)。 它还配备了方便的“即插即印”收据纸卷装入系统,占地面积小,并且具有可靠的断头台收据自动切纸器,可让您熟练掌握业务应用程序。 因此,如果您正在寻找上面提到的如何固定热敏打印机的技巧,而实际上很多时候并没有损坏打印机,而是错误地装入了热敏纸,或者使用了错误的纸张,那么我们希望您知道一些可以帮助您重回正轨的步骤– 1)您需要通过用硬币或指甲刮擦纸的表面来验证纸卷是否是热涂层纸。 如果是热敏纸,则在刮擦的地方会出现黑色标记,如果没有,则不会留下任何标记。 2)您需要检查热敏纸是否正确装入,然后再次尝试打印。 3)您应该检查以确保您具有正确的卷筒尺寸或卷芯尺寸,太少或太大都可能导致问题。 因此,在将纸卷放入打印机之前,请记住这一点。 我们希望您了解检查打印机工作情况的机制。 否则,如果您正在寻找热敏票据打印机,则可以在Wish A POS上找到价格合理且可靠的系列。 更多详细信息@ http://wishapos.blogspot.com/2018/07/is-your-thermal-printer-working-properly.html

集成PayFort-我们受了苦,所以您不必

您认为您的客户要求您集成由Amazon构建的在线支付网关时,您将会取得丰硕的成果。 这就是我的主要iOS开发人员(Tahir Pasha)在回应这张票时告诉我的:“因此,我将创建一个沙箱帐户,按照其文档中所述集成SDK,对其进行测试,然后切换到生产环境,就是这样” 从此链接获取文档, 此处的iOS SDK。 从您的沙盒帐户复制商家ID和访问代码, 在集成设置中,设置创建签名所需的REQUESTPHRASE 创建此链接上所示的签名, 您需要从SDK令牌URL获取SDK令牌,如文档第5.3节所示。 现在,通过该SDK令牌,您可以在移动应用中使用SDK来根据首选付款方式处理付款。 简单? 没有。 完成所有这些步骤并将您的应用提交审核后,您将遇到以下问题。 服务器端认证 将您的应用提交审核后,只有Payfort集成团队的人员才会通知您,您需要在服务器端而非移动应用上进行身份验证并获取SDK令牌。 因此,现在您需要在服务器端重做步骤5和6 。 从上面的步骤5:如服务器端此链接上所示创建签名,为此签名,您还将需要用户的设备ID 从上面的步骤6:从服务器公开一个API,该API接受来自移动设备的设备ID,如上所述创建签名,从Payfort请求SDK令牌,然后在响应中将该令牌提供给移动应用程序。 (ps,因为此代码与其余的后端体系结构无关,所以如果您为此独立于后端创建单独的微服务,则更好) 第7步将与上面相同,因为一旦在移动应用中安装了SDK TOKEN,您就可以执行与之前相同的其余任务。 直接交易反馈网址 您还需要配置直接交易反馈URL,Payfort将在其中处理交易后将响应参数发送给您。 Payfort说,如果用户由于互联网连接断开或他关闭了浏览器或者问题出在您身边作为连接商而导致用户重定向到您的return_url之前关闭了浏览器,Payfort会向您发送响应作为此URL上的POST表单。 这个想法很好,但是唯一的问题是Payfort希望您无需任何身份验证即可公开此POST api。 这会为您的数据库打开一些安全威胁。 因此,您需要创建另一个单独的微服务,它具有自己的私有数据存储,该数据存储仅处理这些响应(独立于您的主数据库),而没有其他处理。 即便如此,将这个api中接收到的信息与您的实际数据库合并也是另一个问题。 调试 调试PayFort提供的错误消息是另一个挑战。 例如: 错误代码001:他们的文档说这意味着“缺少参数”。 它没有指定缺少哪个参数。 进入生产 您会想象,当payfort将您的帐户从沙箱转移到生产环境时,他们也会为您移动所有设置。 但是不会,一旦您解决了上述所有问题,并且您的帐户已获准用于生产,则需要手动激活所需的付款方式。 然后,当您再次认为自己已经完成时,您可能还会面临最后一个问题 回购 是的,你没看错。 在一种情况下,如果在Payfort的末端处理付款时发生错误,或者用户决定在处理付款时取消付款,则Payfort API会给您一个回单而不是响应。 在所有其他api中为您提供消息的键称为“ response_message”,而在此特定api中,该键为“ resposne_message”。 我们花了几个小时才弄清楚这一点! 您还需要在您的应用程序中处理此拼写错误,否则它将崩溃 现在完成了 最后,我必须说,一旦设置好,Payfort是一项出色的服务,它的工作确实比我们上一个付款处理者做得更好。 与塔希尔·帕夏(Tahir Pasha)共同撰写 …………。 更新2019年1月10日 […]

数据结构(基础知识)

数据结构是解决算法问题的有用工具。 您可能熟悉的两个数据结构是数组和字典。 数组具有内置的函数,可让您解决问题。 您可以对数组进行计数,对数组进行排序,将项目追加到数组中,在数组中的项目之间循环等等。类似地,您可以将键值对插入字典中,从字典中提取键值对,等等。 ,队列和树是另外三个对您的代码工具箱有用的数据结构。 堆栈 堆栈有助于按特定顺序组织数据。 堆栈可归为三大功能: 推动将新元素添加到堆栈顶部 弹出以从堆栈顶部删除元素 窥视堆栈顶部而不弹出 与您放在桌上的一堆纸类似,添加到纸堆中的最后一个元素是可以从纸堆中删除的第一个元素。 另外,就像您只能看到桌子上纸叠顶部的纸上内容一样,您也只能看到编码纸叠中的顶部元素。 如果使用字符串,上面的示例很好,但是如果要使用其他类型,该怎么办? 没有恐惧! 泛型在这里! 使用泛型堆栈 s列 类似于堆栈,队列有助于按特定顺序组织数据。 与邮局在队列中等待的第一个人是第一个离开队列并得到服务的人一样,代码队列中的第一个元素也是第一个离开队列的元素。 队列可归为三大功能: 排队将新元素添加到队列 出队以从队列中删除元素 偷看队列中的第一个元素而不将其从队列中删除 像堆栈一样,您也可以将泛型与队列一起使用。 树木 树有助于提高搜索效率,提供排序的数据列表以及使对象之间具有层次关系。 树木由三个元素组成: 节点是树结构中的数据块 根是树的入口点(零级节点) 叶子 (终端节点)是没有子节点的节点 由于树是由节点组成的,因此我首先创建一个Node类。 此类由值,Node类型的子级数组(有时还包括Node类型的父级)组成。 您可能想知道为什么我指定Node类符合等于协议。 为了在使用泛型时实现搜索功能,我不得不让Xcode知道Node类实际上可以执行比较。 如果您要以树的方式考虑上述测试,它看起来像这样: 您可能已经听说过专门的“二叉树”。二叉树是其中每个节点只有0,1或2个子节点的树。 二叉搜索树是一棵树,它从树中插入和删除信息,以便始终对树进行排序。 要了解更多信息,请查看以下链接: 二叉树 二进制搜索树 参考文献: https://github.com/raywenderlich/swift-algorithm-club

SKStoreReviewController — Apple在ios 10.3及更高版本中的iOS应用中请求评论和评级的方式

每个应用程序开发人员的目的都是为了获取反馈或对其应用程序进行评论,以更好地展示其应用并鼓励其他人使用他们的应用程序。 通常,开发人员会向其应用程序提供自定义评论UIView以及UIStackview中的星图。 然后,将用户评分记录在后端中,但在进行应用商店评论时,用户通常会说“现在不选择”选项,因为该用户将从当前应用程序的屏幕中退出,进入Apple App Store页面。 我们是否因为这种行为而错过了用户的反馈? 苹果推出了“ SKStoreReviewController”,可在您的应用程序屏幕上显示评论UIView,并记录评论和评论。 无需任何用户导航到Apple应用商店即可提交他/她的评论。 凉。 是不是 三个简单步骤是: 导入StoreKit。 检查版本是否为10.3及更高版本。 if #available(iOS 10.3, *) { //call ios API method for review view. } else { //Use your custom review view. } 从视图控制器调用SKStoreReviewController.requestReview()。 if #available(iOS 10.3, *) { SKStoreReviewController.requestReview() } else { //Use your custom review view. } 多田! 系统将为您提供评论视图和星号,以对应用程序进行评级。 很好,但是在实现“ SKStoreReviewController”视图时,我们必须意识到某些要点。 […]

自定义导航栏

您知道您可以自定义导航栏吗? 我们开始做吧。 很简单 创建一个新项目。 转到情节提要。 单击ViewController。 转到“ 编辑器->嵌入->导航控制器 ”。 因此,创建了一个导航栏。 现在添加两个条形按钮。 将图像添加到您要显示在导航栏中的Assets.xcassets文件夹中。 现在开始编码。 转到ViewController.swift。 编写一个新的函数覆盖func viewDidAppear(animated:Bool)。 然后将此代码添加到函数中: 现在,让我们逐行浏览代码。 初始化导航栏。 定义导航栏的样式。 设置条形按钮的颜色。 初始化imageView,所以我们有一个显示图像的地方。 创建一个图像并将其设置为我们的imageView。 将imageView添加到我们的导航栏中。 做完了 运行项目 您的导航栏是自定义的。 超级容易。 参考文献: Главнаястраница

Server Side Swift入门:1.1

Turnstile SQLite演示 欢迎来到我的“ Server Side Swift入门”系列的第二部分。 在整个系列文章中,我将解释如何使用Perfect工具箱使用Server Side Siwft的各个不同方面进行入门和运行的基础知识。 本文演示了如何运行Turnstile SQLite演示并探索其Web路由和API,以及深入研究SQLite数据库并找出导致会话滴答的原因。 Turnstile是Stormpath构建的身份验证过程,其模仿Apache Shiro。 Perfect已将其作为该项目的身份验证选项之一,并带有SQLite,MySQL,CouchDB,PostgreSQL和MongoDB的驱动程序。 SQLite是一个出色的教学数据库工具,因为它基于文件,并且几乎不需要任何设置,并且所有Mac和大多数Linux系统都将SQLite作为标准配置。 但是,我不建议在大规模生产系统中使用它。 首先,如果您尚未获得Perfect Assistant应用程序,请访问https://www.perfect.org/en/assistant/以下载Perfect Assistant。 在“欢迎”屏幕上,单击“创建新项目”按钮。 这将滑落为两种项目类型的工作表。 在“示例”下,选择“完美:带有SQLite的旋转门”。 使用“浏览按钮”选择应用程序的位置-并根据需要创建一个新文件夹。 请注意,在Perfect Assistant中,“项目名称”是您选择的文件夹的名称。 取消选中“将Linux构建与Xcode项目集成”,因为在本演练中我们不会部署到Linux。 按下“保存”后,Perfect Assistant将继续创建项目,下载所有依赖项并创建Xcode项目文件。 完成后,您的项目也将列在左侧的“项目”列表中。 它向您显示了项目中已经存在的依赖关系-如果您没有看到自己认为应该存在的内容,请不要担心,子依赖关系也会自动包含在内。 从这里,您还可以在查找器或终端窗口中打开项目目录,然后打开Xcode项目。 在Xcode中,打开Sources目录,您将看到许多其他依赖项已自动添加到我们的项目中。 添加这些是因为它们是子依赖项。 在我们的项目源目录中是一个main.swift文件。 这包含用于运行演示的代码。 需要指出的几件事。 在第38行,我们在此处定义SQLite数据库文件的位置-SQLiteConnector.db属性设置为“ ./authdb”。 SQLiteConnector.db =“ ./authdb” 因为SQLite是基于文件的数据库,所以我们可以将文件放置在所需的任何位置,但是在这种情况下,我们告诉应用程序将其放置在运行时工作目录中。 您还将在项目浏览器中注意到,我们有一个名为“ webroot”的目录。 这是我们保留CSS,JavaScript和图像之类的静态资产以及胡子模板的地方,我们将在本系列的另一部分中介绍这些模板。 由于存在诸如SQLite数据库和webroot目录之类的文件,因此我们需要告诉Xcode在何处考虑“工作目录”。 在“方案”下拉列表中,确保选择“具有终端外观”的黑色图标,并确保目标是“我的Mac”。 现在,让我们选择“编辑方案”。 在“运行->选项”选项卡中,确保选中“工作目录”选项,然后单击文本输入区域中的“文件夹”图标并导航到项目的目录。 在这里,您将看到“ Sources”目录和“ webroot”。 现在可以运行项目-按下三角形的“运行”按钮,或在键盘上按下CMD-R。 构建完成后,Xcode将执行该应用程序,并在右下侧控制台视图中显示一条消息,表明它已在端口8181上启动HTTP服务器。 [INFO]运行设置:用户 […]