ios – 设置NSDataDetector的上下文日期

前端之家收集整理的这篇文章主要介绍了ios – 设置NSDataDetector的上下文日期前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设今天是2014年1月20日.如果我使用NSDataDetector从“明天下午4点”字符串中提取日期,我将得到2014-01-21T16:00.大.

但是,假设我希望NSDataDetector假装当前日期是2014年1月14日.这样,当我解析“明天下午4点”时,我将得到2014-01-15T16:00.如果我在设备上更改系统时间,我会得到我想要的.但是,有没有办法以编程方式指定它?

谢谢.

解决方法

出于测试目的,您可以使用名为 method swizzling的技术.诀窍是用您自己的方法替换NSDate的方法之一.

如果用您自己的实现替换[NSDate date],NSDataDetector将在您指定的任何时候考虑“now”.

生产代码中的混合系统类方法存在风险.以下示例代码通过利用知道它私有地使用NSDate来忽略NSDataDetector的Encapsulation.许多潜在的缺陷之一是,如果iOS的下一次更新改变了NSDataDetector的内部结构,您的生产应用程序可能会意外停止为您的最终用户正常工作.

像这样在NSDate中添加一个类别(另外:如果要构建要在设备上运行的库,则在you may need to specify the -all_load linker flag中从libs加载类别):

  1. #include <objc/runtime.h>
  2.  
  3. @implementation NSDate(freezeDate)
  4.  
  5. static NSDate *_freezeDate;
  6.  
  7. // Freeze NSDate to a point in time.
  8. // PROBABLY NOT A GOOD IDEA FOR PRODUCTION CODE
  9. +(void)freezeToDate:(NSDate*)date
  10. {
  11. if(_freezeDate != nil) [NSDate unfreeze];
  12. _freezeDate = date;
  13. Method _original_date_method = class_getClassMethod([NSDate class],@selector(date));
  14. Method _fake_date_method = class_getClassMethod([self class],@selector(fakeDate));
  15. method_exchangeImplementations(_original_date_method,_fake_date_method);
  16. }
  17.  
  18. // Unfreeze NSDate so that now will really be now.
  19. + (void)unfreeze
  20. {
  21. if(_freezeDate == nil) return;
  22. _freezeDate = nil;
  23. Method _original_date_method = class_getClassMethod([NSDate class],_fake_date_method);
  24. }
  25.  
  26. + (NSDate *)fakeDate
  27. {
  28. return _freezeDate;
  29. }
  30.  
  31. @end

这是用它:

  1. - (void)someTestingFunction:(NSNotification *)aNotification
  2. {
  3. // Set date to be frozen at a point one week ago from now.
  4. [NSDate freezeToDate:[NSDate dateWithTimeIntervalSinceNow:(-3600*24*7)]];
  5.  
  6. NSString *userInput = @"tomorrow at 7pm";
  7. NSError *error = nil;
  8. NSRange range = NSMakeRange(0,userInput.length);
  9. NSDataDetector *dd = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeDate error:&error];
  10. [dd enumerateMatchesInString:userInput
  11. options:0
  12. range:range
  13. usingBlock:^(NSTextCheckingResult *match,NSMatchingFlags flags,BOOL *stop) {
  14. NSLog(@"From one week ago: %@",match);
  15. }];
  16.  
  17. // Return date to normal
  18. [NSDate unfreeze];
  19.  
  20. [dd enumerateMatchesInString:userInput
  21. options:0
  22. range:range
  23. usingBlock:^(NSTextCheckingResult *match,BOOL *stop) {
  24. NSLog(@"From now: %@",match);
  25. }];
  26.  
  27. }

哪个输出

  1. 2014-01-20 19:35:57.525 TestObjectiveC2[6167:303] From one week ago: {0,15}{2014-01-15 03:00:00 +0000}
  2. 2014-01-20 19:35:57.526 TestObjectiveC2[6167:303] From now: {0,15}{2014-01-22 03:00:00 +0000}

猜你在找的iOS相关文章