Tag: cocoa touch

CocoaTouch:框架和边界

用户界面是应用程序开发中最重要的部分之一。 我们的工作是创造出色的用户体验,以与其他应用程序脱颖而出。 但是,让我们先深入基础知识。 对于UI组件,我们必须考虑两件事: 我的元素有多大? 应该放在哪里? 我的元素有多大? 您必须考虑UI元素的宽度和高度 。 Core Graphics为该用例提供了一个结构。 CGSize结构{ CGFloat宽度; CGFloat高度; }; 应该放在哪里? UI元素使用坐标系定位。 这开始于(在iOS中)屏幕的左上角。 用CGPoint结构指定位置。 CGPoint结构体{ CGFloat x; CGFloat y; }; 两者在一起 现在我们有了大小和位置。 两者结合形成一个“矩形”。 还有一个同时包含信息的结构,称为CGRect 。 struct CGRect { CGPoint起源; CGSize大小; }; 仔细研究源代码,我们将看到矩形是一个包含已知结构(CGSize和CGPoint)的结构 。 帧 让我们创建一个新的UIView。 将矩形(大小和位置)指定为CGRect并将其作为参数传递给构造函数。 let rect = CGRect(x: 70, y: 70, width: 160, height: 100) let myView = […]

可可豆BLE PITFALLS

缩写(按出现的顺序) BLE –蓝牙低 PCB —印刷电路板 API —应用程序编程接口 每个使用iOS BLE的开发人员都知道,并非所有功能都像文档中所描述的那样好。 今天,我想描述一些使用BLE时可能会棘手的要点。 我想为您(读者,我想是BLE开发人员)提供一些信息,以使您在Cocoa BLE世界中的旅程更轻松,更高效。 因此,您首先需要知道的是以下问题的答案:“究竟是哪里出了问题—在我这边还是在连接的设备上? 当我向设备发送命令时,会发生什么情况吗?” 要获得此问题的答案,我建议使用以下几种方法: 嗅探器工具 用于测试API的第三方应用程序 测井 设备的固件版本,无需加密或任何其他保护即可与之一起使用 因此,让我们讨论每个点的更多细节。 嗅探器工具 -此工具可让您在不使用CoreBluetooth框架的情况下与数据包相交并对其进行分析。 区分BLE通信的不同方面(请求,响应,未处理的错误,意外消息等)可能非常有帮助。要设置此工具,基本上,您需要做一些事情:特殊的Ppcband固件Mac。 我使用了Wireshark和Nordic Semiconductors测试板。 它们一起为嗅探活动提供了强大的工具集。 嗅探器工具可以在两种模式下使用-广告和连接。 有用的链接是: 有关嗅探工具及其工作方式的信息 嗅探器工具— nRF-Sniffer-UG Wireshark XQuartz(某些版本的Wireshark需要) 用于测试API的第三方应用程序 -测试设备最快的方法之一就是使用第三方解决方案。 使用此类产品,您可以轻松扫描,发现,发送/接收甚至模拟设备的某些功能。 很好的例子是 浅蓝 蓝壁虎 记录 -大多数BLE设备与另一端的智能手机通话。 因此,了解手机本身发生的情况至关重要。 检查电话中发生的事情最有用的技术之一就是使用操作系统自己的日志记录功能。 在iOS中,启用蓝牙日志记录需要在设备中安装特殊的配置文件。 您可以在https://developer.apple.com/bluetooth/(链接是外部的)上找到有关启用它的更多信息。 启用后,iTunes可以将日志同步到计算机,并且可以对其进行分析。 固件 -为了保护自己的产品,通常在应用程序和设备之间使用加密的通信协议。 这种方法为用户确保了更高的安全级别,但同时在开发方面要困难得多。 为了简化此过程,请在开发过程中始终使用未加密的固件版本,并仅出于生产目的提供更高级别的安全性。 当然,这会稍微影响固件开发时间,但这也减少了您方面使用此类固件开发出色应用程序所需的工作。 至此,我假设开发环境已经启动并正在运行,而您所要做的只是弄污双手并编写一些代码以使应用程序栩栩如生:)。 现在,要确保您的用户获得最佳的用户体验,您应该完全控制应用程序内的所有进程,并相应地控制其所有方面。 基本上,您应该考虑以下几点: 蓝牙设备可用性(状态观察) […]

