Tag: 移动应用开发

为iOS应用程序带来动态本地化– Vincent Pradeilles –中

可以在我的 GitHub上找到 一个演示本文内容的演示项目 。 对于用户而言,能够与使用他能理解的语言本地化的应用进行交互具有极其重要的意义。 毫无疑问,iOS在为开发人员提供很少的成本方面提供了出色的性能。 不幸的是,它仅以静态方式提供,这意味着该应用是使用设备的语言环境进行本地化的,但是一旦用户进入应用内部,SDK便无法为我们提供动态更新本地化的方法。 这样的功能仍然可以带来巨大的商业价值。 例如,让我们以一个推销员为例,该推销员使用iOS应用程序在展览会上向潜在客户展示其产品。 并非他遇到的所有人都会说相同的语言,因此能够即时切换其应用的本地化将是一个很好的帮助。 在本文中,我将向您展示如何利用Objective-C运行时的特性来实现此目标,而无需创建新的本地化API。 iOS如何处理本地化? 在iOS应用中, Localizable.strings文件被视为资源,因此使用Bundle类进行存储和访问。 为了更好地了解手头的结构,我们可以检查应用程序的内容: 我们看到,对于每个本地化,都有一个对应的.lproj目录,其中包含本地化的资源。 因此,我们实现动态本地化的策略将是找到一种方法来使应用程序在这些目录之间动态交换。 进入Objective-C运行时 从iOS 11开始,所有应用程序都使用Objective-C运行时运行,Objective-C运行时是一个托管Objective-C兼容类并允许它们按预期进行交互的环境。 对我们来说幸运的是,此运行时公开了一个API,该API允许我们的应用程序与其配合使用。 尽管需要谨慎使用,但它绝对拥有强大的力量。 让我们考虑一下这个函数: 结论 在本文中,我专注于可本地化的字符串,因为它是迄今为止在给定应用程序中最常见的一种本地化资源。 但是,我所描述的解决方案当然可以应用于任何本地化的资源,例如音频文件,视频等。

Bitrise现在支持Xcode 9的新exportOptions属性!

我们已经发布了新的Xcode Archive步骤版本(2.2.0),该版本能够自动检测新的exportOptions属性,因此不再需要两周前提供的解决方法。 👻但是,您仍然必须进行一些设置。 问题… 在Xcode 9中,引入了新的必需exportOptions属性: provisioningProfiles ,它描述了应该使用哪个配置文件来签名项目中的哪个目标。 即使Xcode 9在测试版中,我们也使用它创建了一个堆栈,以使我们的用户可以使用Xcode 9测试他们的项目。但是,即使您可以在Bitrise上使用Xcode 9,我们的Xcode存档步骤也无法自动检测到配置文件–捆绑包ID映射(这是新的exportOptions属性),因此导致多个构建失败。 …现在已整理👨 该步骤将像以前一样归档您的项目,此部分没有更改。 步骤从您的项目中生成.xcarchive文件后,它开始收集exportOptions(如果xcode版本> 6)。 从存档导出IPA文件时,您需要定义该步骤应如何导出。 有两个选项,让我们看一下相关示例: 如果设置了custom_export_options_plist_content输入,则该步骤将使用您提供的exportOptions。 故事结束🙂 如果未设置此项,并且export_method设置为auto-detect ,则该步骤将使用嵌入到.xcarchive文件中的配置文件来确定导出方法(如前所述),从现在开始,项目中的每个目标都将是使用此个人资料签名。 (第二)故事的结局。 如果您为export_method输入指定了任何其他导出方法,则此步骤将列出为签名应用程序而配置的每个已安装的配置文件,然后该步骤过滤此列表以查找与指定的导出方法匹配的配置文件。 如果该步骤仅找到1个匹配的配置文件(每个目标),则此配置文件将用于对目标进行签名。 (3.故事的结尾。) 如果多个概要文件与目标和指定的导出方法匹配,则该步骤无法决定要使用哪个概要文件,因此它将失败。 在这种情况下,您应该按照此博客文章中的说明指定custom_export_options_plist_content 。 (3.b故事结束) 编码愉快! 🚀

Apple iPhone X即将发布。 您的应用程序准备好了吗?

