新普金娱乐网址


【iOS】7.4 定位服务->3.4 地图框架Map基特 功效4:地图截图

iOS Map 知道少单大头针如何去

Cloud基特 初探与教学 – 签到应用 地理

  • 十二月 18, 2018
  • 地理
  • 没有评论

日期.
一个要命一般的年华及她的兑现中数有着巨大的异样,里面隐藏的差不多地点的错综复杂远超此外数据类型。其中囊括亚秒级的精度,重叠单元,不同地理地点的时区边界,语言与语法上的本地化差别,以及为夏令时之变与闰年调整,而在业内时间中补充加删除整块的光阴等等,里面有无比多的事物要开展处理。
当起来开展其余重度日期相关的天职面前,大家发必要深刻摸底一下我们手中已经部分工具。比较写上上千单本子的
dateIsTomorrow
,我觉着重新好之主意是运用 Foundation
方法。你来于为此NSDateComponents
也?你爆发指定正确的日历单元吗?你的代码在 2100 年 2 月 28
号还会正常工作么?
但实则:我们一贯还当应用这些曾经特别熟练了之 APIs
。除非你走去寓目版本表达跟 API 变动表,不然你必不会合了然目前宣布的几乎独
OS X 版本里,NSCalendar
业已上加了同样多样效用很精锐的道去操作总括日期,如今之相同次等发布为我们得以于
iOS 中利用那多少个点子。

Cloud基特 的底子对象类型有 7
种。那一个目的类型或者与您当另外编程领域了然之好像对象类型稍有出入。

NSCalendar *calendar = [NSCalendar currentCalendar];
  • CKContainer
    Containers
    就比如以运行的沙盒一样,一个运只赏心悦目自己沙盒中之情节要休可以访问其他使用的。Containers
    就是无与伦比外层容器,每个应用来还只有暴发一个属于自己之
    container。(事实上,经过开发者授权配置 Cloud基特 Dashboard
    之后,一个采用为堪拜其他以之 container。)
  • CKDatabase
    Database
    即数据库,私有数据库用来储存敏感新闻,比如说用户之性年龄等,用户只美观自己的民用数据库。应用也发出一个当着之数据库来储存公共音信,例如你在构建一个依照地理地方签到的应用,那么地理地方信息就是该储存在公共数据库里以便所有用户都能顾到。
  • CKRecord
    尽管数据库被的同等长长的数据记录。Cloud基特(Kit) 使用 record 通过 k/v
    结构来囤积结构化数据。关于键值存储,近来值的架构支持NSString、NSNumber、NSData、NSDate、CLLocation,和
    CKReference、CKAsset(这半单脚我们会评释),以及存储以上数量类的数组。
  • CKRecordZone
    Record 不是因散之措施有让 database 之中的,它们位于 record zones
    里。每个应用都爆发一个 default record zone,你为堪来于定义之 record
    zone。
  • CKRecordIdentifier
    凡平条 record 的唯一标识,用于确定该 record 在数据库中之绝无仅有地方。
  • CKReference
    Reference 很像 RDBMS
    中之援关系。仍然为地理地方签到应用为条例,每个地理地方好蕴涵众多用户以拖欠职务的记名,那么地点和签到之间便形成了这么平等栽含式的附属关系。
  • CKAsset
    即资源文件,例如二进制文件。依旧因签到以也例,用户签到常或许还带有一张照片,那么那张相片就会师为
    asset 格局储存起来。

从今全新的日期组件存取与日期比艺术,到无敌的日子插值与枚举方法,有无比多的东西叫我们忽略了。接下来让咱抽点时间来打听一下咔嚓。

Convenience API 顾名思义是本着 Cloud基特(Kit) 操作的福利 API。利用 Convenience
API 就可对 record 举行数据的老三栽基本操作:存储、读取、更改。
这就是说,继续周密我们的报到应用吧!起头前记得应用 CloudKit框架并获公开数据库的援:

惠及之日子组件存取

哇, NSDateComponents
真是既实用又活,但当自家只是想精通间隔的时辰数时,它用起感觉又最累了。不要怪,
NSCalendar 来挽救你了!

NSInteger hour = [calendar component:NSCalendarUnitHour fromDate:[NSDate date]];

这样就好多了。NSCalendar
,你还有咋样本事?

  • getEra(_:year:month:day:fromDate:)
    :依据传入的日子引用再次回到纪元,年,月,日。不需之参数可以流传
    nil/NULL 。
  • getEra(_:yearForWeekOfYear:weekOfYear:weekday:fromDate:) :
    依照传入的日期引用再次回到纪元,年,当年第几圆满,星期几。不待之参数可以传
    nil /NULL。
  • getHour(_:minute:second:nanosecond:fromDate:) :
    依据传入的日期引用重返时音信,然后 nil /NULL 巴拉巴拉, 你精晓的。

