Tag: iOS应用开发

Github集成-为什么SashiDo使用GitHub

我们看到您喜欢在SashiDo中设置Cloud Code 多么容易和直接 。 但是您是否知道与GitHub的集成实际上有多酷和有用? 作为开发人员,我们每天都在使用GitHub,但您可能还没有想到可以充分利用SashiDo和GitHub共同提供的各种可能性。 首先,让我解释一下SashiDo为什么选择将其服务与GitHub集成-我们相信使用MBaaS服务非常有用,但有时您需要对代码进行更多控制-这就是GitHub来提供帮助的地方🙂最好的基于Web的Git存储库托管服务,可帮助您更好地管理代码。 因此,让我们从有用的部分开始。 完成云代码的设置后,您可以访问私有存储库。 您会看到两个文件夹:“ cloud”和“ public”。 第一个文件夹保留了根文件,我们将其导入到SashiDo的云中。 如果要运行它,请不要更改名称。 另外两个文件保留了简单云代码和高级云代码的示例。 如果要在SashiDo上托管应用程序网站,则可以在“公共”文件夹中添加html,css,js文件或图像。 另外,这是放置前端文件,javascript库等的地方。 这些是SashiDo提供的主要服务的基础。 如何掌握GitHub提供的强大功能取决于您,以掌握您的代码。 如果您是Git概念的新手,请放心,使用它非常容易,尤其是在基本级别上。 但是,我们的建议是使用友好的GitHub桌面。 利用分支机构 有时,随着工作的进行,您会提出关于如何开发某些东西的不同想法,而您并不确定结果应该是什么。 事情很快就会变得一团糟,您可以轻松地了解项目的不同版本。 答案就是将SashiDo与GitHub集成。 Git概念中最酷的事情之一是,它使您有机会创建可以使用的多个分支-每个分支都是一个单独的版本。 我们的建议是至少在两个分支上工作(正式版为“ master”,在进行中为“ development”)。 如果您正在与其他人一起从事同一项目,这也可以解决您的问题-只需创建自己的分支并可以随意进行试验和提交更改,就可以放心,除非您准备好对分支进行审查,否则请不要合并。与您合作的人。 完成实验和测试后,每个分支都可以与“主”合并。 关于存储库,请保存您的SashiDo的项目-请注意“ master”分支。 当您将更改推送到“ master”分支时,SashiDo会自动将代码部署到您的应用程序正在使用的服务器上。 但是,您不需要任何其他工具即可在SashiDo上管理和部署您的云代码🙂请记住,每次推送到master分支都会触发部署。 因此,如果不确定是否要更改“主”,则只需将其推送到其他分支即可。 一段时间后,当您准备好并确定自己的代码时,只需将其与“ master”分支合并即可。 添加合作者 SashiDo与GitHub集成中最酷的事情之一就是您可以邀请协作者(您的同事或自由职业者),以便您可以安全地一起构建项目。 您的回购是私人的,因此只有您可以选择邀请对象。 您可以决定是否在同一分支上工作。 每次您或您的协作者在代码中提交更改时,您都可以决定是将其放入代码中还是忽略它们。 Git很聪明,并且万一代码版本中有可疑的东西,合并不会发生,并且系统会确切地向您显示错误所在,以便您采取措施使其正常运行。 这样,您可以始终跟踪是否有冲突更改,因此最终版本中不会出现任何混乱。 不要抛出混乱的代码-将其隐藏起来! 通常,当您在处理项目的一部分时,事情处于混乱状态,您想要切换分支以进行其他工作,而您还没有准备好提交。 推动半完成工作不是很好,但是您也不想失去已经完成的工作。 有一个非常有用的命令-git stash可以解决问题。 当您要再次继续处理代码时,它将保存您的代码。 只是一个很酷的提示-当您从其他计算机存放时要小心-重新应用工作可能会遇到问题。 如果应用程序尝试更改自修改以来的文件,则会收到合并冲突,并且必须找到一种解决方法。 有一个更简单的选项可以再次测试隐藏的更改-您可以运行git […]

在Swift中处理函数引用时避免保留周期