只要有新设备或iOS版本发布,Apple都可以为现有应用程序提供出色的兼容性,这是一个很好的途径。 缩放应用程序以适应不断变化的屏幕尺寸。 实际上,最新版本的iOS的行为就像旧版本一样,打破了旧应用可能是针对其环境的假设。 随着苹果iPhone X的发布,用户和开发人员可以期望获得完全不同的iPhone。 苹果已尽力使旧版应用程序在新设备和iOS版本上正常运行。 iPhone X在许多方面与其他设备不同。 屏幕圆角化,并且iPhone X中的硬件按钮已删除。这些更改将对应用程序产生很大影响。 但是,Apple为应用程序开发人员提供了一套工具和指南,使他们能够在iOS设备上提供出色的用户体验。 如果要使您的应用程序可以在iPhone X上阅读,则应重点关注以下功能。 这是您为实现兼容性而应进行的更改所需要了解的所有信息。 阅读本文后,您还将了解设计新应用程序时要考虑的设计准则。 更新版面 消息人士称,大多数使用标准和系统提供的UI元素的iOS应用都会自动适应新设备。 如果您的应用程序使用了自动版式和UIKT组件,那么您的应用程序可以正常运行而无需进行任何更改。 明智的做法是在每个方向,纵向和横向上练习整个应用程序,以查找布局异常。 为了帮助您进行评估,iPhone刺激器随附了Xcode。 更新应用程序的布局时,您需要遵守安全区域。 安全区域描述的是标签栏和状态栏未遮挡的视图区域。 应用开发人员应检查并更新布局以遵守安全区域。 可以使用布局边距或界面生成器来访问安全区域。 必须在情节提要的FileInspector中启用安全区域布局指南。 对于现有的应用程序,转动安全区域指南将升级连接到顶部和底部布局指南的约束。 在启用安全区域指南之后,必须测试约束条件。 屏幕尺寸和方向 iPhone X具有纵向和横向方向的不同屏幕尺寸。 倾向于对接口进行更改的下一件事是UITableView,它会边到边运行。 但是,它受到安全区域的限制,该安全区域允许化妆品填充屏幕,但将内容保留在用户可以看到的地方。 背景视图扩展到边缘,因此可能有其他选项可用于调整自定义。 这说明了为什么您应该在所有方向(尤其是左右横向)上测试屏幕。 如果现有应用的角落有任何内容或控件,则应移动它们,以免被iPhone X的圆角夹住。为了帮助手势,底部的内容或控件需要插入。 iOS 11将导航栏与导航栏统一,结果,导航栏在iPhone X上看起来很糟糕。 更新图形 来到图形方面,该设备使用3倍图像比例因子,显示宽度为375pt。 这意味着它具有4.7英寸的显示屏,与其他iPhone设备相同。 创建的内容和背景图像显示为4.7英寸,在iPhone X上可能无法很好地翻译。状态栏在iPhone X中较高,并且在运行后台任务时不会更改。 Apple为iPhone X应用程序开发人员构建了一个方便的工具,该工具显示了在新设备上无法使用的应用程序列表。 苹果公司正在让开发人员开始将其应用程序切换到64位,因此所有应用程序都可以使用。 但是,值得检查以确保在新设备上没有搞乱任何关键任务。 尺寸等级 尺寸类别会根据其尺寸自动分配给内容区域。 基本上,有两种不同的尺寸级别-常规尺寸和紧凑尺寸,它们在视图的高度和宽度方面有所不同。 视图可以具有大小级别的任何组合,例如-常规高度和常规宽度,紧凑高度和紧凑宽度,紧凑宽度和常规高度,紧凑高度和常规宽度。 iOS 11根据内容区域的大小类别进行布局调整。 […]

利用iOS 10的Today小工具

