QNPipeline.m 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //
  2. // QNPipeline.m
  3. // QiniuSDK
  4. //
  5. // Created by BaiLong on 2017/7/25.
  6. // Copyright © 2017年 Qiniu. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "QNSessionManager.h"
  10. #import "QNPipeline.h"
  11. @implementation QNPipelineConfig
  12. - (instancetype)init {
  13. return [self initWithHost:@"https://pipeline.qiniu.com"];
  14. }
  15. - (instancetype)initWithHost:(NSString*)host {
  16. if (self = [super init]) {
  17. _host = host;
  18. _timeoutInterval = 10;
  19. }
  20. return self;
  21. }
  22. @end
  23. @interface QNPipeline ()
  24. @property (nonatomic) id<QNHttpDelegate> httpManager;
  25. @property (nonatomic) QNPipelineConfig* config;
  26. + (NSDateFormatter*)dateFormatter;
  27. @end
  28. static NSString* buildString(NSObject* obj) {
  29. NSString* v;
  30. if ([obj isKindOfClass:[NSNumber class]]) {
  31. NSNumber* num = (NSNumber*)obj;
  32. if (num == (void*)kCFBooleanFalse) {
  33. v = @"false";
  34. } else if (num == (void*)kCFBooleanTrue) {
  35. v = @"true";
  36. } else if (!strcmp(num.objCType, @encode(BOOL))) {
  37. if ([num intValue] == 0) {
  38. v = @"false";
  39. } else {
  40. v = @"true";
  41. }
  42. } else {
  43. v = num.stringValue;
  44. }
  45. } else if ([obj isKindOfClass:[NSString class]]) {
  46. v = (NSString*)obj;
  47. v = [v stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
  48. v = [v stringByReplacingOccurrencesOfString:@"\t" withString:@"\\t"];
  49. } else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSSet class]]) {
  50. v = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:obj options:kNilOptions error:nil] encoding:NSUTF8StringEncoding];
  51. } else if ([obj isKindOfClass:[NSDate class]]) {
  52. v = [[QNPipeline dateFormatter] stringFromDate:(NSDate*)obj];
  53. } else {
  54. v = [obj description];
  55. }
  56. return v;
  57. }
  58. static void formatPoint(NSDictionary* event, NSMutableString* buffer) {
  59. [event enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSObject* obj, BOOL* stop) {
  60. if (obj == nil || [obj isEqual:[NSNull null]]) {
  61. return;
  62. }
  63. [buffer appendString:key];
  64. [buffer appendString:@"="];
  65. [buffer appendString:buildString(obj)];
  66. [buffer appendString:@"\t"];
  67. }];
  68. NSRange range = NSMakeRange(buffer.length - 1, 1);
  69. [buffer replaceCharactersInRange:range withString:@"\n"];
  70. }
  71. static NSMutableString* formatPoints(NSArray<NSDictionary*>* events) {
  72. NSMutableString* str = [NSMutableString new];
  73. [events enumerateObjectsUsingBlock:^(NSDictionary* _Nonnull obj, NSUInteger idx, BOOL* _Nonnull stop) {
  74. formatPoint(obj, str);
  75. }];
  76. return str;
  77. }
  78. @implementation QNPipeline
  79. - (instancetype)init:(QNPipelineConfig*)config {
  80. if (self = [super init]) {
  81. if (config == nil) {
  82. config = [QNPipelineConfig new];
  83. }
  84. _config = config;
  85. #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
  86. _httpManager = [[QNSessionManager alloc] initWithProxy:nil timeout:config.timeoutInterval urlConverter:nil];
  87. #endif
  88. }
  89. return self;
  90. }
  91. - (void)pumpRepo:(NSString*)repo
  92. event:(NSDictionary*)data
  93. token:(NSString*)token
  94. handler:(QNPipelineCompletionHandler)handler {
  95. NSMutableString* str = [NSMutableString new];
  96. formatPoint(data, str);
  97. [self pumpRepo:repo string:str token:token handler:handler];
  98. }
  99. - (void)pumpRepo:(NSString*)repo
  100. events:(NSArray<NSDictionary*>*)data
  101. token:(NSString*)token
  102. handler:(QNPipelineCompletionHandler)handler {
  103. NSMutableString* str = formatPoints(data);
  104. [self pumpRepo:repo string:str token:token handler:handler];
  105. }
  106. - (NSString*)url:(NSString*)repo {
  107. return [NSString stringWithFormat:@"%@/v2/repos/%@/data", _config.host, repo];
  108. }
  109. - (void)pumpRepo:(NSString*)repo
  110. string:(NSString*)str
  111. token:(NSString*)token
  112. handler:(QNPipelineCompletionHandler)handler {
  113. NSDictionary* headers = @{ @"Authorization" : token,
  114. @"Content-Type" : @"text/plain" };
  115. [_httpManager post:[self url:repo] withData:[str dataUsingEncoding:NSUTF8StringEncoding] withParams:nil withHeaders:headers withCompleteBlock:^(QNResponseInfo* info, NSDictionary* resp) {
  116. handler(info);
  117. }
  118. withProgressBlock:nil
  119. withCancelBlock:nil
  120. withAccess:nil];
  121. }
  122. + (NSDateFormatter*)dateFormatter {
  123. static NSDateFormatter* formatter = nil;
  124. static dispatch_once_t onceToken;
  125. dispatch_once(&onceToken, ^{
  126. formatter = [NSDateFormatter new];
  127. [formatter setLocale:[NSLocale currentLocale]];
  128. [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"];
  129. [formatter setTimeZone:[NSTimeZone defaultTimeZone]];
  130. });
  131. return formatter;
  132. }
  133. @end