本文使用RxSwift来说明其观点。 如果您不熟悉该库,则可以阅读其 GitHub存储库上的简介 。 非常感谢 Hugo Saynac 的表现,使我意识到了这个问题,并提出了我将在下面描述的第二种解决方案。 与许多语言一样,Swift允许开发人员引用实例方法,并在以后使用它引用或调用此方法。 尽管语法使它很容易利用,但其底层实现可能会导致创建一些棘手的保留周期。 在本文中,我将解释这种保留周期何时产生,是什么原因造成的,最后是避免它们的难易程度。 方法参考如何工作? 让我们考虑以下类: 要了解真正的原因,我们需要深入研究方法引用的工作方式。 这是什么意思 ? 我们需要记住, printInput是一个实例方法,因此它的引用需要知道在调用该方法时self将引用哪个值。 即使像我们的示例中那样,该方法实际上并没有使用self ,这也是正确的,并且这是很有意义的,因为子类可能会很好地覆盖该方法并在其新实现中使用self 。 这就是WillNeverBeFreed.printInput为我们提供方法引用的原因,该方法的self值尚未绑定。 它采用函数的形式,该函数以self的值作为参数,并返回对实际实例方法的引用。 因此,对该方法的绑定引用存储了一个强指针,该指针将用于self 。 当我们调用.subscribe(onNext: printInput) ,我们将绑定到self的方法的引用作为参数传递给了参数,这导致了保留周期。 两种可能的解决方案 为了解决这个问题,我们基本上需要找到一种方法的参考方法,同时又不能以很强的方式捕捉self 。 进行的第一种方法是定义一个像这样的函数: 它所做的是在一个弱变量中捕获self的值,直到实际调用该方法为止,如果仍然为self分配了值,它将在该点调用它,否则它将不执行任何操作。 然后我们像这样使用它: 另一种合理的方法是将方法声明为计算属性返回的闭包: (在这种情况下,我们在闭包中不使用self,因此不会捕获它。但是,如果使用并捕获了[weak self] ,则将指示[weak self]以避免捕获强引用) 然后,使用它的语法恰好是我们要实现的语法: 一切都是权衡 上述两种解决方案都设法解决了保留周期的问题,但是每种解决方案都有其特定的缺点。 使用第一个解决方案将使语法稍微简洁一些,但是它具有使用实际方法的优势,既可以覆盖它们又可以调用其超级实现。 第二种解决方案保留了更简洁的语法,但是是以使用闭包而不是方法为代价的,这是Swift 3所付出的代价:闭包可以在子类中覆盖,但是覆盖的闭包需要在使用之间进行选择[weak self]并调用超级实现。

iOS-一个新的LAN网络扫描程序库已经诞生

它是如何开始的 2011年3月,当我为iOS开发我的第一个真实项目时,IT Buddy最初是一个IP计算器,现在被认为是真正的IT Buddy! 从第一天开始,我就考虑在IT Buddy中添加LAN扫描程序的情况,但是我的知识有限,没有任何我可以使用的开源项目。 五年后,仍然没有像样的LAN扫描程序库。 有几个可用的LAN扫描仪,但尚未投入生产。 没有适用于iOS的不错的LAN扫描程序库 很多人在StackOverflow上询问如何实现LAN扫描仪,所以我决定将所有部分放在一起(SimplePing,SimplePingHelper,LAN-Scan和MacFinder),并创建一个不错的开源库来通过iOS设备扫描网络。 。 体面的意思是: 不仅可以扫描所有子网/ 24 快速搜索而不会阻塞UI 使用默认的LAN扫描技术来ping和查询ARP表。 显示可用主机的IP和MAC地址。 根据MAC地址显示设备品牌 MMLanScan 因此,名称为MMLanScan,并且非常易于使用。 在此处下载并在您的项目中复制MMLanScan文件夹! 在您的控制器中导入MMLANScanner #import“ MMLANScanner.h” 将MMLANScannerDelegate添加到您的控制器 @interface YourViewController() 声明MMLANScanner属性 @property(nonatomic,strong)MMLANScanner * lanScanner; 开始扫描 [self.lanScanner停止]; self.lanScanner = [[MMLANScanner alloc] initWithDelegate:self]; self.connectedDevices = [[NSMutableArray alloc] init]; [self.lanScanner启动]; 实现委托方法以接收事件 -(void)lanScanDidFindNewAddressWithIP:(NSString *)ipAddress MACAddress:(NSString *)macAddress和Hostname:(NSString *)hostname; -(void)lanScanDidFinishScanning; -(void)lanScanProgressPinged:(NSInteger)pingedHosts from:(NSInteger)overallHosts; -(void)lanScanDidFailedToScan; 怎么运行的 […]

