ChineseToPinyinResource.m 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //
  2. //
  3. //
  4. // Created by kimziv on 13-9-14.
  5. //
  6. #include "ChineseToPinyinResource.h"
  7. #define LEFT_BRACKET @"("
  8. #define RIGHT_BRACKET @")"
  9. #define COMMA @","
  10. #define kCacheKeyForUnicode2Pinyin @"cache.key.for.unicode.to.pinyin"
  11. static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
  12. return [directory stringByAppendingPathComponent:key];
  13. }
  14. @interface ChineseToPinyinResource ()
  15. - (id<NSCoding>)cachedObjectForKey:(NSString*)key;
  16. -(void)cacheObjec:(id<NSCoding>)obj forKey:(NSString *)key;
  17. @end
  18. @implementation ChineseToPinyinResource
  19. //@synthesize unicodeToHanyuPinyinTable=_unicodeToHanyuPinyinTable;
  20. //- (NSDictionary *)getUnicodeToHanyuPinyinTable {
  21. // return _unicodeToHanyuPinyinTable;
  22. //}
  23. - (id)init {
  24. if (self = [super init]) {
  25. _unicodeToHanyuPinyinTable = nil;
  26. [self initializeResource];
  27. }
  28. return self;
  29. }
  30. - (void)initializeResource {
  31. NSString* cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
  32. NSString* oldCachesDirectory = [[[cachesDirectory stringByAppendingPathComponent:[[NSProcessInfo processInfo] processName]] stringByAppendingPathComponent:@"PinYinCache"] copy];
  33. if([[NSFileManager defaultManager] fileExistsAtPath:oldCachesDirectory]) {
  34. [[NSFileManager defaultManager] removeItemAtPath:oldCachesDirectory error:NULL];
  35. }
  36. _directory = [[[cachesDirectory stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]] stringByAppendingPathComponent:@"PinYinCache"] copy];
  37. NSDictionary *dataMap=(NSDictionary *)[self cachedObjectForKey:kCacheKeyForUnicode2Pinyin];
  38. if (dataMap) {
  39. self->_unicodeToHanyuPinyinTable=dataMap;
  40. }else{
  41. NSString *resourceName =[[NSBundle mainBundle] pathForResource:@"unicode_to_hanyu_pinyin" ofType:@"txt"];
  42. NSString *dictionaryText=[NSString stringWithContentsOfFile:resourceName encoding:NSUTF8StringEncoding error:nil];
  43. NSArray *lines = [dictionaryText componentsSeparatedByString:@"\r\n"];
  44. __block NSMutableDictionary *tempMap=[[NSMutableDictionary alloc] init];
  45. @autoreleasepool {
  46. [lines enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  47. NSArray *lineComponents=[obj componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
  48. //NSLog(@"%@, %@",lineComponents[0],lineComponents[1]);
  49. [tempMap setObject:lineComponents[1] forKey:lineComponents[0]];
  50. }];
  51. }
  52. self->_unicodeToHanyuPinyinTable=tempMap;
  53. [self cacheObjec:self->_unicodeToHanyuPinyinTable forKey:kCacheKeyForUnicode2Pinyin];
  54. }
  55. }
  56. - (id<NSCoding>)cachedObjectForKey:(NSString*)key
  57. {
  58. NSData *data = [NSData dataWithContentsOfFile:cachePathForKey(_directory, key) options:0 error:NULL];
  59. if (data) {
  60. return [NSKeyedUnarchiver unarchiveObjectWithData:data];
  61. }
  62. return nil;
  63. }
  64. -(void)cacheObjec:(id<NSCoding>)obj forKey:(NSString *)key
  65. {
  66. NSData* data= [NSKeyedArchiver archivedDataWithRootObject:obj];
  67. NSString* cachePath = cachePathForKey(_directory, key);
  68. dispatch_async(dispatch_get_main_queue(), ^{
  69. [data writeToFile:cachePath atomically:YES];
  70. });
  71. }
  72. - (NSArray *)getHanyuPinyinStringArrayWithChar:(unichar)ch {
  73. NSString *pinyinRecord = [self getHanyuPinyinRecordFromCharWithChar:ch];
  74. if (nil != pinyinRecord) {
  75. NSRange rangeOfLeftBracket= [pinyinRecord rangeOfString:LEFT_BRACKET];
  76. NSRange rangeOfRightBracket= [pinyinRecord rangeOfString:RIGHT_BRACKET];
  77. NSString *stripedString = [pinyinRecord substringWithRange:NSMakeRange(rangeOfLeftBracket.location+rangeOfLeftBracket.length, rangeOfRightBracket.location-rangeOfLeftBracket.location-rangeOfLeftBracket.length)];
  78. return [stripedString componentsSeparatedByString:COMMA];
  79. }
  80. else return nil;
  81. }
  82. - (BOOL)isValidRecordWithNSString:(NSString *)record {
  83. NSString *noneStr = @"(none0)";
  84. if ((nil != record) && ![record isEqual:noneStr] && [record hasPrefix:LEFT_BRACKET] && [record hasSuffix:RIGHT_BRACKET]) {
  85. return YES;
  86. }
  87. else return NO;
  88. }
  89. - (NSString *)getHanyuPinyinRecordFromCharWithChar:(unichar)ch {
  90. int codePointOfChar = ch;
  91. NSString *codepointHexStr =[[NSString stringWithFormat:@"%x", codePointOfChar] uppercaseString];
  92. NSString *foundRecord =[self->_unicodeToHanyuPinyinTable objectForKey:codepointHexStr];
  93. return [self isValidRecordWithNSString:foundRecord] ? foundRecord : nil;
  94. }
  95. + (ChineseToPinyinResource *)getInstance {
  96. static ChineseToPinyinResource *sharedInstance=nil;
  97. static dispatch_once_t onceToken;
  98. dispatch_once(&onceToken, ^{
  99. sharedInstance=[[self alloc] init];
  100. });
  101. return sharedInstance;
  102. }
  103. @end