等间距的UICollectionView单元格

大多数iOS开发人员使用UICollectionView,并且应内置等距单元 问题 苹果的iOS类UICollectionView和UICollectionViewFlowLayout被许多应用程序开发人员使用,并且大多数情况下这些类可以很好地协同工作,不需要太多的自定义,但是它们做得不好的一件事是自动为所有设备布局分配单元格。 在开发负责显示大型组织的REST服务的照片缩略图的应用程序时,我发现了这个问题。 使用默认值,甚至使用稍微调整的值,我的布局看起来都类似于以下屏幕截图。 虽然单元格之间的水平空白可能很好,但垂直空白要么不存在,要么与水平空白不一致; 同样,在屏幕边缘周围留有一些空白也很好。 可以调整这些值,但是对于每个设备和方向,每个值可以不同。 当前,Xcode的Interface Builder编辑器和UICollectionViewFlowLayout类都没有提供自动设置这些值的方法。 解决方案 为了解决这个问题,我写了一个UICollectionViewFlowLayout的子类DSSCollectionViewFlowLayout,它重写了prepareLayout方法以计算属性minimumLineSpacing,minimumInteritemSpacing和sectionInset所需的值,因此每当用户更改设备的方向或布局时,它们都具有相同的值。应用程序。 进行此更改后,每个单元格周围的空白区域将变得更加令人愉悦。 尽管每个单元周围的空白空间在设备和方向上都不同,但是在特定布局内,空白空间是一致的。 在为Apple平台开发软件时,与编写源代码相比,我更喜欢在故事板和XIB / NIB中尽可能多地添加设置,因此我决定将属性placeEqualSpaceAroundAllCells添加到我的子类中,以便可以在集合视图的内部打开或关闭此功能。资源“身份检查器”面板。 我的子类DSSCollectionViewFlowLayout的Objective-C标头声明了属性placeEqualSpaceAroundAllCells,因此我的prepareLayout版本将知道是否执行等距的空白计算。 子类的prepareLayout实现的Objective-C源代码显示了如何计算水平或垂直滚动​​的正确空间。 而且,为了好玩,我也写了一个Swift版本。 我目前仅将此代码用于正方形和矩形固定大小的单元格,但它也应与可变大小的单元格的集合视图一起使用。

将iOS和Mac异步和相关任务封装到Cocoa Operation子类中