构建一个Foursquare克隆iOS应用—第6部分:状态管理

第1部分:简介和设置 第2部分:位置数据和管理依赖项 第三部分:持续集成 第4部分:流媒体位置 第5部分:网络层 第六部分:国家管理 到目前为止,我们已经为我们的应用程序创建了可靠的数据源,现在我们将致力于在数据和视图之间建立通信。 Apple官方文档提出的MVC架构对于新开发人员来说是最直观的。 这种架构足以满足简单的应用程序和小型团队的需要,但是遵循MVC的趋势是将所有代码集中到UIViewController类中,这会使您的应用程序难以理解并且容易出现错误。 首先,我想说明一下这是一个非常主观的概念,受以下因素的影响:功能的复杂性,团队规模,质量的定义和限制,组件的可重用性水平,开发人员的技术技能以及开发人员具有该架构的经验。 我个人在定义应用程序体系结构时优先考虑了3个基本原则: 组件责任:项目包含预定义的角色,避免了繁琐的类,并且添加新功能相对容易。 简便性:新开发人员第一次阅读代码时,应该能够轻松理解基本原理。 它还应该能够理解定义的模式,并在短时间内开始开发新功能或修复错误。 可测试性:顾名思义,代码应该更易于进行单元测试。 我在这里提出的解决方案不应被视为灵丹妙药,但它绝对比普通的MVC更好,而且相对容易学习。 通过选择使用ReSwift,我获得了体系结构以及数据流模式。 ReSwift的组件包括: Store:一个全局变量,代表您应用程序的当前状态。 在我们的情况下,它应该包含一个位置数组和数据获取状态(加载,完成或错误)。 视图:负责观察状态更改并基于新状态显示正确的UI。 在我们的例子中,它将是主要的UIViewController 。 行动: structs ,包含状态更改所需的有效载荷数据。 示例:一个名为SetPlacesAction的结构, SetPlacesAction包含一个公共位置数组。 Reducer:接收两个参数( Action和State )并返回新State 。 所有状态更改应集中在减速器上。 下面的代码定义了“状态”: 国家代表 这里的主要结构是FetchedPlacesState ,它必须符合StateType协议。 此结构包含一个枚举,表示应用程序的所有可能的三种状态: 加载:默认状态,表示应用程序正在等待提取所有数据。 失败:如果发生任何错误,我们使用此状态为用户显示一条人类可读的消息。 已完成:包含成功获取位置的数组 Equatable扩展仅对于单元测试是必需的。 Actions结构如下所示: 现在唯一缺少的是Reducer : 现在我们已经准备好所有代码,现在可以清楚地看到返回的State是Action和前一个State的函数。 我想在Reducer代码中指出一些细节: 具体来说,在我们的应用程序中,新状态不依赖于先前状态。 因此reduce方法仅使用action参数。 当您调用Observable方法时,它在Observable和Disposable ( subscribe方法的返回类型)之间创建了一个循环内存引用。 为了打破保留周期并避免内存泄漏,您只需要像我已经显示的那样调用disposed(by:)方法即可。 有关在此处处理袋子的更多详细信息。 您可能会注意到在此代码中闻起来不太香的是,在这种情况下, […]

从概念到设备:iOS的首次发布

