EcpmConfigInitExporter.m 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //
  2. // EcpmConfigInitExporter.m
  3. // UUTUtils2.1
  4. //
  5. // Created by zhuge on 2020/7/14.
  6. // Copyright © 2020 dym. All rights reserved.
  7. //
  8. #import "EcpmConfigInitExporter.h"
  9. #import "AdIdNameInCSVUtils.h"
  10. #import "ProjectInfo.h"
  11. #import "ProjectInfo_Server_AdId.h"
  12. #import "NSString+NSString_CountryCode.h"
  13. #import "ZGJsonUtils.h"
  14. #define AdNameInCSV NSString
  15. #define AdKey NSString
  16. #define AdCountry NSString
  17. @interface EcpmConfigInitExporter()
  18. @property (strong) NSDictionary<AdNameInCSV*, AdKey*> *dicAdKeys;
  19. @property (strong) NSDictionary *dicCountryCodes;
  20. @end
  21. @implementation EcpmConfigInitExporter
  22. - (NSString *) doExport:(ProjectInfo *)project admobFilePath:(NSString *)admobFilePath facebookFilePath:(NSString *)facebookFilePath {
  23. self.projectInfo = project;
  24. self.admobFilePath = admobFilePath;
  25. self.facebookFilePath = facebookFilePath;
  26. NSString *ret = @"";
  27. self.dicAdKeys = [self genAdKeyDic];
  28. // 开始读取文件
  29. NSMutableDictionary<AdCountry*, EcpmCountryInfo*> *md = [NSMutableDictionary dictionaryWithCapacity:0];
  30. {
  31. // 读取admob
  32. NSError *err = nil;
  33. NSString *content = [NSString stringWithContentsOfFile:self.admobFilePath encoding:NSUTF8StringEncoding error:&err];
  34. if (err) {
  35. NSLog(@"%@", err.localizedDescription);
  36. }
  37. NSArray *arrLines = [content componentsSeparatedByString:@"\n"];
  38. for (NSString *line in arrLines) {
  39. if (line.length == 0) {
  40. continue;
  41. }
  42. if ([line hasPrefix:@"国家/地区"]) {
  43. continue;
  44. }
  45. if ([line containsString:@"未知地区"]) {
  46. continue;
  47. }
  48. EcpmCountryAdInfo *cai = [[EcpmCountryAdInfo alloc] initWithAdmobLine:line];
  49. if (cai.ecpm < 0.0001) {
  50. // 精度太少,会被忽略掉
  51. continue;
  52. }
  53. EcpmCountryInfo *countryInfo = md[cai.country];
  54. if (!countryInfo) {
  55. countryInfo = [[EcpmCountryInfo alloc] init];
  56. countryInfo.country = cai.country;
  57. md[cai.country] = countryInfo;
  58. }
  59. [countryInfo addCountryAdInfo:cai];
  60. }
  61. }
  62. {
  63. // 读取facebook
  64. NSError *err = nil;
  65. NSString *content = [NSString stringWithContentsOfFile:self.facebookFilePath encoding:NSUTF8StringEncoding error:&err];
  66. if (err) {
  67. NSLog(@"%@", err.localizedDescription);
  68. }
  69. NSArray *arrLines = [content componentsSeparatedByString:@"\n"];
  70. for (NSString *line in arrLines) {
  71. if (line.length == 0) {
  72. continue;
  73. }
  74. if ([line hasPrefix:@"国家"]) {
  75. continue;
  76. }
  77. EcpmCountryAdInfo *cai = [[EcpmCountryAdInfo alloc] initWithFacebookLine:line];
  78. if (cai.ecpm < 0.0001) {
  79. // 精度太少,会被忽略掉
  80. continue;
  81. }
  82. EcpmCountryInfo *countryInfo = md[cai.country];
  83. if (!countryInfo) {
  84. countryInfo = [[EcpmCountryInfo alloc] init];
  85. countryInfo.country = cai.country;
  86. md[cai.country] = countryInfo;
  87. }
  88. [countryInfo addCountryAdInfo:cai];
  89. }
  90. }
  91. // 按ecpm排序国家
  92. NSMutableArray<EcpmCountryInfo*> *maCountry = [NSMutableArray arrayWithCapacity:0];
  93. for (NSString *country in md) {
  94. [maCountry addObject:md[country]];
  95. }
  96. // 排序国家
  97. [maCountry sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
  98. EcpmCountryInfo *c1 = obj1;
  99. EcpmCountryInfo *c2 = obj2;
  100. return [c1 avgEcpm] < [c2 avgEcpm];
  101. }];
  102. // 输出
  103. NSMutableDictionary<AdCountry*, NSMutableDictionary<AdKey*, NSDecimalNumber*>*> *mdOut = [NSMutableDictionary dictionaryWithCapacity:0];
  104. for (int i = 0; i < maCountry.count; i++) {
  105. EcpmCountryInfo *c = maCountry[i];
  106. NSMutableDictionary *mdCountry = [NSMutableDictionary dictionaryWithCapacity:0];
  107. for (EcpmCountryAdInfo *l in c.maCountryAdInfos) {
  108. NSString *adKey = self.dicAdKeys[l.adName];
  109. if (adKey == nil) {
  110. NSLog(@"ad key not found: %@", l.adName);
  111. continue;
  112. }
  113. NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%0.4f", l.ecpm]];
  114. mdCountry[adKey] = dn;
  115. }
  116. mdOut[c.country] = mdCountry;
  117. }
  118. NSDictionary *d = @{ @"countries": mdOut };
  119. ret = [ZGJsonUtils dictionaryToString:d];
  120. return ret;
  121. }
  122. - (NSDictionary<AdNameInCSV*, AdKey*> *) genAdKeyDic {
  123. NSMutableDictionary<AdNameInCSV*, AdKey*> *md = [NSMutableDictionary dictionaryWithCapacity:0];
  124. for (ProjectInfo_Server_AdId *adid in self.projectInfo.server.xibAdIdArray) {
  125. NSString *adKey = adid.idIndex;
  126. NSString *adName = [[AdIdNameInCSVUtils shared] adNameForAdIdIndex:adid.idIndex];
  127. if (adName != nil) {
  128. md[adName] = adKey;
  129. }
  130. }
  131. return md;
  132. }
  133. @end
  134. #pragma mark - Admob国家版本信息
  135. @implementation EcpmCountryAdInfo
  136. - (instancetype)initWithAdmobLine:(NSString *)line {
  137. NSArray *arr = [line componentsSeparatedByString:@","];
  138. NSAssert(arr.count == 3, line);
  139. self.type = ADMOB;
  140. self.country = arr[0];
  141. self.adName = arr[1];
  142. self.ecpm = [arr[2] floatValue];
  143. NSString *s = [NSString getFBCountryCode:self.country];
  144. if (!s || [s isEqualToString:@""] || [s isEqualToString:self.country]) {
  145. NSAssert(NO, @"无匹配国家: %@", s);
  146. }
  147. self.country = s;
  148. return self;
  149. }
  150. - (instancetype)initWithFacebookLine:(NSString *)line {
  151. NSArray *arr = [line componentsSeparatedByString:@","];
  152. NSAssert(arr.count == 3, line);
  153. self.type = FACEBOOK;
  154. self.country = arr[0];
  155. self.adName = arr[1];
  156. self.ecpm = [arr[2] floatValue];
  157. return self;
  158. }
  159. @end
  160. @implementation EcpmCountryInfo
  161. - (instancetype)init
  162. {
  163. self = [super init];
  164. if (self) {
  165. self.maCountryAdInfos = [NSMutableArray arrayWithCapacity:0];
  166. }
  167. return self;
  168. }
  169. - (void)addCountryAdInfo:(EcpmCountryAdInfo *)countryAdInfo {
  170. for (EcpmCountryAdInfo *cai in self.maCountryAdInfos) {
  171. NSAssert(!(cai.type == countryAdInfo.type && [cai.adName isEqualToString:countryAdInfo.adName]) , @"有问题:广告ID有重复: %@, %@", cai.adName, countryAdInfo.adName);
  172. }
  173. [self.maCountryAdInfos addObject:countryAdInfo];
  174. }
  175. - (float)avgEcpm {
  176. int len = (int)self.maCountryAdInfos.count;
  177. if (len > 0) {
  178. float total = 0;
  179. for (EcpmCountryAdInfo *cai in self.maCountryAdInfos) {
  180. total += cai.ecpm;
  181. }
  182. return total / len;
  183. }
  184. return 0;
  185. }
  186. @end