异步任务(例如,从网络中获取数据,解析,处理数据并将数据保存到本地缓存中)是当今应用程序执行的常规任务。 作为开发人员,我们必须确保UI /主线程运行平稳,并将长时间运行的繁重工作任务移入后台线程,以维持60 FPS动画。 Apple为开发人员提供了两种在后台线程中执行任务的方式: 大中央调度(GCD):开发人员可以使用队列在后台线程池中串行或并发执行任务的API集。 操作(也称为NSOperation):可可抽象类,代表要执行的单个任务单元。 它是一个线程安全类,具有开箱即用的内置状态,优先级和QoS,取消和依赖项管理。 在本文中,我们将构建一个异步的Operation子类,该子类可从GitHub API异步获取存储库,以及一个从属的Operation子类,可将获取的存储库数据解析并将其序列化为Swift类。 我们将建立什么 AsynchronousOperation:支持异步操作的Operation子类。 FetchRepoOperation:AsynchronousOperation子类,该类从上周开始使用URLSession异步获取最新趋势的GitHub存储库的数据。 ParseRepoDataOperation:操作子类,该子类使用Swift Codable和JSONDecoder将FetchRepoOperation中的数据解码并序列化为GithubRepo对象的数组。 游乐场页面:使用OperationQueue执行操作,在操作之间添加依赖关系,并使用完成块在操作对象之间传递数据。 使用Operation子类实现异步操作 默认情况下,Operation Class同步运行代码。 Apple提供了一种通过子类化isAsynchronous布尔属性并将其重写为true来异步运行代码的方法。 我们还需要使用枚举添加我们自己的状态管理属性,处理从就绪,执行和完成状态的更改。 当同时读写状态属性时,dispacth队列将用于对状态属性使用调度屏障来处理同步。 在启动函数中,我们检查任务是否未取消,如果取消,则仅调用finish将状态更改为完成并返回。 如果没有,我们将状态设置为执行并调用主函数。 我们的子类将覆盖main函数,以执行函数内部的任务。 实现FetchRepoOperation来获取Github API FetchRepoOperation是异步操作的子类,我们声明两个可选属性,fetchedData是一个Data对象,将用于存储来自API调用的数据响应,以及一个error属性,将用于存储来自API的错误如果发生,请致电。 在超类的重写的main方法中,我们构造URL和查询项,这些查询项将查询自上周以来创建的存储库,该存储库按星数降序排列。 之后,我们初始化URLRequest并使用URLSession调用异步数据任务。 在数据任务完成处理程序内部,我们将响应数据和错误分配给实例属性,然后调用finish方法将操作的状态设置为finish,以将操作标记为完成。 实施ParseRepoOperation以使用Swift Codable类解码JSON数据 我们创建GithubRepoFetchResult,GithubRepo,GithubOwner Swift类,该类实现了codable和CodingKeys枚举,以将json属性名称映射到实例属性骆驼案例名称。 通过使用Codable,我们可以利用JSONDecoder将Data解码为自动实现Codable的类。 实现ParseRepoOperation非常简单,我们将Operation用作子类,因为JSONDecoder的解码功能是同步的,因此我们不需要使用AsynchronousOperation。 我们声明了3个可选的实例属性,fetchedData是从FetchRepoOperation传递的数据,如果将数据解码为对象时发生错误,则错误为Error对象,包含GitHubRepo的repos数组将用于将JSONDecoding的结果存储到对象中。 在main函数内部,我们使用guard来解包可选的fetchedData,如果为nil,我们只是从函数中返回。 之后,在try catch块中,我们使用JSONDecoder解码函数,将fetchedData和GithubRepoFetchResult作为要解码的根类。 然后,我们将GithubRepoFetchResult中的items属性分配给repos实例属性。 如果解码时发生错误,我们会将错误分配给我们的错误实例属性。 使用OperationQueue执行操作 为了执行操作,我们使用OperationQueue,它充当优先队列,该队列使用先进先出机制来处理操作的执行。 我们将maxConcurrentOperationCount设置为1,因此我们的操作不会同时执行。 我们实例化FetchRepoOperation和ParseRepoOperation对象,然后将FetchRepoOperation对象添加为ParseRepoOperation对象的依赖项,因此将首先启动fetch任务,并且必须完成分析任务才能开始。 在操作之间传递数据并不容易,有许多方法可以做到,例如使用包含数据的数据包装器引用类,然后将其传递给每个操作。 对于此实现,我们将使用操作完成块,该操作将在操作完成时调用。 我们参考解析和提取操作对象为提取操作完成块分配一个闭包。 使用Unowned来避免保留周期,在该块内部,我们将获取响应数据传递给了解析的fetchedData属性。 我们为解析操作完成块属性分配一个闭包,该闭包仅循环存储库并将打印库的名称打印到控制台,以便我们看到结果。 最后,要开始操作,我们将调用包含获取和解析操作的数组传递给OperationQueue的addOperations来开始任务。 结论 可可操作类为开发人员提供了极大的灵活性,例如任务之间的依赖性,调整队列优先级和QoS,执行后台任务时的取消和状态管理。 […]

(iOS)可可触控框架