我一直在iOS上进行大量的工作开发,尽管直到最近我还没有独立发表过任何东西,但自从回溯开始大约两年后,我觉得自己对平台的开发过程相当满意。大约在2014年。我认为这是一个尝试为自己发布内容的好时机,因为我有足够的自信可以管理一个体面的项目。 要启动任何应用程序,您当然需要一个主意。 就我个人而言,决定我是否真正完成一个项目的一个重要因素是我自己是否会使用它。 在大多数星期二晚上,我将在当地的斯诺克台球俱乐部与朋友见面打几场球-没有竞争,只有休闲游戏。 我以前从未真正玩过游戏,但是不久之后我就迷上了。 以前玩过的任何人都可以理解,对于初学者来说,首先要知道设置桌子时哪种颜色以及放置球体时每个球的价值有些困惑。 在这夜晚中,创建斯诺克记分牌应用程序的想法在我脑海中震撼了,我开始这么做。 潜水 从工作中获得的经验,我非常肯定自己至少可以建立一个原型并使用所需的功能来运行。 我在一张纸上计划了基本的逻辑,写下了每个班级和他们要做的事,在我的脑海中听起来像是在完全和谐地工作。 因此,我坐下来忙了起来,一天之内,我就设法制作出了一个功能原型。 您可以轻按一个球将其盆起来,然后可以看到每个球员的得分和他们的盆栽球。 突然间,我仅凭念头就想到的想法突然变成了现实。 它开始显示出希望。 我对自己说:“这正是我在谈论的那种应用程序。”我认为这是继续努力和完善并最终发布给公众的坚实基础。 程序员设计 当然,我实际上没有花任何时间思考我想要应用程序的外观,这显然是一件很愚蠢的事情。 对于下一次,我肯定会像在结构上一样多地考虑设计,但这是一个经验教训。 因此,接下来的几天花了很多时间来尝试不同的布局,并寻找该“最佳”位置-一个看上去吸引人但功能完善的位置。 “您不一定要完美,而要比竞争对手更好。” 我冒昧地去了App Store,以探索其他类似斯诺克记分牌的应用程序的集合。 我注意到的趋势是,尽管它们看起来很实用,但看起来却很不合适。 尽管我不愿透露任何名字,但一款应用看上去特别糟糕,因此脱颖而出。 仿佛“设计师”刚刚敲了几个按钮和标签,并设置了它们的字体和颜色时没有任何想法。 并不是说它们看起来都不好,但是有一对夫妇看起来特别好。 但是,视觉美学完全是主观的,虽然它可能对一个人看起来很糟糕,但另一个人可能喜欢它的外观或地狱,甚至不在乎; 只要功能在那里。 您必须在这三个之间找到快乐的中介。 最后,我想认为该应用程序的设计相当不错。 它看起来不算太高,但看起来像是精心制作的; 不只是扔到情节提要上,并称之为一天。 另外,它以一种很好的方式脱颖而出-如果正确执行应用程序的自定义设计,就可以很好地工作。 与众不同 但是,我注意到在即将发布第一个版本时的趋势是,App Store上许多现有的斯诺克记分牌应用程序实际上是在花钱。 如果您有零花钱并且不介意购买零钱,这很好,但是实际上很少是免费的-那些没花钱的东西要么是不久前发布的,没有更新,或者(个人)没有看起来很好 我收集到的普遍共识是,如果您想通过自己的应用获利,请通过应用内购买来实现。 如果用户喜欢,他们将更倾向于从您的应用中购买商品。 将其隐藏在付费墙后面只会阻止这些潜在客户。 因此,最后,我决定免费提供该应用程序。 玩桌球时,任何人都可以拿起并开始使用的东西。 小小鬼 虽然在应用程序上工作时会遇到一些打((不出所料),但值得庆幸的是,没有什么游戏破坏性的事情导致我丢下毛巾。 当我处理下一个项目时,主要要考虑的事情。 一旦创建了应用程序,便无法从iTunes Connect删除该应用程序—据推测,一旦版本1可供销售,便可以执行此操作。 我曾考虑过将名称更改为“斯诺克伴侣”,但事实证明,我需要在控制面板中创建一个全新的条目。 当然,您可以更改显示名称,但是如果您像我一样是OCD,那还不够! 手动创建您的配置文件和签名证书,不要让Xcode为您做。 在归档阶段,我遇到了几个问题,当时Xcode抱怨,我没有必要的证书来签名捆绑软件,因此最后我删除了所有证书,并在开发人员中心手动创建了它们。 Huzzah,没有其他问题了! 似乎我也不是一个人。 经常休息一下。 认真地说,如果您在休息10分钟后仍处于挣扎状态,就会感觉更好。 […]

Tentang Button和IBAction,juga Label和IBOutlet

晕semua! Yuk mari kita lanjutkan教程iOS应用程序开发教程。 Tutorial kali ini akan membahas beberapa hal yaitu: Komponen标签(sebetulnya sudah kita kenal di tutorial sebelumnya) Komponen Button Apa dan bagaimana视图控制器itu Sekelumit tentang IBAction,丹 Sekelumit tentang IBOutlet 查看布局 商业逻辑 Tentang View-Controller Membuat Button的IBAction Membuat Label的IBOutlet Ngoding业务逻辑! Buka Xcode,lalu buat项目iOS / Swift baru。 卢帕/贝鲁·塔胡·卡兰尼亚? Simak教程cara membuat iOS App应用程序Anda disini。 挑战! Cari komponen […]

Android vİOS’a SqlLite PlugininiTanıtmave React Native ileİlkSqlLite Denemeyimi

Merhaba sevgiliyazılımaşıkları, 反应本机 ile uygulamageliştirirken 数据 üzerindekiişlemlerimizi服务员aracılıylasunucularüzerindegerçekleştireceğiz。 Sadece local’deçalışanuygulamalargünümüzdeyok denecek kadar az.Uygulamalar dataişimlerinisunucuüzerindeyapıyorlar。 Bizde ileri tarihli React Nativeyazılarımızdayapacağımızörnekuygulamalarıbumantıkdageliştirmeyeçalışacağız。 Geliştirmeyeçalışacağızdiyorum。 Çünkücihazüzerindemutlaka本地数据tutmamızgerekecek。 Böylebir durumda SqlLite birseçenekolabilir。 Siz altarnetif bir插入de kullanabilirsiniz。 SqlLiteyazısınıniki anaamacıolacak。 Birincisi: react-native-sqlite-storage 插件Andorid ve Ioscihazlarıiçinçalışırhale getirmek。 Bumantığıanladığımızdadiğerpluginlerikullanırkensıkıntıyaşamayızdiyedüşünüyorum。 饮食信息: Cihazüzerinde本地数据tutmakiçinyazmamızgereken SQLkodlarınımetotlararacılıylaçağırmamızısağlamak。 不说SQL的原因是什么,请执行以下操作。 佩尔·阿科尔德·奥尔马迪·阿玛·伊勒莱恩·博尔德·达哈·阿奇尔·比尔·塞克尔德·inceleyeceğiz。 SqlLite konusunabaşlamadanönce反应本机projesioluşturmamızgerekiyor。 Bununiçinreact-native init projeismi komutunu终端üzerindençalıştırmamızgerekiyor。 响应React Native 01和 响应React Native 02yazılarımıinceleyebilirsiniz。 YadaAşağıyaeklediğimReact原生projesinin […]

快速提示:属性配置

如果您从事iOS开发已有一段时间,那么您会遇到大型的init和viewDidLoad()方法,如下所示: 类MyViewController:UIViewController { var collectionView:UICollectionView? 覆盖func viewDidLoad(){ super.viewDidLoad() 让layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizo​​ntal collectionView = UICollectionView(frame:.zero, collectionViewLayout:布局) collectionView? .translatesAutoresizingMaskIntoConstraints = false collectionView?.isPagingEnabled = true collectionView?.backgroundColor = .clear collectionView?.showsHorizo​​ntalScrollIndicator = false view.addSubview(collectionView!) //自动版式代码… } } 由于Swift能够配置闭包内联的属性,因此我们可以做得更好。 类MyViewController:UIViewController { 让collectionView:UICollectionView = { 让flowLayout = UICollectionViewFlowLayout() flowLayout.scrollDirection = .horizo​​ntal 让collectionView = UICollectionView( 帧:.zero, collectionViewLayout:flowLayout ) collectionView.translatesAutoresizingMaskIntoConstraints = […]

构建Foursquare克隆iOS应用-第3部分:持续集成

第1部分:简介和设置 第2部分:位置数据和管理依赖项 第三部分:持续集成 第4部分:流媒体位置 第5部分:网络层 第六部分:国家管理 我们将在项目中使用持续集成(CI),通过每次推送到存储库的提交自动检查应用程序的质量。 CI还可以用于自动构建应用程序并将其部署到App Store,但这不在此介绍。 您可以随时查看Github存储库以供参考。 Travis最初将负责克隆最新的存储库提交,安装其依赖项,然后将尝试构建和运行我们在上一篇文章中编写的测试。 运行CI脚本后,如果构建或测试失败,它将把您的提交/ PR标记为无效。 我选择Travis CI作为CI平台是因为我过去有一些经验。 它在开源社区中得到了很好的采用,因此它也得到了StackOverflow的良好支持。 开始使用Travis 首先,使用您的Github帐户登录TravisCI页面,并在配置文件页面中轻按开关以添加存储库。 Travis已经在听您的提交了。 然后,您需要在每次推送提交时指示Travis您想要什么。 这些说明在您需要在存储库的根文件夹中创建的.travis.yml配置文件中传递。 这是我们项目最初的文件外观: 上面的状态表示我们的应用程序已成功编译,但是使用TravisCI可以实现更多目标。 在下一步中,我们将使用TravisCI的另一个免费工具来显示我们应用程序测试的代码覆盖率。 Codecov是用于集中存储库的代码覆盖历史记录的工具。 在运行上一篇文章中描述的测试之后,将Travis配置为将代码覆盖率报告上载到Codecov。 要启用此功能,首先您需要配置Xcode项目以生成coverage数据,以便稍后上传:选择方案并点击“ Edit Scheme …”,选择“ Test”并启用“ Gather coverage data”。 要在您的存储库中启用Codecov,请首先使用您的Github帐户注册,然后在此处添加您的存储库。 完成此操作后,您就可以通过配置travis.yml开始上传覆盖率数据: 危险是另一个在代码检查期间强制执行约定的CI工具。 在这个项目中,我们将使用默认配置以及SwiftLint验证。 要使其正常工作,您基本上需要: 在项目的根目录中添加.swiftlint.yml文件,以排除外部依赖项。 在此文件中,您还可以添加自定义棉绒规则: 将个人令牌添加到存储库的TravisCI设置页面上的DANGER_GITHUB_API_TOKEN环境变量中: 指示TravisCI使用bundle exec danger运行Danger: 在CI工具上设置存储库肯定需要花费一些时间,但是,如果您的项目具有一定的复杂性,那是值得的,因为它可以节省代码检查时间并避免错误。 在项目开始时,您可能还需要为每个应用程序执行一次操作。 通过自动执行本文中描述的无聊的重复任务,您还将改善开发人员的体验。 下一部分:流媒体位置

优化HTTP实时流(HLS)以获得最佳用户体验1

苹果每年都会更改并扩展其框架。 为了更好地理解和利用框架功能,以下是用于优化HTTP Live Streaming(HLS)的演示文稿和注释。 HTTP实时流(HLS)用于向全球受众流式传输实时和点播内容。 您可以发现如何调整和调整流创作和传递元素,以通过会话502改善用户体验。 会话链接 在会议上,他们讨论了以下内容: 建立通用的流QoS语言 客观衡量流式QoS 识别并解决损害QoS的问题 有关HLS回放会话的基本知识,请参见下图。 首先,您需要先找到问题再解决。 为了发现问题,您需要测量定义的一些指标。 什么是HLS用户体验的KPI? 这是会议中讨论的一些KPI。 5个用于HLS性能的KPI 启动时间:每个会话的启动时间 失速计数:失速速率(标准化为已观察的持续时间—计数/小时) 失速持续时间:失速持续时间与观察的持续时间之比 指示比特率:时间加权指示比特率 错误:播放失败百分比 启动时间 这是启动媒体播放的每个阶段。 失速计数,失速持续时间,指示的比特率 您可以使用AVPlayerItemAccessLog来衡量KPI 播放失败百分比 定义KPI后的下一步,提高性能! 减少启动时间 调查摊位 调查错误 使用AVAsset减少启动时间 您可以通过减少启动时间 在用户决定播放之前创建并检查AVAset 预取解密密钥(采用AVContentKeySession) 减少启动时间-AVPlayer和AVPlayerItem 您可以通过减少启动时间 在缓冲之前设置AVPlayItem 在设置播放器项目之前设置AVPlayer速率 减少启动时间-AVPlayerItem过渡 您可以通过减少启动时间 使用AVQueuePlayer播放多个项目 预先排队第二个AVPlayerItem 在本文中,我讨论了会话(502)“测量和优化HLS性能”的部分内容 这是本文的摘要 设置KPI以获得更好的HLS UX 找到衡量KPI指标的方法 减少启动时间(通过更改avasset,avplayer的配置-avplayeritem,avplayeritem转换) 在下一篇文章中,我们将看一下如何调查HLS播放中的停顿和错误