CIZO是一个很棒的应用程序。 它是由粉丝们为粉丝创建的,它为您的基于iOS的设备(包括电影,游戏,时尚,音乐会,技术等)提供了精选的“最佳内容”,从而节省了用户在互联网上搜索最新视频预告片的麻烦。 , 和更多。 我们喜欢它的内容,设计和动画。 但是CIZO存在内容交付问题。 还没有实现现有的机制(例如“推送通知”)来提醒用户新视频的到来。 因此,如果用户每天不检查CIZO,可能会错过新的预告片。 因此,我们不禁要问,是否有另一种方法可以让用户在不打开应用程序的情况下了解新内容? iOS 10提供了解决方案 在安装iOS 10之后,首先要注意的是Apple从锁定屏幕上删除了“滑动解锁”功能。 现在,如果您尝试按照习惯的方式滑动屏幕,则会看到一个锁屏,其中充满了今日小部件。 当您要查看天气,标题或公交信息时,这非常方便,因为您无需解锁手机即可看到。 只需快速滑动即可。 当我们看到iOS预览时,CIZO问题的解决方案就变得清晰了:如果我们添加一个CIZO Today小部件,该小部件可以显示和启动该小部件的视频播放,那该怎么办? 实施CIZO Today小部件 现在,让我们引导您完成在“今日”屏幕上创建和展示窗口小部件的过程。 添加目标 第一步,我们需要向CIZO应用程序本身添加一个新目标。 为此,请在Xcode中打开CIZO项目,然后选择“文件”>“新建”>“目标”。 然后选择今天扩展。 如果在添加了“今日扩展”目标之后重建了CIZO应用,则可以看到它已被列为可添加到屏幕的小部件: 如果此时我们将CIZO小部件添加到锁定屏幕,则外观如下所示: 那很容易。 我们现在需要的只是呈现内容。 决定显示什么 第一个想法是重用包含应用程序本身使用的Carousel View。 这将使用户能够以精美的动画方式在精选视频之间滚动。 但是,Apple指出,开发人员应避免将滚动视图放在“今日”窗口小部件中,因为用户难以在不无意间滚动到“今日”视图的情况下在窗口小部件中滚动。 因此,我们决定接受Apple的推荐,并决定仅在小部件中显示最后三个精选视频。 初始视图控制器 在为CIZO创建Today扩展时,Xcode创建了一个初始视图控制器(现在符合NCWidgetProviding) 。 如果在目标内打开MainInterface.storybord,则可以看到带有“ Hello World”标签的视图。 我们用包含三个图像视图的“水平堆栈视图”替换了该视图: 码 – ( void )openURL:(NSURL *)URL completionHandler:( void (^)(BOOL success))completionHandler; 在此方法的实现中,我们调用精选视频API。 如果响应与之前调用时的响应不同,则该小部件将提取有关前三个新视频的信息,并将缩略图放入图像视图中。 结果显示如下: […]

清除与客户一起使用Appstore的麻烦

