Tag: iOS App开发

使用SNS,Lambda和Node.js创建推送通知作业

页面出现时,单击“创建平台应用程序”: 接下来,您需要为您的应用程序创建一个名称,为您的Push通知平台选择Apple生产或Apple开发,然后从您已经创建的证书中上传信息(请参阅先决条件)。 在查找器中选择您的证书,如果使用一个证书将其导出,请输入密码,然后单击“从文件加载凭据”。 您的证书和私钥应该自动填充。 单击创建平台应用程序。 创建应用程序后,记下应用程序ARN(Amazon资源名称)。 我们将在步骤3中使用它。 2.创建SNS主题: 导航到左侧导航菜单中的主题,单击创建新主题。 填写主题名称和显示名称。 就我而言,我只想创建一个推送通知,该通知将发送给整个用户群,因此我创建了一个名为all_app_users的主题。 创建主题后,请记下ARN。 我们将在步骤3中使用它。 3.配置程序访问 在我们的node.js代码中,我们将需要配置一个具有适当权限的用户aws-sdk,以创建SNS终结点并订阅我们的all_app_users主题。 返回AWS控制台,导航至IAM,然后单击Users。 创建一个新用户,选择一个名称,然后选中“访问类型”的“编程访问”,然后单击“下一步”:权限: 在权限屏幕上,单击附加现有策略,然后单击创建策略: 在弹出的IAM屏幕上,选择“策略生成器”。 然后在Edit Permissions中,选择适用于AWS Service的Amazon SNS,在Actions字段下检查CreatePlatformEndpoint,然后从步骤1插入应用程序ARN: 单击“添加语句”,然后重复上述步骤以创建允许该用户创建all_app_users主题的订阅的all_app_users 。 再次为AWS服务选择Amazon SNS,为“操作”选择“订阅”,然后从步骤2插入SNS主题ARN。单击下一步,将策略名称更改为sns-programmatic-access,然后单击创建策略。 返回创建用户的窗口,搜索sns-programmatic-access(您可能需要单击刷新按钮),然后单击其旁边的复选框以将其选中。 单击“下一步:查看”,然后单击按钮以完成创建用户。 在下一个屏幕上,将显示您的访问密钥ID和秘密访问密钥。 现在记下这些凭据,因为您将无法再次访问密钥*。 我们会将这些凭证插入到我们的node.js代码中,以配置我们的AWS客户端。 *如果您最终丢失了密钥,则可以通过IAM管理控制台创建新密钥。 4.向平台注册用户: 这部分取决于您当前如何处理设备令牌的注册。 在本例中,我们当前正在将设备令牌发送到服务器,以将它们存储在数据库中。 为了实现SNS,我们将需要在包含该设备令牌的SNS应用程序上创建一个平台终结点,然后将该设备预订到我们的all_app_users主题。 为此,我们将需要aws-sdk npm模块: npm install -save aws-sdk 在我们的代码中,让我们使用在上一步中创建的凭证来配置我们的AWS客户端: 在“配置触发器”屏幕上,单击“下一步”。 我们将在确认该功能正常工作后再设置触发器。 在“配置功能”屏幕上,我们需要在all_app_users主题上设置具有SNS:Publish权限的角色。 向下滚动到Lambda函数处理程序和角色部分。 在角色下,选择创建自定义角色: 在打开的IAM窗口中,将“角色名称”更改为所需的名称(我使用notificationsRole)。 然后单击允许。 现在,您的Lambda角色应设置为刚创建的角色。 最后,单击下一步,然后完成创建函数。 现在,我们只需要使用策略生成器添加SNS:Publish权限。 导航到IAM管理控制台,在左侧导航菜单中单击“角色”,然后选择我们刚刚创建的角色(如果使用该名称,则为“ […]

TableView顶部的iOS视差视图

本篇文章将按步骤详细说明,如何在iOS TableView中实作Parallax的其中一个视觉效果,Demo Project使用XCode 8,Swift 3 ,适合读者为: 了解ScrollView的ContentOffset属性以及委托设计Patten。 熟悉ImageView的ContentMode属性。 对AutoLayout有基本了解。 下图为想要实现的效果,上方的ImageView会跟着拖动的动作产生相对应的变化。 步骤1:从 Dropbox 下载启动项目 。 (按此下载) 下载后,打开ParallaxDemo.xcodeproj ,里面已经有一个写好的TableView,在每一个单元格里面显示每一个各自的行号。 步骤2:透过TableView的ContentInset属性,将TableView往下移,腾出上方的空间,给后续要置入的ImageView使用。 在DemoTableViewController里添加一个imageViewLength属性: 类DemoTableViewController:UIViewController,UITableViewDelegate,UITableViewDataSource { // 1 让imageViewHeight:CGFloat = 200.0 … } 在DemoTableViewController里面的setUpTableView()函数中加入以下代码: func setUpTableView(){ // 2 tableView.contentInset = UIEdgeInsets(顶部:imageViewHeight,左侧:0,底部:0,右侧:0) // 3 tableView.contentOffset = CGPoint(x:0,y:-imageViewHeight) … } 以下说明每一段程式码的作用: 设定要留给ImageView的高度,将之存在ImageViewHeight属性中,以供后续使用。 设定TableView的ContentInset,这个属性的资料类型状态是UIEdgeInsets,透过分别设定上,左,下,右,可以调整TableView的内容视图与底下ScrollView的相对距离。这里我们把ImageViewHeight作为UIEdgeInset初始值设定项的top参数,并将这个新生成的UIEdgeInset物件指定给TableView的ContentInset属性。 设置好ContentInset后,为了让一进来App的时候,显示上方的空白,我们还必须设置TableView的ContentOffset,让上方的空白可以被看见。 设定完这些指令之后,跑模拟器就可以看到下方的画面: 步骤3:添加ImageView 在DemoTableViewController里添加setUpImageView函数: 接下来就进到更重要的部分,UIScrollView有相对应的协议:UIScrollViewProtocol,会在发生一些事件的时候通知委派对象,执行相对应的方法,而UITableViewDelegate协议继承自UIScrollViewDelegate,自然也继承了这些方法。我们将会用到scrollViewDidScroll()这个功能。 将下列的程式码新增到DemoTableViewController中: 3. changeImageViewHeightConstraint(contentOffset:CGPoint) 当TableView已经被滑到最上层的画面,还继续被拖动的时候,我们希望imageView变大,来替换空白,所以我们去修改的imageViewHeightConstraint,让imageView随着拖动的动作高度变大,而因为contentMode设置为ScaleAspectFill的关系,imageView显示的内容就会有所改变,达到我们想要的效果。 […]

如何在App Store上获得推荐

自从Phil Schiller负责商店以来,我们已经看到商店和iTunes Connect都在逐步改进。 每天都会更新“最佳新应用程序”,审核时间缩短到一天,搜索算法更好,而且彭博社报道说,有一个由100人组成的秘密团队致力于商店的改善。 令人兴奋的时代。 对我来说,成为特色是一个目标。 该目标可以分解为一组目标。 潜在的目标是:支持CloudKit,iOS 10或使用Apple Music API的流音乐。 我想从被推荐中获得的主要好处是:Apple来自苹果公司,对我的同伴的吹牛,品牌知名度以及与苹果公司的良好关系。 理想情况下,更好的关系将导致及早使用新功能,并邀请其参加技术讲座或实验室。 如何获得特色? 最好的信息来源是苹果。 他们有一篇关于功能类型的文章,也有一篇关于充分利用App Store的文章。 iOS 7讲座的第4节和第12节与App Store的发行和营销有关,电视讲座的第11节也是如此。 “精选应用程序都有一个共同点-它们为用户提供独特的价值。 我们在所有类别中寻找高质量的应用程序,尤其关注新应用程序和具有重大更新的应用程序。” 如果您使用所有这些信息,您将了解到没有设置挑选应用程序的要求,但是有一致的准则指出: 您的应用程序必须很棒,说起来容易做起来难。 用户体验应一流,并遵守iOS HIG。 实施高质量的本地化。 构建通用应用程序(如果您拥有tvOS应用程序,则可以通用购买)。 使其对初次使用的用户而言非常出色。 性能很重要:他们检查崩溃,加载缓慢和冻结。 撰写引人注目的产品页面:视频,屏幕截图,好名字和质量说明。 推广您的应用。 使用正确的商业模式:免费或付费的免费增值。 拥有良好的App Store Optimisation(ASO):应用名称,关键字和类别。 他们专注于新应用和具有重大更新的应用 他们喜欢季节性的内容:万圣节,农历新年,香肠折腾…… “没有付费的刊登位置或需求清单–我们的编辑根据各种因素做出决定,所有这些因素都构成用户会喜欢的优质产品。” 这就是苹果告诉我们的,但是他们没有告诉我们什么? 苹果出售硬件,这是他们目前的主要业务。 他们在软件方面也持观望态度。 可以说,他们正在寻找能够炫耀其硬件并炫耀其操作系统新功能的应用程序,这并不是一个很大的飞跃。 如果您帮助他们做到这一点,那么您被选的可能性就会增加。 当他们展示新的更新时,他们已经在主题演讲和指南中选择了合作伙伴应用程序。 该商店还具有特殊类别,以突出显示具有新功能或硬件的应用程序。 一切就绪后,您就可以制作出令人赞叹的产品了,下一步就是联系apple 。 他们提供了两种方法:通过电子邮件或表单。 电子邮件地址为AppStorePromotion@apple.com和AppoftheWeek@apple.com,第二个地址是免费提供付费应用程序。 该表格可以在其开发人员网站上找到。 如果您不希望与他们联系,您可以随时用手指指望,希望他们有机地吸收您的意见。 但是,如果您愿意与他们联系,他们会提供他们想要的信息列表: 你的名字。 您的电子邮件地址。 […]

魔术计数器精简版

在此处从应用程序商店下载Magic Counter Lite。 我多年来一直在玩魔术。 由于《海岸奇才》不断添加新功能,因此该游戏保持了新的激情。 我记得看到我的第一张魔术卡,那是我最喜欢的颜色的利维坦。 生物Leviathan-在MTG金鱼网站上找到的图像。 海洋生物的图像和蓝色边框的漩涡使我着迷。 然后,我了解了该卡的功能,并迷上了艺术品和游戏玩法。 从我十几岁起我就一直是艺术家和桌面游戏玩家。 尽管我玩过无数游戏,而且享受的乐趣无穷,但在魔术师看来,在我身边或亲近的人中,没有人比我更喜欢。 在《魔术》中,辉煌的艺术作品充满了受到智力挑战的机会。 此外,由于Magic已经存在了很长时间,因此大约有2万张卡片在浮动。 如果您知道其他更复杂的纸牌游戏,那么我想听听。 快进几年,大学毕业后,以及职业过渡期间。 我决定更新我的专业技能。 我踏上了学习编程的旅程。 我尝试了一些免费的在线课程,但并没有真正获得很大的动力。 即使我获得了平面设计专业的本科学位,但在进行Web开发时,我似乎还是很挣扎。 人们不断告诉我,对于很多人来说,学习编程非常困难,尤其是在早期阶段。 他们不断告诉我要坚持下去,我需要克服第一个主要的学习过程。 直到我找到iOS和Xcode时,它才点击缺少的内容。 视觉元素。 Xcode提供了一种可视化布局资产以及编写使它们具有交互性的代码的方法。 我仍然还是一个初学者,但实际上我终于开始取得进步,并享受这个过程。 这是Xcode环境中的Magic Counter Lite应用程序的一个片段,完整的代码可以在Github上找到。 如您所见,在一个窗格中有视觉元素,在第二个窗格中有一些使各种功能栩栩如生的代码。 默认颜色从20寿命开始。 由于简单和易用是目标,因此我选择了简约的设计美学。 我选择了一种利用可读性的现代字体。 我使+/-按钮易于在很大的点击区域上轻按,同时保持了视觉上的适度。 我对计分板感到非常兴奋。 如果说实话,那是因为我很高兴看到七场最佳比赛中我赢了多少场比赛。 我从法术力符号中选择了微妙的颜色,因为它们在眼睛上柔和并向游戏致敬。 对于那些想对自己的甲板更加保密的人,我将它们包括在内。 我最喜欢的功能是添加了滑动手势。 轻按一下即可轻松更改生命计数器 加或减按钮。 上下滑动或左右滑动,可以增加或减少五到十岁的生命。 当您的生命低于1岁时,生命计数器会变成红色 。 当您的总寿命小于1时,字体变为红色。 有时我会在多个游戏中扮演同一个对手,因此渴望拥有一个得分板。 您可以通过点击胜利按钮, 将一个数字添加到您的胜利计数中。 轻触失败按钮可将计数减少1,如果更改对手,则可以轻按“重置”以将计数恢复为零 。 现在可以下载Magic Counter Lite。 我热切地等待着我从魔术社区获得的重振,并将其视为成长的机会。 如果您有兴趣签出,请在App Store上以Magic […]

将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,执行后台任务时的取消和状态管理。 […]

从底部到UITableView布局的有趣解决方案

这里,我们设计了一个表格视图,该表格视图从下至上添加了单元格。 在研究StackOverflow https://stackoverflow.com/questions/28105905/how-to-populate-uitableview-from-the-bottom-upwards之后 我发现主要有两种解决方案: 1- 翻转UITableView翻转单元格 ,然后反转UITableView中每个单元格的顺序。 问题: ScrollViewIndicator向左旋转。 滑动删除操作将引起混乱。 2 —计算所有单元格,部分标题和部分页脚的总高度 ,然后设置UIEdgeInsetTop 将其向下推 。 问题: 该解决方案很复杂,很难与Autolayout / UITableViewAutomaticDimension一起使用。 我提出了解决这些问题的解决方案: 如您所知,使用自动布局设置多个UILabel可以根据字体大小,字符数等自动调整内容大小。 相同的解决方案可以应用于这种情况: 首先,使用它来根据内容大小计算内部布局: 类IntrinsicTableView:UITableView { 覆盖var contentSize:CGSize { didSet { self.invalidateIntrinsicContentSize() } } 覆盖var internalContentSize:CGSize { self.layoutIfNeeded() 返回CGSize(width:UIViewNoIntrinsicMetric,height:contentSize.height) } } 设置UITableView左右左右的布局 设置顶部布局> = 0,以便视图可以从顶部浮动到底部而不会溢出父视图 tableView.snp.makeConstraints {(m)在 m.left.bottom.right.equalToSuperview() m.top.greaterThanOrEqualToSuperview() } 结果: 底部的UITableView布局。 通过设置基本TableView或仅处理几行代码,即可轻松应用于任何地方。 使用此解决方案,无需计算页眉,页脚,单元格的高度,并且同时使TableViewCell上的Swipe正常运行。

为什么没有注释的代码浪费我的时间

在编程中,关于注释的使用一直在进行讨论。 一位出色的Swift博主兼书籍作者Erica Sadun过去写了很多有关评论的文章。 最近,安德鲁·沃纳(Andrew Warner)写了一篇文章,说用代码编写注释通常已过时,甚至对您的代码库有害。 评论衰减。 它们不会被编译,并且永远不会在运行时执行。 如果它们过时或不正确,则不会有测试失败,也不会有用户抱怨。 程序员绕着它们工作是因为担心“有人可能需要此注释,或者它将来可能会提供一些价值”,从而使它们在有用之后就走了很远(如果您甚至可以说它们一开始就有用)。 埃里卡(Erica)对这篇文章做出了很好的回应,强调了注释在代码库中的重要性。 注释不仅仅涉及不良的设计和编码。 他们记录了正确编写代码的过程,支持将来的阅读和修改。 好的评论减少了读者每次查看您的资源时所需的精力,使他们可以将更多的精力放在特定的任务上,例如“我如何添加此功能”,而不是“到底发生了什么”。 我完全同意Erica,并且我想强调一种特殊的方式,其中注释可以帮助您的代码读者。 注释不仅针对错误的代码 过去,我主要与比我聪明得多的高级开发人员一起工作,并且在代码中几乎没有注释。 我们在iOS方面经验丰富,通常不会在同一文件上工作。 因此,我们不会经常遇到代码可读性问题。 但是,在我们最近的项目中,我们招募了新员工,一个精明的Java开发人员仍在学习Swift和iOS。 这是我第一次发现我们的代码有时不可读。 在进行配对编程并看到他遍历我们的代码库时,我可以看到他很难辨别Swift或iOS的组成部分以及什么是我们的代码。 看起来他似乎可以很容易地理解一种方法及其作用,但是很难看到所有部分如何组合在一起。 对于UIViewController中更复杂的代码,尤其如此。 由于UI代码的性质,动画,生命周期方法,样式和表示之类的不同部分都混合在一起并且相互依赖。 在这里,我注意到我们的格言“注释仅针对错误的代码”散开了。 不管代码有多好,阅读代码都很困难。 弄清楚所有这些不同部分如何组合在一起并非易事。 作为开发人员,使阅读代码更容易是我们的工作。 提供背景 在写文章时,我总是特别注意要写的简介。 其目的是为读者建立上下文和动机,以使其了解文章中的查找内容。 如果您阅读的文章没有前几段,那么您将不得不花前几分钟来试图辨别本文的目的。 它是教程吗? 是新闻文章吗? 是广告吗? 在前几段中,您将注意力集中在尝试分析文章本身而不是实际内容上 。 您也没有必要的上下文来理解本文要说的内容。 一篇文章不仅仅是其段落的总和。 这些段落的流动方式和适合的方式建立了共同的线索,并达到了您想要实现的目的。 代码也一样。 一个类不仅仅是其公共方法的总和。 每个类都有责任(一个要点),并与周围的代码(上下文)相适应。 尽我们所能尝试,使用类总是会影响我们编写它们的方式。 没有方法与呼叫站点完全隔离。 每个类都有适合的上下文。 在读取代码时,如果没有类的上下文,则必须仔细阅读几次,以弄清其中的依赖关系以及它们如何组合在一起。 就像没有介绍的文章一样,这会浪费读者的时间,并且在其他开发人员(或将来的您)尝试更改某些内容时会导致错误。 这就是为什么我绝对建议在每个类(或复杂方法)上使用一个大的注释块,以实质上描述该代码的用途。 每段文字都需要一个简介,为什么一个班级会有什么不同? 永远记住,代码的读取远不止于编写。 针对读者而非作家进行优化。

我的副项目如何在2天内获得1000位用户,以及我学到的知识

尽管我在一家初创公司从事移动开发人员的全职工作,但我在空闲期间从未停止过自己制作应用程序。 在构建了许多辅助项目(iOS和Android应用程序)之后,大多数项目并没有得到解决。 甚至那些确实发布的用户也只有十个用户。 但是最近的一个项目7Web起飞并吸引了很多人。 这是奇怪的部分。 耗时不到30小时。 它教会了我很多东西,这就是我学到的东西。 这就是我们大多数人的生活想法。 不一定是这样。 保持简单 您是否有一个雄心勃勃的想法,它具有巨大的潜力并且使您相信会产生重大影响? 嗯,在这种情况下,它比副项目更大,您必须对此更加热情,您需要组建团队并努力确保项目进展顺利。 但这不是附带项目。 它必须很简单。 我在以前的项目中犯了这个错误,这些项目规模巨大,我一个人呆了一年多。 这些项目现在回到架子上,收集灰尘。 尽管我在此过程中确实学到了很多东西,但它让我感到不满意,而且这肯定不好玩。 解决个人的小问题 一旦将标准设置得足够低,为您的副项目找到一个想法可能比您想的要容易。 这个想法的目的是解决问题。 问题可能是如此之小,以至于您甚至不敢称其为问题。 您可能是全世界唯一一个遇到此“问题”的人,但这并不重要。 找到这样的“问题”,您的项目就是解决方案。 即使您是百万分之一,也有7,000个像您一样。 就我而言,我在手机上阅读技术新闻时遇到了问题。 我每天阅读大约5到6个网站(例如“ TechInAsia”,“ TechCrunch”,“ The Verge”等),但发现打开电话(iPhone的Safari)上的许多标签确实非常困难。 “ 7Web”是我想出的解决方案。 一个简单的应用程序,以可滑动的方式放置我所有喜欢的网站,并一次性加载它们。 学习新技能 找到想法后,下一步就是实施。 如果您是一名程序员,那么应该很幸运,可以通过编写一堆代码来轻松解决问题。 没有多少人拥有此特权,并且不会将您的技能视为理所当然。 此外,此类项目对于您来说是学习新技能的绝好机会。 它可能是您想学习的新技术(也许看到了关于区块链的炒作),也可能是一种新的语言,但是您必须走出自己的舒适区来构建这个项目。 如果您不学习任何新知识,那么它就达不到目的。 作为iOS开发人员,我一直想抛弃“ Storyboard”,并使用代码(Swift)编写完整的UI。 我还想学习我在项目中所做的反应式编程(RxSwift)。 这是一次很棒的学习经历,我也可以在日常工作中重用这些技能。 使事情井井有条 这可能是我从该项目中学到的最重要的一课。 组织和计划您的项目绝对重要。 仅仅因为这是您的项目,并不意味着它必须快速而混乱。 从积极的一面看,您是您自己的项目经理。 使用Asana和Trello之类的工具来跟踪项目并确保遵守截止日期 。 即使您编写的代码也必须组织得井井有条,并且您应该有足够的信心将其开源(即使您选择不开源),也要记住这不是hackathon项目。 分享你的想法 尽管您的想法可能完全是愚蠢的,但不要回避与他人共享它。 一方面,它可以帮助您获得一些反馈。尽管目标是学习和娱乐,但获得一些反馈并没有什么坏处。 […]

不论电话语言如何,如何在iOS应用程序内部进行本地化

最近,当我们与我的团队为一个iOS应用程序开发项目的完成感到高兴时,一封电子邮件入侵了我的屏幕。 我们从刚刚完成项目的同一客户那里收到了新要求。 邮件中写道:“我希望我们的应用程序应从应用程序内部更改其语言,而与电话语言无关”。 你们遇到过这个问题吗? 好吧,你可能有! 因此,我想到写这个博客来分享我如何解决此问题的经验。 在这篇文章中,我想介绍以下几点: 什么是应用程序本地化? 本地化如何在iOS中工作? 为什么应该优先考虑iOS应用本地化? 如何在iOS应用中进行本地化? 为什么本地化很重要? 什么是应用程序本地化? 根据W3C(万维网的主要国际标准),应用程序本地化是指对您的应用程序进行调整,以满足目标市场( 语言环境 )的语言,文化和其他要求。 本地化通常写为l10n ,其中10是l和n之间的字母数。 本地化如何在iOS中工作? 启动iOS应用程序后,操作系统会努力将您喜欢的设备语言与应用程序支持的语言进行匹配或整理。 您的应用使用默认语言。 例如,英语和法语是您的应用程序支持的语言,在这种情况下,用户将英语设置为应用程序的默认语言。 因此,现在当用户的电话语言设置为法语时,您的应用将显示法语内容。 但是,当用户将电话语言更改为意大利语时,您的应用将加载默认的应用语言,在这种情况下为英语。 这是因为您的应用仅支持英语和法语,而没有意大利语本地化。 因此,在这种情况下,当电话语言设置为法语以外的其他任何语言时,您的应用将始终显示英语内容。 为什么要优先考虑iOS应用本地化? 多年来,iPhone在全球范围内的销售取得了巨大的增长。 让数字说明一切,请参见下图(由Statista提供)。 在上图中,您可以看到苹果iPhone从2007年第三季度到最近一个财务季度的全球销售情况。 苹果在2017财年售出2.176亿部iPhone ,2018年第二季度售出5222万部iPhone 。 尽管全球智能手机市场竞争激烈,但苹果的收入从2004年的80亿美元增长到2017年的超过2,290亿美元 。 归功于几乎所有国家/地区的iPhone成功。 现在,您可以期望您的下一个客户来自印度,中国,墨西哥,泰国或其他任何地方! 因此,正确制定iOS应用本地化策略可能会转化为更多应用下载。 如何在iOS应用中进行本地化? 当涉及到根据手机更改语言时,通常我们会获取手机语言代码并相应地加载“ lproj”文件。 但是在这种情况下,它必须是动态的,因此我创建了“ String”的扩展名。 看下面的代码: extensionString { publicvar localized:字符串{ ifletbundleName:String = UserDefaults.standard.value(forKey:“ USER_LANG”)如? 串 { let […]

Ruby数值类型:是和不是

在大多数编程语言中,我们拥有各种数字类型。 Ruby为我们提供了5种不同的选择: 固定编号 比格纳姆 合理的 浮动 大十进制 为什么? 作为世界上的所有事物,我们通常根据其特征将数字分为不同的集合。 最常见的-可能是您在开发软件时接触的所有对象-以下是: 自然数 , 整数 , 有理数和无理数 。 整数 自然数是指以1开头并保持加1的自然数。因此,1、2、3、4、5,…。 整数是相同的数字,但也包括相反方向的相同求和,即0,-1,-2,-3,-4,…。 Ruby对此集合有一个表示形式:抽象类Integer。 它的具体兄弟是Fixnum和Bignum。 > 10.class => Fixnum 当您将Integer文字(看起来像Integer的东西)提供给解释器时,该语言将尝试将其适合Fixnum实例。 但是有时候这不可能发生。 我们有内存限制,因为Ruby不允许Fixnum大于本地机器字[1](这在处理器之间会有所不同)。 >整数= 2 **(1.size * 8-2)-1 => 4611686018427387903 > integer.class => Fixnum >整数=(整数+ 1).class => Bignum >(-整数-2).class => Bignum 处理大于四百亿个基数的数字不是日常工作,因此使用Fixnum应该没问题。 如果将变量的值更改为超出支持范围(大于或小于)的数字,Ruby将负责释放用于保存该值的内存并将其存储在其他位置。 最后一个将被视为无限分配,因此您可以将其用于基本上可以得出的任何整数。 [1]:Ruby核心团队已经在努力定义一种更简单的方法来获取适合Fixnum对象的最大和最小数量。 看一看: https : //bugs.ruby-lang.org/issues/7517 做和不做 […]