iOS애플리케이션개발환경코코아터치 iOS版,“可可接触框架”,“可可触摸框架”。 Cocoa Touch Framework的iOS版本,可下载的内容可在iOS上下载。 框架 는共享库(或API)개념으로,것입니다것입니다。 여기서“상위레벨”이란로그래머가필요한기능을가장사있있다는는。 상위레벨의Framework는내부적으로하위레벨의Framework를이용하여기능을다。 “媒体层”,“核心服务”,“核心OS”框架,“ Cocoa Touch”框架和“服务”。 可可触控框架,“ UIKit&Foundation” UIKit :iOS의UI를다。 MacOS X的UI和AppKit的下载,Mac OS X的用户界面和UIUI的应用程序都已下载。 Mac OS X的“ NS”로시작하는스의이의사름을다。 2. 基础 :프로그램의 应用의对象모든를리하는기본적인제공 메모리할당기반환하는정의 NS스와리와모두스들은’NS’로시작 예외)Foundation이이용하는CoreFoundation(=하위框架) :基金会基金会和CoreFoundation基金会。 (’CF’) “ CoreFoundation” :GUI와관련된Foundation(例如바이트,유니코드,문자열,숫자,달력,배열,사전,딕셔너리) 및세세및및및및설설설관를를를를를를를를를를를를를를를를를를 3. CoreData :框架。 속성을수명주수명주수명주와와와와와된솔루션공합니공합니공합니공합니공합니공합니공합니공합니공합니공합니공합니공합니공합니공합니솔루션공합니공합니솔루션 구현이터는구현구현50 50 50 50 50 50이–양–이–百分之五十至七十。 4. MapKit ::표시하고이스에지도미이미지를표시하고를정보를정도구모음입니도구모음입니다도구모음입니다。 5.核心动画 :iOS및OS X용할렌더링Graph Graph Graph […]

创建并发布Cocoa Touch框架。