经过多年的发展,我很高兴地注意到,越来越多的客户来到了移动开发者手中,他们从自己的角度认识了创建应用程序所需的基础。 尽管如此,很多时候,这个问题仍然是参数未知的难题。 对于此类情况,最好对准则进行解释。 尽管Apple提供了应用在其商店中的发布和审查指南的基本准则,但仍有一些空白需要澄清。 今天,我想解释一下如何为您的业务创建应用程序时与App Store一起使用。 如果您不喜欢阅读冗长的指南,则可以在本文的说明性演示中看到基础知识。 事先调整AppStore 我建议您在应用程序的开发过程中,甚至在您选择开发人员进行项目开发时,甚至更早开始使用AppStore。 acc的注册和所有文档的准备可能比您一开始想的要花更多的时间。 最好在早期对其进行监督。 第一步是使用您要在商店中关联应用程序的名称注册帐户。 提示是在财务信息中使用公司的确切名称,以避免以后出现付款问题。 选择帐户:开发人员与公司(普通或企业) 在此步骤中,您需要确定最适合您的帐户类型-开发人员帐户或公司帐户。 如果您的应用程序将免费,那么唯一的区别就是人们可以在您的应用程序下看到签名,即开发人员的姓名或公司的姓名。 如果您想从您的应用程序中赚钱,我建议您从一开始就创建公司的帐户。 不过,如果有需要,您始终可以为该公司注册另一个帐户,然后将您的应用程序转移到该帐户。 如果您决定使用公司帐户,则还有两个选项可供选择:常规帐户或企业帐户。 第二个让您有机会发布应用程序而无需编写设备的唯一编号(被编号)。 这意味着您可以将应用程序的测试版本安装到所有员工设备上,并在大量设备上向客户端演示。 常规公司帐户没有这种奖金,并且要求您为每台测试设备写下被审核的号码。 此外,可能的设备数量有限-一年中,每种类型的设备(iPhone,iPad,Apple TV)最多只能使用100个设备。 当然,价格会有差异。 开发人员帐户和常规公司帐户每年的费用均为99 $,而企业帐户费用较高,同期的费用为299 $。 内部购买 如前所述,如果您想为自己的应用安装获得报酬或进行内部购买,则需要注册公司帐户以提取利润。 处理DUNS号码 如果您决定使用公司帐户,则需要耐心等待。 实际上,注册过程可能需要一段时间-从一天到整个工作周。 首先,您需要为您的公司分配一个DUNS编号(这是法律上的可识别编号)。 要获得此号码,您需要转到特殊站点之一并填写有关您公司的信息。 该过程通常需要几天,费用约为190 $。 传真过去的来信 取得编号后,您可以将其放入App Store的注册表格中,然后填写另一张表格(这次来自Apple)。 奇怪的是,即使到今天,也必须通过传真将表格发送给苹果。 在我们公司中,从一开始就没有传真,因此我们使用了一个特殊的程序来模仿传真机的工作。 在填写的表格中使用正确的电话号码也很重要,因为Apple员工会打电话给您,并要求您提供英文的一些详细信息。 准备发布您的应用 帐户注册完成后,您需要准备好要发布的应用程序。 还有几件事要牢记: 选择关键字是一回事,因为它将极大地影响您的应用放置。 用户可以根据您编写的关键字在商店中找到您的应用。 为您的应用选择正确的类别 -您可以选择一个主要类别和一个其他类别(最好同时插入两个类别)。 选择应用程序的名称 -应该简单,吸引人,而不是太长且唯一。 如果您想放样并声明名称,并且担心在开发名称时该名称可能被其他人使用,则可以事先为应用创建App Store卡。 在这种情况下,即使没有在App […]

Swift的最佳图像下载,处理和缓存库

大家好! 我想介绍一下我最新的下载,处理和缓存管理器库选择。 更新:2017年12月1日。 PINRemoteImage PINRemoteImageManager使用下载和处理任务的概念来确保即使多次调用下载或处理图像,也只会发生一次 安装 使用CocoaPods将PINRemoteImageManager添加到您的项目中。 只需将以下行添加到您的Podfile中即可。 pod’PINRemoteImage’,’〜> 3.0.0-beta’ 然后运行: pod install SDWebImage 该库提供了具有缓存支持的异步图像下载器。 UI元素有类别,例如UIImageView , UIButton , MKAnnotationView 。 安装 使用CocoaPods将SDWebImage添加到您的项目。 只需将以下行添加到您的Podfile中即可。 pod ‘SDWebImage’, ‘~> 4.0’ 莫阿 Moa是使用Swift编写的图像下载库。 通过设置其moa.url属性,它允许下载图像并在图像视图中显示图像。 安装 使用CocoaPods将Moa添加到您的项目中。 只需将以下行添加到您的Podfile中即可。 pod ‘moa’, ‘~> 8.0’ 然后运行: pod install 文森特 一个小型图书馆,可以轻松下载和显示远程图像。 安装 使用CocoaPods将Vincent添加到您的项目中。 只需将以下行添加到您的Podfile中即可。 pod ‘Vincent’, ‘~> 1.5.4’ 然后运行: pod install 翠鸟 Kingfisher是一个轻量级的纯Swift库,用于从Web下载和缓存图像。 […]

克隆中型iOS应用程序-第2部分