NSDateComponents
,刚才自己是挑起你打吧,我撤前边吐槽你的说话。上边还有很多属于您的法门:

  • componentsInTimeZone(_:fromDate:) :
    按照传入的之日期及时区重回一个 NSDateComponents 实例。
  • components(_:fromDateComponents:toDateComponents:options:) :
    重回五个 NSDateComponents
    实例间的差异。若是来非赋值的零件,该法会动用默认值,所以我们传入的实例至少得装了年属性。options参数暂时没有就此,传
    nil/0 就实施。
#import <CloudKit/CloudKit.h>
// ...
CKDatabase *publicDB = [[CKContainer defaultContainer] publicCloudDatabase];

日期比

虽一贯相比较 NSDate
凡是件非凡简单的事,但有的更有意义的于可能移得惊心动魄之错综复杂。两单 NSDate
实例是当天?同一刻钟?亦或者同一周? 现在未曾必要发愁了,NSCalendar
供了大气底比艺术:

  • isDateInToday(_:) : 假诺传入的日期是当天返 true 。
  • isDateInTomorrow(_:) : 要是传入的日子是明回到 true 。
  • isDateInYesterday(_:) : 如若传入的日子是前几日返 true 。
  • isDateInWeekend(_:) : 假若传入的日期是星期一重回 true 。
  • isDate(_:inSameDayAsDate:) : 假诺个别独 NSDate 实例在当天归
    true没必要更失去取日期部件举行相比了。
  • isDate(_:equalToDate:toUnitGranularity:):
    如若传入的日子在同等指定单位内回到 true
    。这意味,两独以平周之日子实例调用calendar.isDate(tuesday,
    equalToDate: thursday, toUnitGranularity: .CalendarUnitWeekOfYear)
    艺术时会回去 true ,尽管他们不在与一个月也是这般。
  • compareDate(_:toDate:toUnitGranularity:) :
    再次回到一个NSComparisonResult
    ,当做和外指定区间内之日子等。
  • date(_:matchesComponents:) : 假若日期匹配指定的构件再次回到 true 。

下,新建一个职音信并蕴藏
因 Cloud基特(Kit) 在异步运行 saveRecord:completionHandler:
常会见使用网络与服务器交互,网络情形是未肯定的,所以 一定 记得要以 block
中处理错误,一个吓的利用该有完美之错误处理机制。
若用检查 NSError
对象来规定在处理啊种错误。例如,无网络线连接的时节会触发CKErrorNetworkUnavailable
类型的左,然后你用做的尽管是败北后重试。等等,那么一旦啊时重试呢?立即,依然十秒之后?别担心,Cloud基特(Kit)在 error 的 userInfo 字典中提供了一个提议之重试时间 CKErrorRetryAfterKey

日子插值

连着下去说话一些冲着手点寻找下一个日期的措施。你可因一个
NSDateComponents
实例,一个点名的日子组件,或者特定的当儿秒,去找到下一个(或达一个)日期。所有这多少个格局都亟待一个NSCalendarOptions
各队参数去供更为小巧的操纵,特别是同等开始大家从没会找到确切之匹配的下,它好扶助咱确定哪些选定下一个日期。
NSCalendarOptions

尽简单易行的 NSCalendarOptions 选项是 .SearchBackwards
,使用她大家可当有着方被展开反为搜索。反向搜索和正向搜索得到的结果是类似的。举个例子,反向搜索
11 在此以前的一个 钟头
会晤为你归 11:00, 而未是 11:59, 即便当倒为搜索中 11:59
严峻意义上来讲是比 11:00
“早”。确实,反向搜索咋一看是合直觉的,但想多矣怪可能会晤管您绕进去。既然
.SearchBackwards 是一度是最简便的选料项,你大概能才怀疑到背后如故几什么不良。
接下来的 NSCalendarOptions 选项可以拉我们处理这个 “消失”
的年华。举个最直观的例证来说,当你举行一个短时窗搜索时境遇夏令时调整,时间提前了一个刻钟。或者搜索时相遇类似
2 月 或者 4 月 31
号,它还是可以够协助咱越了这个缺失的时日。当碰着缺失的日子日常,尽管大家装了
NSCalendarOptions.MatchStrictly ,相关方法会依照传入的零部件寻找一个 精确
的异常。假若无装的话,那么必须提供 .MatchNext提姆e
,.MatchNext提姆(Tim)ePreservingSmallerUnits ,和
.MatchPrevious提姆(Tim)ePreservingSmallerUnits
中的管一起。那么些选用决定了哪处理我们恳请时遇到的时刻少失问题。