在本文中,我将演示如何在不共享源代码的情况下创建和分发Cocoa Touch Framework。 Cocoa Touch框架与Cocoa Touch静态库。 创建可可触摸框架。 编写用于创建Cocoa Touch Framework的源代码。 测试框架而不发布 创建Pod规范文件。 验证.podspec文件。 发布Cocoa Touch Framework窗格。 发布后的测试框架。 答:静态库是已编译源文件的集合,这些源文件随后直接链接到应用程序的二进制文件中。 也就是说,它成为您应用程序二进制文件的一部分。 框架是一个独立的实体,其中包含一个二进制文件,该二进制文件包含已编译的代码(以及所有相关资源),而其本身就是一个独立的单元。 B.从iOS 8开始支持Cocoa Touch框架。 如果需要在iOS 8之前支持iOS版本,则应考虑使用Cocoa Touch静态库并在Objective-C中编写代码。 C. Cocoa Touch静态库不支持Swift。 因此,如果您决定使用Cocoa Touch静态库,则需要使用Objective-C。 D.与静态库相比,框架在项目中进行设置所需的手动工作更少。 A.创建可可触摸框架: 文件>新建>项目(命令+ shift + N),然后在iOS选项卡下选择Cocoa Touch Framework。 B.输入您的框架名称和其他详细信息。 根据需要选择语言Swift / ObjectiveC。 C.创建的框架看起来像。 A.创建新文件: 右键单击项目名称文件夹,然后选择“新建文件”。 在iOS标签下选择Swift文件。 输入文件名,然后单击创建按钮。 B.创建公共类: C.通过使用任何iOS模拟器(与通用iOS设备类似)构建项目,为iPhone模拟器生成框架。 D.在Finder中显示框架。 A.为框架创建演示项目: 要创建演示项目,请依次选择文件>新建>项目(命令+ shift + […]

在Swift中使用CoreNFC构建NFC扫描仪应用

近场通信(NFC)是一种技术,它可以在一定距离(通常约4厘米)内的两个设备之间实现非接触式通信。 如今,NFC已用于非接触式支付系统,电子身份证,电子票证中,并用于共享信息,例如联系人,照片,视频或URL。 可以用于使用NFC读取信息的此类标签或卡称为NFC标签。 根据维基百科,在完整的NFC设备中可以执行3种通信模式: NFC卡仿真 使支持NFC的设备(例如智能手机)像智能卡一样工作,允许用户执行交易(例如付款或票务)。 NFC读/写器 使启用NFC的设备能够读取存储在标签或智能海报中嵌入的廉价NFC标签上的信息。 NFC对等 使两个启用NFC的设备相互通信,以特定方式交换信息。 iOS中NFC的当前状态 iOS中的NFC始于2014年的Apple Pay发行。iPhone7和iPhone 7 Plus是第一批内置NFC硬件的设备,可用于使用Apple Pay执行非接触式支付。 但是,除了Apple Pay功能之外,Apple没有提供任何API供第三方开发人员使用NFC功能。 苹果最终在iOS 11中引入了CoreNFC框架,该框架使第三方开发人员能够在其应用程序中读取NFC标签。 当应用程序在前台运行时,该API仅支持读取NFC标签。 在iOS 12中,随着Apple新款iPhone的发布:Xr,Xs,Xs Max,Apple终于引入了扫描NFC标签的功能,而无需使用这些设备运行应用程序。 它还使用Apple Universal Link机制处理将扫描重定向到关联的应用程序。 截至目前,CoreNFC还无法写入NFC标签。 我真的希望iOS 13将为第三方应用程序提供写入标签的功能,因为执行写入所需的硬件已经存在。 我们将建立什么 在本教程中,我们将构建一个充当产品扫描程序的简单应用程序。 这是该应用程序的主要功能: 该应用程序将扫描NFC标签并获取关联的URL,以检索产品SKU ID; 然后,该应用会使用特定的SKU ID搜索其本地数据存储; 如果找到,该应用程序将显示产品的详细信息,例如名称,图像,描述,价格和可用性; 使用Apple Universal Link和Firebase托管无需运行应用程序即可扫描NFC标签。 开始项目 您可以从下面的GitHub存储库中克隆入门项目源代码: alfianlosari / NFCScanneriOSStarter NFC产品扫描仪iOS演示应用程序的入门项目– alfianlosari / NFCScanneriOSStarter github.com 入门项目包含所有自定义表格视图单元格,将在应用程序UI中使用的资产以及Product模型。 产品型号和本地数据存储 我们使用具有几个属性的Product模型来表示产品。 请记住,产品ID是每个产品的唯一标识符,商店将使用它来查找产品。 […]

使用UICollectionView构建自适应的自适应iOS应用

UICollectionView是一个UIKit视图,用于管理已订购商品的集合,并使用可自定义的布局显示商品。 它是由Apple在WWDC 2012中随iOS 6 SDK发行而引入的。 UICollectionView接口与旧的UITableView非常相似,因为它提供DataSource作为显示数据的源,并提供Delegate处理每个项目的交互。 与UITableView在UITableViewCell内部使用固定列表布局显示每一行不同, UICollectionView通过子类化UICollectionViewLayout为开发人员提供了灵活性和可自定义性以提供自己的布局,它还支持自定义装饰视图,每个单独的横断面图和单元格的可自定义大小。 Apple本身提供了一种UICollectionViewFlowLayout布局,称为UICollectionViewFlowLayout 。 UICollectionViewFlowLayout是使用网格系统显示项目的布局,并支持页眉和页脚。 它还提供了2个垂直和水平滚动方向。 在垂直方向上,项目的宽度受集合视图的宽度限制,因此在每一行中,它会尝试在下降到下一行之前在集合视图宽度的范围内填充尽可能多的项目,因此用户可以垂直滚动内容。 在水平方向上,内容的高度受集合视图的高度限制,因此在每一列中,在向右移动到下一列之前,将尽可能多地添加项目,以便用户可以水平滚动。 如果要使用集合视图构建圆盘传送带,则水平滚动方向非常适合。 我们将建立什么 在本文中,我们将使用UICollectionViewFlowLayout构建一个自适应的电影列表应用程序,以适应从小型iPhone 5到最大iPad Pro的各种UICollectionViewFlowLayout 。 用户将具有使用列表,小网格和大网格布局显示电影的选项。 以下是我们将要执行的任务: 启动项目。 建立模型。 构建MainListViewController 。 构建列表布局。 构建网格布局。 开始项目 要开始项目,您可以在下面的GitHub存储库中下载入门项目。 alfianlosari /响应式iOS收集视图启动器 带有Collection View的自适应和自适应iOS App的入门项目… github.com 入门项目包含多个资产,用于列表的集合视图单元格以及我们将用于集合视图的网格项目布局。 建立模型 让我们创建代表电影的模型。 创建一个新文件,并将其命名为Movie.swift 。 复制下面的声明以创建具有所有属性的Movie结构。 我们还需要确保更新MovieLayoutListCollectionViewCell ,在这里我们创建一个方法setup(movie:)以便在通过电影时可以设置标签和图像视图。 建立网格布局 让我们构建网格布局,在此布局中,每个单元格将仅在每个单元格内显示电影的海报图像。 窥视入门项目提供的MovieLayoutGridCollectionViewCell ,以查看布局。 确保更新MovieLayoutGridCollectionViewCell ,在这里我们创建一个方法setup(movie:)以便在通过电影时可以设置图像视图。 结论 最后,恭喜!我们已经成功使用Collection View构建了自适应的自适应iOS应用程序! 借助Cocoa Touch […]

使用Swift 5结果类型构建简单的异步API请求

Apple终于在2019年3月底将Swift 5发布到稳定版频道。它捆绑在macOS的Xcode 10.2中。 Swift 5为Apple平台中的Swift标准库提供了ABI稳定性。 这意味着,所有未来的Swift版本将与使用Swift 5代码编写的应用二进制兼容。 它还引入了App Thinning,缩小了应用程序的大小,因为ABI的稳定性意味着二进制文件不必将所有Swift标准库嵌入应用程序包中,从而减小了应用程序的大小。 从iOS 12.2开始,操作系统将包括Swift运行时和标准库。 您可以在下面的链接中阅读与Swift的未来有关的所有有关模块稳定性和库演变的信息。 ABI稳定性和更多 在MacOS,iOS,watchOS和tvOS上稳定Swift的ABI是一个长期的目标。 swift.org 是一个稳定的ABI。 在本文中,我们将讨论Swift 5的新Result类型,以及如何利用它来创建异步API请求并简化对完成处理程序闭包的处理。 在开始之前,让我们看看我们通常如何在Swift中创建一个异步函数。 我们通常使用几种方法。 1. Objective-C风格 使用Objective-C样式,我们创建一个带有多个参数的单个回调closure ,其中包含异步函数中的可选result value和可选error 。 func fetchMovies(URL:URL,completionHandler:@ 转义 ([Movie] ?, Error?)-> Void){ … } 2. Swift风格 在这种样式中,我们创建2个完成closures 。 一种是将result value作为参数处理成功,另一种是the error作为参数处理失败。 func fetchMovies(URL:URL,successHandler:@ 逃逸 ([Movie])->无效,errorHandler:@ 逃避 (Error?)->无效){ … } 介绍Swift 5结果类型 Swift 5最后引入了新的Result类型,以使用enum来处理异步函数的结果。 只有两种情况都使用带有关联值的Swift […]

Swift 5.0引入了新的结果类型…..?

Swift 5.0引入了新的 结果类型 作为通用枚举实现的,有两种情况 :。 成功和。 失败 , 在每种情况下都包括一个关联值。 值与大小写关联。 成功可以是任何值(取决于您)。 值与case关联。failure必须是采用Error协议的类型 。 为什么? 结果类型 — 它 提供 了一种更清晰,类型安全的错误处理方式。 例如-让我们创建一个简单的函数toInteger ,它将字符串转换为整数并返回Result 。 请注意, case .success的关联值是Int类型,而case .failure的关联值是AnErrorType类型,该值采用Error协议。 现在我们可以像这样使用它: 因此,通过使用 Result类型 ,很明显,我们可以获取 Int 类型的 结果值 或 AnErrorType 类型的强类型错误值 。 不可能 全有 或 全无 结果类型 提供 了更清晰,类型安全的错误处理方式。 另外, Result类型支持特定的初始化器,该初始化器接受引发的闭包- 例如 – 目前为止就这样了。 感谢您的阅读! 这是我有史以来第一篇中级职位。 我希望本快速阅读可以使您快速了解利用枚举功能在Swift 5.0中引入的新Result类型。 我真的很感激我的任何建设性批评,请随时在这里发表您的看法。 请通过与世界各地的Swift爱好者分享并分享这篇帖子,来帮助我传播信息。 […]