注意:自从我开始撰写本系列文章以来,Medium已使用名为“ Stories”的新功能更新了其应用。 本系列基于以前的版本,该版本具有非常相似的UI。 更改ViewController的背景色 在处理导航栏之前,让我们更改视图的背景。 我们可以在ViewController.swift中通过更改view.backgroundColor属性来实现。 通过在Medium应用程序上使用方便的吸管工具,我们看到背景色应对应于(249,249,249)的RGB。 Swift中内置的UIColor构造函数使我们以一种不直观的方式创建颜色,但是幸运的是LBTAComponents库使用更好的构造函数扩展了UIColor类。 因此,在将库导入文件后,我们可以添加viewDidLoad方法 view.backgroundColor = UIColor(r:249,g:249,b:249) 如果您现在运行该应用程序,我们现在将具有与真实应用程序相匹配的灰白色背景! 自定义导航栏 现在该处理导航栏了。 为了提高代码的可读性和结构性,我们将使用一个名为setupNavigationBar的新方法来封装本节中的所有代码,该方法将在viewDidLoad中调用。 我们可以先处理背景色,恰好是纯白色 navigationController?.navigationBar.backgroundColor = .white 如果运行该应用程序,您会发现颜色有些不对劲。 这实际上是因为默认情况下,该条设置为半透明。 我们可以简单地改变它 navigationController?.navigationBar.isTranslucent = false 现在背景看起来正确了。 现在,我们将“中”徽标放置在中间。 我在Github存储库中包含了徽标的切口。 让titleImageView = UIImageView(image:UIImage(named:“ medium_logo”)) titleImageView.frame = CGRect(x:0,y:0,宽度:34,高度:34) titleImageView.contentMode = .scaleAspectFit navigationItem.titleView = titleImageView 我们首先使用Medium徽标(位于资产文件夹中)创建一个UIImageView。 然后,我们通过首先将封装视图的框架设置为所需的大小,然后告诉图像缩放以适合该框架(通过.contentMode属性),来设置我们希望图像的大小。 最后,我们将titleView(已居中)设置为我们的自定义视图。 现在,让我们在右上角添加搜索按钮。 我们可以使用几乎所有的精确技术,而是创建一个自定义按钮并将其设置为导航栏的rightBarButtonItem。 让searchButton = UIButton(type:.system) searchButton.setImage(UIImage(name:“ search”)?. withRenderingMode(.alwaysOriginal),用于:.normal) searchButton.frame = […]

带有iOS中故事板的MVVMC

MVVM是MVC的替代品之一。 MVX模式未解决的缺点之一是视图导航。 MVVM也没有。 因此,提到了MVVMC。 C作为协调者是将导航与视图控制器分开。 使用MVVMC时,我们发现它将无法使用情节提要。 加入协调器后,诸如绑定,具有更好的可维护性的自动布局和可见性之类的所有好处都会消失。 原因是ViewController是调用performSegue并处理prepareForSegue那个。 如果我们想将这些方法转移到协调器上,我们需要找到一种方法来处理困难。 只要可以引用viewController,协调器就可以始终处理performSegue。 通过Apple文档,我们知道运行时的prepareForSegue 在segue创建之后且perform前调用。 为了在协调器中处理prepareForSegue ,我们需要在运行时进行一些技巧。 所以提出了一个问题。 我们是否要替换所有视图控制器的prepareForSegue ? 个人我更喜欢灵活性。 我不认为在所有情况下使用相同设计模式的整个应用程序都有意义。 另外,我不希望任何人只有在了解其工作原理后才能开始编码。 最好还是调用视图控制器的prepareForSegue 。 因此,我们可以认为视图控制器或协调器的prepareForSegue将首先被调用,或者我们可以认为一个是另一个的回调。 这导致使用毛毛雨。 通过这次采访,我们知道快速的动态编程不会很快到来。 似乎没有比迅速扑朔迷离的效果更好的方法了。 如果您发现我们不使用任何方法即可实现的任何方法,请发表评论。 因此,在需要协调器帮助时,让视图控制器可以采用一个协议。 protocol Coordinated { var coordinationDelegate: CoordinationDelegate? { get set } } 然后协调员应该处理方法 protocol CoordinationDelegate { func prepareForSegue(segue: UIStoryboardSegue) } 单一协调员 对于2个简单视图,假设我们要构建一个城市列表视图和一个城市详细信息视图。 MVVMC结构可以设计如下。 城市协调员创建城市视图模型和视图控制器。 因此,城市列表视图控制器和城市协调器分别采用协议。 class MVVMCSCityListViewController: UITableViewController, […]

自动布局:朋友还是敌人?