这种状态,往往一例胜千言:

NSDate *valentines = [calendar dateWithEra:1 year:2015 month:2 day:14 hour:9 minute:0 second:0 nanosecond:0];NSDateComponents *components = [[NSDateComponents alloc] init];components.day = 31;

以精确匹配会在一月找到下只 31
号,如下:

NSDate *date = [calendar nextDateAfterDate:valentines matchingComponents:components options:NSCalendarMatchStrictly];
// Mar 31, 2015, 12:00 AM

勿采取规范匹配的语,nextDateAfterDate
方法会在找到匹配的指定天数前就在一月之止了下,然后以产个月连续找。
可见,你所提供的精选决定了最终回的有血有肉日期。举例来说,使用.MatchNext提姆(Tim)e
选项找到下一个适度的光景:

date = [calendar nextDateAfterDate:valentines matchingComponents:components options:NSCalendarMatchNextTime];
// Mar 1, 2015, 12:00 AM

类之,当用 .MatchNext提姆ePreservingSmallerUnits
选项时会找到下一致天,不过所有比指定单元 NSCalendarUnitDay
要聊之单元会被封存下来:

date = [calendar nextDateAfterDate:valentines matchingComponents:components options:NSCalendarMatchNextTimePreservingSmallerUnits];
// Mar 1, 2015, 9:00 AM

最后, 使用 .MatchPreviousTimePreservingSmallerUnits
选项会在 另一个 方向上解决不够失的时空问题,
和前面一样,保留较小之单元,然后找到匹配的前几天:

date = [calendar nextDateAfterDate:valentines matchingComponents:components options:NSCalendarMatchPreviousTimePreservingSmallerUnits];
// Feb 28, 2015, 9:00 AM

除了这里的 NDateComponents外,还值得留意的凡
nextDateAfterDate方法来一定量栽转移:

// 匹配指定的日历单元
date = [calendar nextDateAfterDate:valentines matchingUnit:NSCalendarUnitDay value:31 options:NSCalendarMatchStrictly];
// March 31, 2015, 12:00 AM

// 匹配时,分,秒
date = [calendar nextDateAfterDate:valentines matchingHour:15 minute:30 second:0 options:NSCalendarMatchNextTime];// Feb 14, 2015, 3:30 PM
    CKRecordID *markID = [[CKRecordID alloc] initWithRecordName:@"mark"];

    CKRecord *place = [[CKRecord alloc] initWithRecordType:@"Place" recordID:markID];

    [publicDB saveRecord:place completionHandler:^(CKRecord *savedPlace, NSError *error) {

        if (!error) {

            NSLog(@"[success]\n keys: %@\n type: %@\n rName: %@", savedPlace.changedKeys, savedPlace.recordType, savedPlace.recordID.recordName);
        } else {

            NSLog(@"[error]\n info:%@", error.userInfo);

            double retryAfterValue = [error.userInfo[CKErrorRetryAfterKey] doubleValue];
            NSDate *retryAfterDate = [NSDate dateWithTimeIntervalSinceNow:retryAfterValue];

            NSLog(@"[retrydata]\n %@", retryAfterDate);
        }
    }];

枚举插值日期

NSCalendar 提供了一个API去枚举日期, 所以我们没必要反复的调用
nextDateAfterDate
方法。enumerateDatesStartingAfterDate(_:matchingComponents:options:usingBlock:)
方法依照提供的日期组件和挑选,依次拿到匹配的日子。可以用 stop 属性设为
true 去平息枚举。来试试这 NSCalendarOptions
的初措施吧,上边呈现了一样种拿到随后50单闰年的法门:

NSDateComponents *leapYearComponents = [[NSDateComponents alloc] init];
leapYearComponents.month = 2;
leapYearComponents.day = 29;

__block int dateCount = 0;
[calendar enumerateDatesStartingAfterDate:[NSDate date] matchingComponents:leapYearComponents options:NSCalendarMatchStrictly | NSCalendarSearchBackwards usingBlock:^(NSDate *date, BOOL exactMatch, BOOL *stop) { 
  NSLog(@"%@", date); 
  if (++dateCount == 50) { 
  *stop = YES;
 }}];
