到目前为止,我们已经为Raspberry Pi构建了Haskell Cross Compiler,并且为Android构建了Haskell Cross Compiler。 为了解决这个问题,我们还将为iOS构建一个交叉编译器。 WWDC发出信号通知32位设备的末尾,最后32位设备是iPad(第四代)和iPhone 5 / iPhone 5C,我们将只构建64位交叉编译器。 请注意,Apple 在其他地方 将 arm64 称为 aarch64 。 这是很不幸的。 SDK和LLVM Apple随Xcode一起提供了iOS SDK。 因此,需要AppStore的Xcode的最新副本。 由于Apple不随Xcode一起交付opt和llc ,而且GHC当前要求llvm4提供opt和llc ,因此我们也需要从LLVM发布下载网站获取副本。 工具链包装 Apple为xcrun实用程序提供了针对我们所需工具的自动设置工具链。 但是,我们仍然需要提供目标前缀别名,以实现更好的自动工具互操作。 最初的设置工作归功于ghc-ios-scripts,我们将使用经过稍微修改的版本: #!/ bin / bash 名称= $ {0 ## * /} cmd = $ {name ## *-} target = $ {name%-*} 案例$ name *-阴谋) fcommon […]
在本教程的第1部分中,您将学习如何在不使用情节提要的情况下以编程方式创建自定义注释。 在第2部分中,我们将添加通过使用地理编码而不是对坐标进行硬编码从地址创建注释的功能。 步骤1:启动没有情节提要的新应用程序 如果您不知道如何在没有情节提要的情况下开始新项目,则可以阅读我以前的教程之一。 iOS-没有情节提要的应用 本教程将教您如何在没有情节提要的情况下启动应用程序。 以编程方式创建应用程序… medium.com 步骤2:设置MKMapView 在ViewController.swift文件中,我们将创建一个MKMapView实例并设置其约束。 请按照以下步骤操作。 导入MapKit,以便我们创建一个MKMapView实例。 将MKMapView实例添加到ViewController.swift类。 将此实例作为子视图添加到视图控制器的视图。 设置MKMapView实例的约束。 步骤3:为我们的自定义注释创建模型 在您的项目中添加一个新的swift文件,它将代表您的自定义注释。 在这个新文件中,请按照以下步骤操作。 导入MapKit。 使用NSObject作为新类的超类,并采用MKAnnotation协议。 添加一个属性来存储注释的坐标,另一个属性来保存标题。 创建一个初始化程序以构造您的自定义注释类的对象。 现在,在ViewController.swift文件中,执行以下步骤。 采用MKMapViewDelegate协议。 将mapView的委托属性设置为self。 实现mapView函数,该函数允许您显示自定义注释。 创建一个注释并将其添加到您的mapView中。
最近几个月,我一直在研究WebRTC,以为我目前正在使用的iOS应用实现视频和音频通话功能。 最近,我们的团队计划添加低数据模式功能。 是的,就像WhatsApp上的低数据模式功能一样。 低数据模式的目的是减少拨打电话时将使用的数据量。 每当用户启用低数据模式时,我们必须做两件事 我们必须控制(减少)WebRTC在拨打电话时将使用的带宽。 我们必须降低视频质量,以便以减少的带宽传输视频。 在开始使用此功能之前,我去做了一些研究,以检查是否有针对我们正在尝试解决的问题的解决方案。 那是我偶然发现以下文章的时候。 如何通过修改SDP来限制WebRTC带宽– webrtcHacks WebRTC 1.0使用SDP进行各方之间的协商功能。 尽管有越来越多的物体进入…… webrtchacks.com 这篇文章的灵感来自上述文章,您可以去那里阅读。 这是一篇很棒的文章 。 我采用了上一篇文章中提供的解决方案,并在iOS的Swift中复制了它。 让我们看一下如何控制带宽并降低呼叫的视频质量以支持带宽。 我们可以通过降低用于拨打电话的视频源(摄像机)的帧频来降低通话的视频质量,如下所示。 创建视频源时,使用媒体限制降低呼叫的视频质量。 该webrtchacks文章指出,我们可以通过修改SDP来控制WebRTC在呼叫期间使用的带宽。 因此,在修改SDP以控制带宽之前,让我们先了解一下SDP是什么。 如果您使用过WebRTC,那么您肯定会碰到SDP。 WebRTC使用SDP协商双方(Dialler和Receiver)之间的功能以建立呼叫。 SDP会话描述由以下几行文本组成: = 其中必须精确地是一个区分大小写的字符,而是结构化文本,其格式取决于。 您可以从规范中阅读有关SDP的更多信息:RFC 4566 SDP:会话描述协议。 TLDR; 上面提到的RFC表示将对SDP中的类型进行排序。 由于我们对控制带宽感兴趣,因此我们仅关注提供媒体描述的SDP部分。 SDP的媒体描述部分的类型如下:m,i,c,b,k,a。 根据RFC 3556 RTP控制协议(RTCP)带宽的会话描述协议(SDP)带宽修改器,我们可以使用b线设置带宽,其中b = AS:XXX,其中XXX是我们要设置的带宽。 AS部分表示它是“ Application Specific Maximum”,这表示它在限制总带宽。 同样从RFC中我们可以看到,我们需要以每秒千比特为单位指定带宽值。 因此,基于RFC,要设置带宽,我们的代码应执行以下操作 跳过SDP中的行,直到找到m = audio或m = video行 跳过i和c行 如果我们有b行,请对其进行修改 如果我们在i和c行之后没有b行,请添加新的b行 […]
烤面包视图是一个短暂的小弹出窗口,它为用户提供了一小部分信息(请参阅我在那儿做了什么?)。 这是一个Android范例,但是如果您正在使用具有Android组件的iOS应用程序,那么您曾经或将被要求在某个时候实现一个应用程序的可能性很高。 因此,您不妨学习如何简单地制作一个,而不必引入第三方依赖性,对吗? 好吧,那就开始吧。 我将专注于帮助您掌握动画的基础知识。 视图的实际外观可以留给比我更多的才华横溢的设计师使用。 我们将为从导航栏上下来的吐司做动画,但是所学到的教训不必与确切的实现方式联系在一起。 根据需要创建动画。 这是我们希望达到的最终结果: 动画转换 通常仅出于动画目的而修改视图的框架是一个坏主意。 我们将为转换设置动画。 视图frame的职责是设置视图在视图层次结构中的位置。 transform的责任是对视图对用户的外观进行任何修改。 您可以修改视图的变换以旋转,缩放或重新定位。 我们将使用它来重新定位屏幕上的视图并为更改设置动画。 1。 首先,创建吐司视图。 通过将其框架的y位置设置为视图高度的负值,将其定位在当前视图上方。 这会将其放在用户看不到的导航栏后面。 它偷偷地躲在幕后,直到我们对其进行动画处理。 2。 根据视图的高度转换视图的变换。 平移是位置的变化,类似于旋转是角度的变化, 比例尺是大小的变化。 您可以在transform属性上使用以下三种方法来平移,旋转和缩放动画: translatedBy(x:y:) rotated(by:) scaledBy(x:y:) 在第一步中,我们将烤面包的位置精确地定位在视图上方。 通过添加一个变换将其向下移动到最大高度,我们可以将Toast放置在适当的位置,并使它看起来好像它从导航栏的后面掉落了一样。 3。 一旦完成对视图转换的动画,请反转动画。 在视图的变换上反转任何动画非常容易,只需将变换设置回CGAffineTransform.identity 。 这是用于创建所有视图的默认的,未经修改的转换。 在缩放,旋转和平移之后,可以通过将转换重置回CGAffineTransform.identity来回到其舒适区域。 4。 动画的反转完成后,请从层次结构中删除视图。 根据您要制作的动画的确切程度,此步骤可能不是必需的。 但是,对于吐司视图,该视图是瞬时视图,因此我认为最好尊重瞬时吐司的心理模型并将其从视图中删除。 使用UIViewAnimationOptions播放动画的时间安排。 您可以使动画变得容易进出,也可以将其设置为重复并反向运行。 而且,当您准备好继续动画向导的旅程时,请开始探索UIViewPropertyAnimator。 您可以轻松简洁地自定义动画的时间安排,动态更改其方向,甚至使其与用户互动。 祝您玩得开心,Swifting开心!
剧透警报:您根本不写! ⭐️⭐️⭐️️⭐️⭐ 嗨! 此帖已移至新博客! 来到Fivestars.blog以获得最新文章! ⭐️⭐️⭐️️⭐️⭐ 上周,我写了关于如何在Swift中编写著名的Dijkstra算法的代码:本文是其后续内容。 我的原因 我没有写上一篇文章,而是花时间做文章研究:我所有的Metro Metro应用程序都实现了类似的算法。 在本文中,我将向您展示为什么您不需要利用我的相同方法,即利用Apple提供的工具并以更少的努力获得相同的结果 (同时获得其他好处)。 介绍GameplayKit 在Apple的数十种框架中,有GameplayKit:无论您的应用程序是否为游戏,该框架始终可供您使用。 但是什么是GameplayKit? 我很高兴你问! 我将让Apple的GameplayKit指南为您解答: GameplayKit是用于在iOS,OS X和tvOS中构建游戏的基础工具和技术的集合。 构建,发展和维护复杂的游戏需要精心计划的设计-GameplayKit提供了一些架构工具,可帮助您以最小的努力设计模块化,可扩展的游戏架构。 哇,这个框架听起来很多东西! GameplayKit核心 让我们使用分而治之范例更好地理解此GameplayKit,以下是其主要核心(摘自Apple的GameplayKit指南): 随机化 。 使用标准算法的这些强大,灵活的实现方式作为多种游戏机制的构建块。 实体和组件 。 通过在此架构上构建,设计更多可重用的游戏代码。 状态机 。 使用此体系结构可以解开游戏设计中的复杂程序代码。 Minmax策略家 。 为基于回合的游戏和AI玩家对象创建模型,并使用该模型计划最佳移动。 寻路 。 用图形描述游戏世界,允许GameplayKit规划游戏角色遵循的最佳路线。 代理人,目标和行为 。 使用此模拟可以使游戏角色根据高级目标移动自己并对周围环境做出反应。 规则系统 。 将游戏设计与可执行代码分开以加快游戏开发周期,或实施模糊逻辑推理以向游戏中添加逼真的行为。 等等…又是什么第五点? 5.寻路 。 将[…]世界描述为图表 ,[…] 规划最佳路线 […] 这听起来很像我们正在尝试做的事情! 让我们深入研究。 GameplayKit 寻路 […]
嗨,向导。 首先,让我们自我介绍。 我们是Pinga(www.pinga.co.uk),我们让人们轻按一下按钮,然后在15分钟之内将任何东西运送到他们家。 我们还帮助人们赚钱,在社区中随时随地为人们完成小任务。 通过将这两个群体联系起来,我们希望改变社会,使其更正常地为您周围的人提供帮助。 酷吧? 我们处于740亿英镑产业的中心,这个产业正以惊人的速度增长。 我们完全有能力通过取消传统的交易快递公司,而由恰好在正确的时间放置在正确的地方的本地人员来代替按需交付。 这对消费者也很重要,因为他们可以更便宜,更快捷地交货! 那么我们在做什么呢? 我们已经18个月大了,刚刚结束了我们在诺丁汉的成功启动活动之后的第二次募集资金,该活动在短短几个月内下载了3,000个用户。 我们热爱我们的工作,因为我们每天都处于“现状”,并使共享经济发挥到最大。 现在是关键时刻。 Pinga在伦敦启动,以证明这种改变世界的概念可以使其成为世界上最好的城市。 这意味着要加快产品开发的步伐,我们确实有很多工作要做。 我们收到了很多用户反馈,我们的产品路线图涵盖了整个办公楼层。 管理此产品开发是向导iOS开发人员的工作。 有人会将此职位称为iOS首席开发人员,但这与您实际要做的工作并不相近。 根据您过去的工作,我们会预算合理的薪水,并提供大量的认股权。 那么角色实际上是什么样的? 从根本上讲,您需要喜欢编码。 最初,我们希望您以已经拥有的Swift代码为基础,但我们完全可以稍后再进行架构设计-开始扩展时需要在Android上使用,因此我们希望您拥有当需要这样做的时候,对学习新语言(例如React Native)的热情。 但是,您将不仅会做到这一点,而且会生活并拥有问题,并提出解决这些问题的好主意。您将在现场进行思考,改进主意并看到潜在的陷阱。 那你呢 好吧,我们并不是规则的坚持者,但是我们希望您已经编码了至少两年了。 现在我们不在乎是在您的卧室,当地酒吧还是在埃菲尔铁塔上。 我们还需要您说双语(在代码中是)。 最后,请告诉我您已经将应用程序从概念移植到App Store? 现在,必须要做的事情……您必须乐于在我们拥有的基础上继续工作-不用担心这是很棒的代码。 您必须加入我们的愿景,并且您必须像我们一样。 否则,它的效果确实不好。 现在,这里的必备品真是太好了。 一些后端经验会很棒,特别是PHP。 另外,如果您对区块链的事情一无所知,我们会不断听到这是另一个好处。 对,那么我们需要您做什么? ●通过电子邮件将指向您的LinkedIn个人资料的链接发送给我们(现代的iOS向导不需要简历) ●在该电子邮件中,您还可以回答以下问题吗? 现在,如果您完成所有这些操作(很抱歉,很多操作),那么我们保证我们的CEO将在24小时内回复您并提供有关您的应用程序的反馈。 保证。 我们的iOS向导问题(请简短易懂!) 您显然已经从App Store下载了Pinga,那么您对此有何看法? 你会改变什么? 您将如何改善? 你最喜欢什么书? 命名您认为以最佳方式实现了产品市场适应的产品,为什么? 请通过主题行“我是iOS向导”通过电子邮件将您的LinkedIn个人资料和答案发送至jack@pinga.co.uk。
预习 资源 项目 https://github.com/calmone/iOS-UIKit-component 参考 UIBezierPath https://developer.apple.com/reference/uikit/uibezierpath 快乐编码😄
探索Apple当前推荐的日志记录方法 特别是在登录Swift和iOS应用程序时,首先想到的API可能是print和NSLog 。 但是,最近,Apple以统一日志记录的形式引入了新的日志记录标准,可以通过OSLog访问。 这是当前推荐的日志记录方式,提供了一种在我们的应用程序中捕获信息的有效方法。 统一日志记录对以前的技术进行了许多改进,并且与我们习惯的有所不同。 可以在适当的级别记录每条消息,包括:默认,错误,调试和信息。 它们会影响向我们显示和保留消息的方式。 消息按子系统和类别分组,以实现有效的搜索和过滤。 由于系统是为提高性能而设计的,并且仅在读取时才呈现日志,因此无需将日志语句包装在条件语句中。 认真考虑用户隐私,需要将动态字符串内容显式标记为public,否则将在任何日志中将其删除。 让我们开始记录 从Swift使用统一日志记录就像使用os_log函数一样简单,我们很快就会注意到,它使用StaticString作为参数而不是常规String 。 记录消息的最简单方法是将String常量直接放在函数调用中。 可以将消息提取到属性,但是,我们需要将其类型定义为StaticString 。 由于StaticString要求,我们需要使用format参数,而不是使用字符串插值。 最初可能会感到不舒服,但是要适应它并不难,它为用户隐私提供了好处,我们将在后面讨论。 我们可以访问所有标准格式参数,以及许多附加值类型的解码器。 想法是,日志记录系统会为您处理尽可能多的格式,以使系统效率更高。 有条理很好 调用os_log可以指定要使用的OSLog ,其中包含特定的子系统和类别。 在筛选,搜索和稍后尝试了解我们的日志时,此信息非常宝贵。 如果未指定log参数,则使用默认参数,该参数未配置子系统或类别。 子系统将特定应用程序或模块的所有日志分组,从而使我们能够过滤所有自己的日志。 从评估Apple的日志来看,子系统的约定是反向域样式,例如应用程序或框架本身的捆绑标识符。 如果将应用程序模块化到框架中,则最好使用框架的捆绑标识符将日志分为相应的组件。 类别用于将日志分组到相关区域,以帮助我们缩小日志消息的范围。 类别的约定是使用易于理解的名称,例如UI或User 。 我们可以将日志分组为跨多个子系统或功能(例如Network或Contacts 。 或者,我们可以将特定类的所有日志分组,例如Contacts Repository 。 在同一个项目中结合使用这两种方法是完全可以接受的,我们应该简单地使用最合适的类别,以使我们了解项目日志消息的上下文。 我们可以将不同的类别和子系统添加为OSLog的扩展,从而可以在整个应用程序中轻松访问它们。 将它们存储在一个地方可以避免在整个代码库中创建OSLog实例,并有助于使使用中的不同类别井井有条。 记录级别 统一日志记录系统采用一组不同的日志记录级别,在这些级别上,我们可以针对不同类型的消息。 级别控制如何向我们显示消息,如何以及何时保留消息以及是否在不同环境中捕获消息。 甚至可以通过我们机器上的命令行来定制系统如何处理每个级别。 为每个消息使用最合适的日志记录级别是一个好主意,以最大限度地利用我们的日志记录系统。 默认值 :如果没有其他合适的级别,则捕获可能导致失败并实质上回退的所有内容。 除非更改,否则消息将存储在内存缓冲区中,并在消息填满后保留。 信息 :捕获可能有用但未直接用于诊断或排除错误的任何内容。 除非更改,否则不使用持久性,消息仅存储在内存缓冲区中,并在消息填满时清除。 调试 :在开发过程中捕获信息以诊断特定问题,同时积极调试。 除非通过配置更改启用它们,否则不会捕获它们。 错误 […]
我在编码时曾遇到多次使用全局变量和局部变量的问题,所以我想写一篇关于它们是什么以及如何使用它们的初学者版的文章。 我假设本文的读者不了解其中的区别,并且在从事项目工作时不了解范围,因此我将首先解决该问题。 听起来,局部变量在项目的较小范围内起作用。 通常作为类实例或方法。 从技术上讲,范围在某些方面类似于同心圆: 如上所示,最里面的圈子有自己的范围或范围,并且在某些方面处于其他关联圈子的层次结构中。 范围也是如此。 一个本地范围可以在另一范围内,依此类推。 但是,回到局部变量。 局部变量通常是在程序范围内声明的变量,通常被视为类或方法内的子集。 另一方面,全局变量在整个项目中都有范围。 使用全局变量,您可以获取该变量的值并在完全不同的类中使用它。 这是关于全局声明的最甜蜜的部分。 它允许您进入同心圆的最内部,取走其中的任何东西,并在其范围之外使用它。 现在我们已经清除了那部分,让我们谈谈这有什么帮助。 好吧,可以说您正在运行一个异步方法或该方法中的任何方法。 可以这样说: class NameArray:UIViewController {let array = [[James,Mike,Ben,Lisa,Anna],[James,Mike,Ben,Lisa,Anna],[James,Mike,Ben,Lisa,Anna],[James,Mike, Ben,Lisa和Anna]] let nameArray = [String]() ///(这是类中的局部变量)////用于数组{let nameArrayForTBView = subarray [0] .name ///(这是for循环方法中的局部变量)//// nameArray.append(nameArrayForTBView) ///(nameArray是我所讨论的层次结构的一部分)/// }} 在上面的代码中,数组中包含数组,并且这些数组中包含字符串列表。 然后,您将获得一个for循环,该循环遍历数组并获取每个数组的第一项,因此索引为[0]。 这些第一项被附加到for循环外的变量中,而for循环外的变量位于类内(同心圆,范围)。 现在,我们有了一个充满名称的nameArray,它位于for循环之外。 现在说我们要把那些名字放在一个完全不同的文件中吗? 假设您想将其用作tableView计数。 现在您有两个选择: 选择1:让您的课程具有全球性 class NameArray:UIViewController { ///全局类(单例)/// 静态let shared = NameArray() let […]
在SCADE,我们始终在思考如何提高用户的工作效率。 我们通过SCADE 0.9.8.1达到的一个重要里程碑是SPM支持 。 我们对此感到非常兴奋。 这意味着您可以轻松下载,构建任何Swift SPM库并将其链接到SCADE项目中,并利用Android上以前只能用于iOS的Swift库 。 Marcin Krzyzanowsk的https://github.com/krzyzanowskim/CryptoSwift就是CryptoSwift。 它是一个纯Swift库, 实现了加密算法 。 CryptoSwift已变得非常流行,我们很高兴将其用于SCADE项目,并将其编译为Android。 在SPM功能的质量检查阶段,由于不明确的SPM规范,我们发现了许多较小的问题。 我们使用一些较小的库(例如SwiftMoment)测试了SPM,但是当我们第一次尝试使用CryptoSwift时感到惊讶。 它像一种魅力一样工作: 在依存关系部分中,指定URL和CryptoSwift的标记号 2.然后,导入库,并开始编码: 在Androidlet上导入CryptoSwift // strVal =“ Awesome = CryptoSwift和SCADE” 让strValMd5 = strVal.md5() 打印(strValMd5) 3.按编译,瞧瞧,CrytoSwift在Android上运行并打印 我们很高兴CryptoSwift和Android能够如此完美地一起玩。 要自己尝试,请尝试在此处进行辅导或观看视频 教程 https://docs.scade.io/docs/cryptoapp 影片 https://www.youtube.com/watch?v=GGkqO-0yQ9Y 维瓦·斯威夫特 您的SCADE团队 www.scade.io