首先是第一件事。 根据Apple的自动版面配置: 根据放置在视图上的约束,动态计算视图层次结构中所有视图的大小和位置。 例如,您可以限制按钮的位置,使其在“图像”视图中水平居中,并且按钮的顶部边缘始终保持在图像底部下方8个点。 如果图像视图的大小或位置发生更改,则按钮的位置会自动调整以匹配。 这种基于约束的设计方法使您可以构建可动态响应内部和外部更改的用户界面。 这是一个非常强大的工具,当有人完全理解它时,这几乎是魔术。 如此说来,下面列出的是我多年来发现的一些优点。 它可以帮助新开发人员 2年前,作为新开发人员,我不得不学习Swift,如何正确编写语言以及诸如扩展,闭包之类的许多其他内容。 我不想花更多的时间来编写UI,所以我了解了自动布局的工作原理。 我了解到,如果新开发人员能够很好地理解该技术,则可以节省大量开发时间。 简单的布局和适应性 当涉及到简单的布局和应用程序的适应性时,“自动布局”是一个很好的工具。 特别是对于Xcode 8,界面构建器背后的团队在改善它方面做得非常出色。 确实很棒,并且具有一些很棒的功能(接口构建器的提示和技巧将在第二部分中介绍,请继续关注) “自动布局”比编写UI更快 在iOS开发中创建用户界面的方法不是对是错。 对于许多用户而言,“自动版式”的工作原理比另一种更好且更快。 我就是其中之一。 我认为使用自动布局比通过编程设置约束要快。 先进的技术 信不信由你,Auto Layout是一项先进的技术,Apple付出了大量的努力来改进它并使其变得更好。 通过每次Xcode更新,我发现Interface Builder团队所做的更新确实执行得很好。 有用的结论 作为开发人员,在Xcode上设计UI时不要只放弃/使用一种方法。 两种方法都有其优点和缺点。 拥抱他们两个。 如果您是Auto Layout的新手,则WWDC讲座是了解其工作原理并了解一些有用的见解的良好起点。 更具体地说,当我开始尝试“自动布局”时,WWDC对我来说是如此。

ARC:Swift中的强引用和弱引用

我对撰写有关参考文献的博客的兴趣始于IBOutlets。 我一直想知道为什么IBOutlet很弱,或者这意味着什么。 弱? 我问自己,什么是弱变量? 考虑到这个问题,我继续阅读Apple的文档以了解其含义。 我几乎不知道,虚弱是一个比我想象的要复杂的话题的一部分。 我发现苹果使用自动引用计数(ARC)来管理和跟踪应用程序上的内存使用情况。 使用强,弱或无主等引用是使ARC知道何时为任何给定对象释放内存的方法。 在这篇文章中,我将重点放在强引用和弱引用上,因为无所有权将被保存以供以后的帖子使用。 让我们从强大开始 我们中的许多人甚至在没有意识到的情况下在代码中使用强引用。 实际上,每次我们声明一个类属性时,除非我们另外指定,否则它默认为强引用。 var name = String() 这是强参考周期的外观的直观表示: 本质上,强引用用于描述对象之间的关系。 当一个对象强烈引用另一个对象时,这将创建一个保留周期,以防止释放被引用的对象并将保留计数增加到1。换句话说,这些对象现在彼此保持活动状态。 在下面,我创建了两个类,一个类为Person类型,一个类型为Pet类型,它们具有强大的引用周期,以便我们可以大致了解代码中的内容。 类人{ 变量名称:字符串 var pet:宠物? 初始化(名称:字符串,宠物:宠物?){ self.name =名称 self.pet =宠物 } } 宠物类{ var所有者:个人? var pet:字串 init(所有者:人,宠物:字符串){ self.owner =所有者 self.pet =宠物 } } 在此示例中, Person通过其pet属性强烈引用了Pet , Pet通过其所有者所有权强烈引用了Person 。 此示例的问题在于,由于这些对象之间具有强引用,因此当不需要其中一个对象时,ARC无法释放内存。 从理论上讲,如果Pet在任何时候都不为零,那么Person仍然会强烈引用Pet,并且即使该类为nil,也无法释放该类的内存。 反过来,如果Person在任何时候都不为零,ARC也将无法为此对象释放任何内存。 为了防止此保留周期,我们可以创建保存弱引用的属性。 参考文献薄弱 弱引用是在声明之前使用关键字weak创建的。 弱变量名称:字符串? 与强引用不同,弱引用的保留计数为零,这是因为被引用的对象在某个点上可能保留缺失值,并且有可能被ARC释放。 […]