完成框架后,您可能希望与Cocoapods共享它,以便每个人都可以轻松安装您的框架。 您的框架可能包含图像,gif或某些捆绑文件,本教程将显示如何通过pod.spec将资源包括到Cocoapods中。 顺便说一句,处理Cocoapods可能涉及一些基本的终端命令,如果您不熟悉终端,我建议您去找一些有关它的教程,因为在本教程中,我将不做详细解释。 在本教程中,我们将从头开始,创建一个GitHub存储库并编写一个名为SAProgressHUB的框架,最后,与Cocoapods共享它。 首先,让我们创建一个名称为SAProgressHUB的GitHub存储库。 不要忘记创建许可证。 现在,只需git将此存储库克隆到本地文件夹即可。 $ cd〜/ Documents / Hank_Private / $ git clone git@github.com:bbkaf / SAProgressHUB.git //下载成功后$ cd SAProgressHUB / $ ls -al 我们将创建.gitignore。 只需使用vim创建.gitignore和过去的gitognore https://github.com/github/gitignore/blob/master/Swift.gitignore $ vim .gitignore $ git add .gitignore $ git commit -m“添加.gitignore” $ git push 好的,现在让我们启动Xcode来创建我们的框架。 文件新项目选择“ Cocoa Touch Framework”。 使用GitHub存储库的名称来命名项目,使用不同的名称可能会给您带来混乱,我认为您不喜欢这样做。 现在让我们检查框架路径并进行提交,然后将其推送到GitHub $ ls -al $ git […]
要开始处理核心数据的关系,您应该对核心数据框架有所了解。 今天,我将通过适当的示例向您展示删除规则如何与核心数据关系一起工作。 首先设置项目,从xcode创建新项目,名称为Department,如下面的屏幕截图所示。 不要忘记选中使用核心数据复选框。 现在,是时候借助xcode接口创建数据模型了。 打开Department.xcdatamodeld并创建数据模型。 在这里,我将创建两个名称分别为Department和Employee的实体。 部门和雇员实体具有一个类似于名称的属性,更重要的是在这两个实体之间添加关系。 我创建了Department和Employee实体名称之间的一对多关系 ,因为departmentToEmployee因为部门有很多员工。 另外,我还添加了Employee和Department名称之间的To One关系,因为employeeToDepartment因为雇员只有一个部门。 下面的屏幕快照显示了两个实体之间的关系。 删除核心数据规则 现在是时候通过删除一个实体对象来考虑其他实体对象的影响了。 意味着如果员工被删除会怎样? 员工所属的部门是否也应删除? 否。但是,如果删除部门会怎样? 应该有没有部门的员工吗? 在这里图片处理这种情况。 为此,我们在核心数据框架中有删除规则。 每个关系都有删除规则。 删除规则定义删除拥有该关系的对象时发生的情况。 核心数据支持四种基本删除规则。 没有行动 无效化 级联 拒绝 无操作删除规则 如果将删除规则设置为对该关系不执行任何操作 ,则不会发生任何事情。 让我们举个例子,如果部门有很多员工,如果部门被删除,那么员工什么都没有发生。 员工认为其仍与删除的部门有关。 取消删除规则 如果将删除规则设置为对关系无效,则关系的目的地将变为无效。 在我们的情况下,如果部门有很多员工并且部门被删除,部门与员工之间的关系将失效。 这是默认的删除规则,我们经常在项目中使用此规则。 级联删除规则 此删除规则很重要,并且在将规则设置为realtionship时,请确保所有可能的情况。 当数据模型具有更高的依赖性时,通常使用此规则。 在我们的情况下,这意味着,如果部门有很多员工,并且部门被删除,则属于该部门的所有员工都会自动删除。 在使用此规则之前,请确保您的项目要求。 因为如果删除关系对象,此规则将删除所有记录而不会产生任何暗示。 拒绝删除规则 此规则功能强大,与级联规则完全相反。 它可以防止删除记录,而不是按照级联规则删除所有记录。 在我们的情况下,如果部门有很多员工,则仅当删除属于同一部门的所有员工或没有员工与同一部门捆绑在一起时,部门才被删除。 这全部与核心数据的删除规则有关。 在处理两个实体之间的关系之前,请先了解此概念。 在设置删除规则之前,请先了解您的要求。 我希望你们喜欢阅读这个故事。 如果您对此有任何疑问,请与我们联系。
打开Xcode并创建一个新的Cocoa Touch框架或Cocoa Touch静态库。 我们称之为: MyFrameworkProject 为此,您需要使用要在Playground中测试的库创建Podfile,例如在此处Alamofire: 来源’https://github.com/CocoaPods/Specs.git’ use_frameworks! 目标’MyFrameworkProject’做 pod’Alamofire’,’〜> 4.7′ 结束 然后运行: 吊舱安装 打开使用cocoapods创建的工作区并创建一个新的游乐场。 要白蚁,请在工作区中添加游乐场。 现在,您可以使用新创建的游乐场内的第三方库(此处为Alamofire)。 导入 UIKit 导入 Alamofire var str =“你好,操场” 您可以在这里找到代码:https://github.com/barrault01/cocoapods_insideplay_ground
测试代码和功能是构建任何应用程序的重要组成部分。 但是,不幸的是,在构建阶段进行测试有时可能很困难和/或耗时。 通常,我在编写代码时进行一些快速测试和故障排除的方法是在以下功能下实例化App Delegate文件中的对象。 然后,我将把打印语句放在类的函数或App Delegate中。 程序启动后,将执行此功能以创建每个对象的实例,然后查看控制台上打印的内容以评估是否实现了所需的功能。 但是,这很耗时,而且直言不讳,令人讨厌。 我要采取的另一种方法是将文件复制到操场上并在其中进行测试。 这很方便,因为它将在右侧显示进度和信息。 在功能和测试方面,它比应用程序委托提供了更多功能。 但是,这很不方便,因为一旦应用程序变得比几个文件大,您就必须复制很多副本。 此外,Playground文件通常按其写入顺序进行编译和运行,并且一行代码不知道在其下写入的任何内容。 因此,一旦程序变得有些复杂,就会引入一些问题。 知道有一种方法可以在Xcode项目中直接创建运动场文件,我认为必须有一种方法可以使该项目中的所有内容在该运动场中可用,并且肯定有! 随意打开Xcode,然后逐步学习,并逐步分享一些代码。 首先,让我们创建并命名一个新项目。 完成此操作后,右键单击左侧文件结构中的任意位置,然后单击“新建文件”,就像添加新的swift文件一样。 从这里选择游乐场,如下所示。 让我们创建更多文件,以便我们也可以进行一些测试。 请参阅下面的示例。 现在我们已经创建了一些测试文件,让我们进入我们的操场并尝试创建一个人。 您会注意到在自动完成中没有可用的初始化程序,并且您将收到类似以下的错误。 仅仅因为游乐场存在于Xcode项目中并不能使项目中的所有内容都可用。 我们将必须在项目中创建一个框架,然后将该框架导入操场。 要创建框架,请单击文件->新建->目标。 从菜单中选择Cocoa Touch Framework,然后单击下一步。 命名框架,然后单击完成。 保留所有其他选项不变。 单击完成之前,您的屏幕应如下所示。 现在已经创建了框架,我们必须将项目中的文件添加到其中,以便在导入框架时可以对其进行访问。 如果单击“个人”文件,您将在文件检查器中注意到创建的框架现在可用作目标成员身份。 选中框架旁边的框。 对性别和狗也要这样做。 这将包括框架中“人”,“性别”和“狗”文件的内容。 现在,让我们跳到游乐场文件。 需要像导入其他任何框架一样导入该框架。 为此,您需要在操场文件的顶部放置“ @testable import FrameworkName” 。 现在,您可以在操场上使用框架中包含的所有项目。 让我们尝试测试一些东西。 成功! 该项目的课程现在在操场上可用。 一旦对框架中包含的任何项目进行了更改,这些更改将不会在操场上反映出来,直到代码被编译。 通常,在框架方面,“干净”和“构建”是您的好朋友,因此,如果一切工作不正常,这应该是进行故障排除的第一步。 此外,在将新文件添加到项目中时,可以在创建文件时通过选择适当的目标将它们添加到框架中。 让我们向项目添加一个汽车类。 通过在DemoKit目标旁边放置一个对勾标记,汽车类将立即添加到框架中。 现在,我们将一些代码添加到car类中,然后进行构建并查看它是否在Playground文件中可用。 另外,让我们更新Person类,使其包含类型为“ […]
Android IDE在构建时自动生成一个R.java文件,该文件包含项目中每种资源类型的子类以及对其的静态引用。 例如,R.drawable.icon将是名为“ icon”的图像的ID。 在iOS中,我们不太幸运-加载资源文件需要我们指定其名称,例如:UIImage(named:“ icon”)。 这可能会导致一些问题: 不必要的强制转换-例如:使用标识符使可重用单元出队将导致UICollectionView类型的实例,但是在运行时,我们大多数情况下将有一个继承自UICollectionView的实例。 如果我们知道该单元格的标识符,那么我们就知道该单元格的类型。 由于错误的字符串标识符,导致运行时崩溃。 没有自动完成。 R.swift是一个模仿Android IDE R.java文件创建的框架:我们添加了一个在构建时生成R.swift文件的脚本。 该文件包含对项目中所有资源的静态引用,例如: 图片 字型 资源文件 色彩 本地化字符串 故事板 塞格斯 笔尖 可重复使用的细胞 因此,例如,看下面的行: 让图像:UIImage = UIImage(名称:“ imageName”)! 如果文件imageName不存在,它将崩溃(强制解开nil)。 相反,我们可以使用以下行: 让图像:UIImage = R.image.imageName()! 如果imageName文件更改了它的名称或从项目中删除了它,我们将收到一个编译错误! R.swift对我来说是必不可少的框架-没有它,我就不会开始一个项目! 我建议您转到它的GitHub存储库并检查文档中的其余示例。 快乐(安全)的编码🙂
这是我如何解决一个奇怪需求的简短简历,并发现了lldb高级命令的隐藏功能。 在谈论iOS / Mac开发中的框架时,通常会考虑在静态或动态库中构建的一组源代码文件,最终会嵌入一些其他资源。 有很多众所周知的工具(例如CocoaPods和Carthage)可以为您完成这些任务,因此这里没有什么新鲜事物。 最近,我们面临着一种可能被视为相反的方式:在我们的项目中有一个框架,我们有在另一个位置(项目之外)生成该框架的源文件,我们希望能够使用调试器逐步进入框架类。 那到底是为什么呢? 为了优化项目的构建时间,我们有一个特殊的流程,在该流程中,我们可以构建框架并将其提交到我们的仓库中,而不是源文件中。 尽管这有一些缺点可能值得在另一篇文章中讨论,但我们对结果感到非常满意,因为我们将构建时间减少了三分之一以上,从大约7分钟减少到大约2分钟。 此外,将我们的应用程序划分为多个框架迫使我们重新思考整个架构,从而清楚地将我们的依赖项隔离开来,这是一个不错的奖励! 我们构建的框架附带了DWARF调试信息,这些信息可以使用dwarfdump进行解析并转换为人类可读的内容。 该工具的使用真的非常有趣,并且可以提取的内容令人赞叹。 DWARF调试信息按节进行构造,每个编译单元一个节,并且通过调用dwarfdump –debug-info您将获得存储在.debug_info节中的所有信息。 其中包括符号之间的匹配以及源代码文件中的精确位置,如下面的屏幕快照所示。 请注意,源文件的路径是绝对路径,这意味着该文件甚至可能不存在(请考虑在另一台计算机上构建框架的情况)。 对我们来说幸运的是,我们正在不同的机器上构建框架,但是总是从同一路径/ tmp / SubitoFrameworksBuilder构建框架,由于这个假设,这只是重新映射路径的问题。 能做到吗? 是的,事实证明,使用lldb的以下命令确实很容易: settings set target.source-map ” ” 每次启动调试器时都要编写代码,这很繁琐,但是好消息是,每次启动应用程序时,都有一种方法可以通过将上述行添加到~/.lldbinit-Xcode来自动执行。 能够按项目而不是按用户执行此操作会很好,但是不幸的是,有一个开放的雷达坐在那里一段时间。 ~/.lldbinit-Xcode每一行都~/.lldbinit-Xcode执行,从而允许您定义别名和自定义命令。 值得检查一下Facebook已发布的功能非常强大的功能。 回顾一下:通过一个lldb命令,我们现在可以将调试器与我们的预构建框架一起使用,在文件系统中的某个位置具有源代码文件。 😎
在本教程中,我们的重点是使用依赖于其他容器的框架。 打开终端,并使用以下命令克隆启动程序项目。 git clone –branch 1.0.3 https://github.com/aliakhtar49/MyFramework.git 这是我们在上一部分中开发的框架。 如果您遵循 上一部分 ,则可以直接转到“入门”部分。 框架的职责是使用NSUrlSession打入网络调用,并将数据返回给使用者应用程序。 在上一部分中,我们看到了如何在本地和远程使用框架,而在这一部分中,我们将对框架添加一个依赖关系,而不是使用NSUrlSession,它将使用pod中附带的alamofire。 如果您不了解或不了解Podfile,Podspec和如何创建框架,强烈建议您看一下前面的部分。 😐 如图1所示,磁盘上的克隆存储库项目结构。 如果尚未创建框架存储库,则必须执行以下操作( 或参阅上一部分) 在github上创建MyFramework存储库 将项目克隆到一些空文件夹 将clone 1.0.3 MyFramework项目内容移动到空克隆存储库文件夹中 推送代码 您可以下载消费者应用程序(Consumer_Part2_Starter)。 该应用程序将使用我们创建的框架 入门 在本节中,我们将向我们的框架添加一个依赖项。 转到终端中MyFramework项目的根文件夹,如图2所示,然后运行以下命令。 这将创建一个podfile ,如图2所示。 Podfile定义项目所依赖的内容。 pod init 打开podfile并将其替换为图3中所示的代码。我们所做的是添加Alamofire作为对框架的依赖。 转到终端中MyFramework项目的根文件夹,如图2所示,然后运行以下命令。 这将安装Alamofire,并创建一个MyFramework.xcworkspace文件。 现在关闭项目并打开MyFramework.xcworkspace 。 pod install 如图4所示,我们在框架中添加了新功能。 现在,与以前的版本相比,它还有另一种方法。 此方法使用Alamofire从服务器获取数据,并且Alamofire包含在Pod中,该Pod是对此框架的依赖。 转到MyFramework项目的根文件夹,打开MyFramework.podspec文件,并用以下代码替换代码,如图5所示。我们做了几件事 Cocoapods使用此git url下载源代码并寻找标签1.0.6 当消费者使用cocoapods安装我们的框架时,cocoapods首先查看依赖关系,然后按照步骤1进行自动安装。消费者应用程序无需担心它 Pod规范描述了Pod库的版本。 它包括有关应从何处获取源,使用哪些文件,要应用的构建设置以及其他常规元数据(例如其名称,版本和说明)的详细信息。 将更改推送到您创建的存储库。 我推动了回购 推送标签以创建历史记录点。 这一步很重要。 由于我们将使用此标记在客户应用程序上安装pod,如图7所示 […]
在处理框架时,这是一个常见错误。 大多数人只是遵循stackoverflow上的解决方案(将Build Active Architecture Only仅设置为NO ,并将i386,x86_64添加到有效架构中),但实际上并不需要花费很多时间来了解其背后的原理。 armv64:iPhoneX,iPhone 5s-8,iPad Air-iPad Pro armv7:iPhone3Gs-5c,iPad WIFI(第四代) armv6:iPhone — iPhone3G 上面的如果用于真实设备 i386:32位模拟器 x86_64:64位模拟器 上面的列表是向下兼容的,这意味着iPhoneX也可以与armv6一起运行,而不能完全利用armv64的功能 有关iOS体系结构的更多信息,请参见: 设备兼容性 描述有关现有iOS设备功能的详细信息。 developer.apple.com 如果选择“是”,它将仅将框架构建到“所选设备”,即实际设备(armv)或模拟器(x86_64或i386)。 对于“否”,它将把您的框架构建到“有效架构”列表中 默认情况下,在调试模式下为“是”。 在更多版本中,它表示“否”,可以节省调试模式下的编译时间,并确保您的发布项目框架可以在您指定的所有体系结构上运行。 这就是为什么接受的答案通过强制框架针对所有体系结构进行构建而起作用的原因,但是通过阅读更多内容,您会知道背后的内容,并且可以肯定地节省编译框架的时间。 当然,您也可以更好地控制自己。 因此,如果您使用的是框架,并且要导入到另一个项目,则可以使用模拟器(i386或x86_64)通过 “ 仅构建Active Architecture ”编译该框架,然后使用 “ 仅构建Active Architecture ”将其导入项目。如果是真实设备(armv)的 “是”,您将遇到此错误。 寻找错误说明: 该文件是为x86_64构建的,不是链接的体系结构( i386 )意味着您在64位模拟器中构建框架,并使用32位模拟器构建合并的项目。 而更常见的是: 框架文件是为 x86_64 构建的, 它不是要链接的体系结构( arm64 ):这意味着您的框架是在模拟器中构建的,而合并的项目是使用实际设备构建的。 一种常见的做法是右键单击框架,然后选择“在Finder中显示” ,而大多数开发人员将Finder保持打开状态,而新编译的框架将替换旧框架,而无需关闭Finder并再次重新打开。 是的,这是正确的,但是如果您在两者之间切换构建目标设备,则框架将导致存在不同的文件夹 。 有时您认为自己已经编译了框架,但实际上它在另一个文件夹中。 […]
注意:这是上一篇文章的Xcode 10更新,但有一些补充。 Xcode Playgrounds是编写代码原型甚至练习测试驱动开发的好地方。 有时,第三方库可能会方便使用。 在本文中,我将向您展示两种在框架中使用Xcode Playgrounds的方法。 第三方框架不能简单地包含在游乐场中,甚至不能作为“来源”的一部分: 假设我们有一个要在操场上测试的框架-在下面的示例中,我选择了一个著名的库:由多产的开源和作者Marin Todorov编写的SwiftSpinner。 下载的档案包含可以直接打开的Xcode项目。 确保项目构建成功(Cmd + B) 操场 现在,让我们创建要使用的游乐场-从菜单中选择“文件”>“新建”>“游乐场”,确保它是一个iOS游乐场,然后选择“单一视图”模板。 您可以使用默认名称(MyPlayground.playground)并将其存储在框架本身中: 创建游乐场后,切换到“助手编辑器”以查看游乐场输出: 现在,使用该框架非常容易: 将其导入顶部: 让我们看看如何在操场上使用多个框架。 我们将使用相同的SwiftSpinner和Alamofile。 首先,下载两个库并将它们并排存储在文件夹中: 现在,我们将像以前一样打开SwiftSpinner Xcode项目,并围绕它创建一个工作区-从菜单中选择:File> Save as Workspace。 我将其命名为:Playground.workspace,并将其保存在两个文件夹旁边: 添加第二个框架 现在,让我们添加第二个框架—从Alamofire主项目中,将Alamofire.xcodeproj(确保您添加了项目而不是Alamofire.xcworkspace)拖放到SwiftSpinner项目旁边的工作区中。 现在,工作空间应包含来自两个框架的方案。 操场 与上一节一样,我们将创建一个游乐场-从菜单中选择“文件”>“新建”>“游乐场”,确保它是一个iOS游乐场,然后选择“单视图”模板。 确保将其添加到“游乐场”组。 一种统治所有人的方案 现在,在使用框架之前,我们必须一个一个地构建它们。 虽然对于我们而言,这并不难,但是如果使用更多的它们,或者如果您在操场上使用它们时积极开发它们,可能会很麻烦。 为此,我们将添加一个将构建所有框架的新方案。 从方案选择器中,选择“新方案…”: 确保目标是“无” —我已将其命名为“我的游乐场”: 在下一个屏幕的Build类别下,使用小+按钮添加从属目标-这是应如何配置的: 点击“关闭”。 现在,每次您建立Playground目标时,也会建立所有的依存关系。 注意:请确保您要为模拟器而不是真实设备而构建。 使用框架 现在可以像以前一样使用这些框架: 导入它们 快乐的游乐场! 🤓
Cocoapod是一个依赖管理器,其中包含数千个库。 创建通用库允许安装pod,而无需在podfile中指定存储库URL。 该博客介绍了从创建框架到公开发布pod所涉及的步骤。 创建通用Pod 1.创建框架 创建名称为“ SampleUniversalFramework”的框架。 按照以下链接创建框架。 https://medium.com/@sundareshj75/creating-a-private-ios-framework-in-swift-and-distributing-it-using-cocoapods-6ddb5cfab92f 注意 为了删除模拟器架构,请在应用程序目标的“ 构建阶段 ”中创建一个新的“ 运行脚本 阶段 ”,并将以下代码段粘贴到脚本文本字段中: bash“ $ {BUILT_PRODUCTS_DIR} / $ {FRAMEWORKS_FOLDER_PATH} /SampleUniversalFramework.framework/strip-frameworks.sh” 2.创建存储库 在gitlab中创建一个名为“ SampleUniversalFramework”的公共存储库,并添加MIT许可。 3.在桌面上创建一个空文件夹。 4.启动终端并导航到上面创建的文件夹。 cd FOLDER_NAME 5.在文件夹内克隆在步骤2中创建的存储库。 git clone [PUBLIC_REPO_URL] 6.导航到您刚刚使用cd克隆的存储库。 cd sampleuniversalframework 7.将步骤1中创建的框架粘贴到当前目录中。 8.运行以下命令,创建一个包含LICENSE和框架的zip文件夹。 zip -r SampleUniversalFramework.zip许可SampleUniversalFramework.framework 运行以上命令后,请观察文件夹结构。 9.现在是时候将“ SampelUniversalFramework.zip”推送到在步骤2中创建的存储库了。 运行以下命令 9.1。 将SampleUniversalFramework.zip添加到暂存区域中,从而准备将它们包含在下一个git commit 。 git添加SampleUniversalFramework.zip 9.2使用git commit记录对存储库的更改。 git commit […]