// 2012-02-29 05:00:00 +0000
// 2008-02-29 05:00:00 +0000
// 2004-02-29 05:00:00 +0000
// 2000-02-29 05:00:00 +0000
// ...

左情状

处理周末

假若想寻找周末吧,记住下边两独 NSCalendar 方法就是行:

  • nextWeekendStartDate(_:interval:options:afterDate) :
    按照传入的前片个参数重返下只星期六之启时只长。尽管手上底地带和日历未提供对周末性能之支撑,该方法会重临false 。唯一相关的特性是.SearchBackwards。(例子在上边。)
  • rangeOfWeekendStartDate(_:interval:containingDate) :
    依据传入的前头少单参数再次回到 包含
    该日期的礼拜。假设传入的日期并无在周末要手上底地域以及日历未提供对周末性能的帮助,该方法会返回false 。

脚,获取一个岗位音讯

本地化日期符号

似乎所有这些新功能还不够丰富似的, NSCalendar 还提供了一整套的本地化日期符号,用来快速获取月份名称,星期名称等等。每组符号都列举在两个轴上:(1) 符号的长度 (2) 它是作为标准名称还是日期的一部分。
理解这两个属性对本地化来说十分的重要,有些语言,特别是斯拉夫语言,会依据不同的内容使用不同的名词格。举例来说,一个日期要使用某个 standaloneMonthSymbols 的变体作为头,而不是使用monthSymbols 去格式化日期。 下面这张表包含了 NSCalendar 提供的所有符号,供大家阅览,请注意俄语列中独立符号的不同之处:

1

2

3

横流: 著作转载自 NShipster.cn. 签字-非商业性使用 3.0
中国地

    CKRecordID *greatID = [[CKRecordID alloc] initWithRecordName:@"GreatPlace"];

    [publicDB fetchRecordWithID:greatID completionHandler:^(CKRecord *fetchedPlace, NSError *error) {
         // handle errors here
    }];

重改一个早已是的职务音信

    CKRecordID *greatID = [[CKRecordID alloc] initWithRecordName:@"GreatPlace"];

    [publicDB fetchRecordWithID:greatID completionHandler:^(CKRecord *fetchedPlace, NSError *error) {
        if (fetchedPlace != nil) {
            NSString *name = fetchedPlace[@"name"];
            fetchedPlace[@"name"] = [name stringByAppendingString:@" Door A"];

            [publicDB saveRecord:fetchedPlace completionHandler:^(CKRecord *savedPlace, NSError *savedError) {
                //...
            }];
        } else {
            // handle errors here
        }
    }];

查询

如果自身思询问名字中含 Dylan 的

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS 'Dylan'"];
    CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Place" predicate:predicate];

    [publicDB performQuery:query
              inZoneWithID:nil
         completionHandler:^(NSArray *results, NSError *error) {
             // ...
    }];

订阅通告

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description CONTAINS 'party'"];

    CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:@"Checkin" predicate:predicate options:CKSubscriptionOptionsFiresOnRecordCreation];

    CKNotificationInfo *info = [CKNotificationInfo new];
    info.alertLocalizationKey = @"NEW_PARTY_ALERT_KEY";
    info.soundName = @"NewAlert.aiff";
    info.shouldBadge = YES;

    subscription.notificationInfo = info;

    [publicDB saveSubscription:subscription
             completionHandler:^(CKSubscription *subscription, NSError *error) {
                 //...
             }];

接过推送通知时,在 app delegate 中处理

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    CKNotification *ckNotification = [CKNotification notificationFromRemoteNotificationDictionary:userInfo];
    if (ckNotification.notificationType == CKNotificationTypeQuery) {
        CKQueryNotification *queryNotification = ckNotification;
        CKRecordID *recordID = [queryNotification recordID];
        // ...
    }
}

近日苹果允许你使用 Cloud基特(Kit) 存储 10 GB 资源,100 M 数据库存储,每日 2 GB
流量;当你的用户数量扩充的时节,这多少个免费额度也对应地充实至 1 PB 存储、10
TB 数据库存储,以及每日 200 TB 流量

WWDC 2015 中提到,CloudKit 已经 不仅 能够以 iOS 和 OS X
上以,可以在公的网站及合CloudKit
JS
,以便
iCloud 用户可以浏览器中吗可以利用相应的效应,或者是行使 CloudKit web
service

对 Cloud基特(Kit) 服务端直接开展 HTTP
请求。这意味着,现在其他运动仍然桌面平台都可行使 CloudKit 了!

CopyRight@Dylan. Copy@NSHipster

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图