解决了语音上传到问题,接下来要解决下载播放问题
This commit is contained in:
254
Pods/Qiniu/QiniuSDK/Common/QNAutoZone.m
generated
Normal file
254
Pods/Qiniu/QiniuSDK/Common/QNAutoZone.m
generated
Normal file
@@ -0,0 +1,254 @@
|
||||
//
|
||||
// QNAutoZone.m
|
||||
// QiniuSDK
|
||||
//
|
||||
// Created by yangsen on 2020/4/16.
|
||||
// Copyright © 2020 Qiniu. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNDefine.h"
|
||||
#import "QNCache.h"
|
||||
#import "QNUtils.h"
|
||||
#import "QNAutoZone.h"
|
||||
#import "QNConfig.h"
|
||||
#import "QNRequestTransaction.h"
|
||||
#import "QNZoneInfo.h"
|
||||
#import "QNUpToken.h"
|
||||
#import "QNUploadOption.h"
|
||||
#import "QNConfiguration.h"
|
||||
#import "QNResponseInfo.h"
|
||||
#import "QNFixedZone.h"
|
||||
#import "QNSingleFlight.h"
|
||||
#import "QNFileRecorder.h"
|
||||
#import "QNUrlSafeBase64.h"
|
||||
#import "QNUploadRequestMetrics.h"
|
||||
|
||||
@interface QNUCQuerySingleFlightValue : NSObject
|
||||
|
||||
@property(nonatomic, strong) QNResponseInfo *responseInfo;
|
||||
@property(nonatomic, strong) NSDictionary *response;
|
||||
@property(nonatomic, strong) QNUploadRegionRequestMetrics *metrics;
|
||||
|
||||
@end
|
||||
|
||||
@implementation QNUCQuerySingleFlightValue
|
||||
@end
|
||||
|
||||
@interface QNAutoZone ()
|
||||
|
||||
@property(nonatomic, strong) NSArray *ucHosts;
|
||||
@property(nonatomic, strong) QNFixedZone *defaultZone;
|
||||
// 已经查询到的区域信息
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, QNZonesInfo *> *zonesDic;
|
||||
@property(nonatomic, strong) NSMutableArray <QNRequestTransaction *> *transactions;
|
||||
|
||||
@end
|
||||
|
||||
@implementation QNAutoZone
|
||||
|
||||
+ (QNSingleFlight *)UCQuerySingleFlight {
|
||||
static QNSingleFlight *singleFlight = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
singleFlight = [[QNSingleFlight alloc] init];
|
||||
});
|
||||
return singleFlight;
|
||||
}
|
||||
|
||||
+ (instancetype)zoneWithUcHosts:(NSArray *)ucHosts {
|
||||
QNAutoZone *zone = [[self alloc] init];
|
||||
zone.ucHosts = [ucHosts copy];
|
||||
return zone;
|
||||
}
|
||||
|
||||
+ (QNCache *)zoneShareCache {
|
||||
static QNCache *queryCache;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
QNCacheOption *option = [[QNCacheOption alloc] init];
|
||||
option.version = @"v2";
|
||||
queryCache = [QNCache cache:[QNZonesInfo class] option:option];
|
||||
});
|
||||
return queryCache;
|
||||
}
|
||||
|
||||
+ (void)clearCache {
|
||||
[[QNAutoZone zoneShareCache] clearMemoryCache];
|
||||
[[QNAutoZone zoneShareCache] clearDiskCache];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_zonesDic = [NSMutableDictionary dictionary];
|
||||
_transactions = [NSMutableArray array];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setDefaultZones:(NSArray <QNFixedZone *> *)zones {
|
||||
self.defaultZone = [QNFixedZone combineZones:zones];
|
||||
}
|
||||
|
||||
- (QNZonesInfo *)getZonesInfoWithToken:(QNUpToken *_Nullable)token {
|
||||
|
||||
if (token == nil) return nil;
|
||||
NSString *cacheKey = [self makeCacheKey:[QNConfiguration defaultConfiguration] akAndBucket:token.index];
|
||||
QNZonesInfo *zonesInfo = nil;
|
||||
@synchronized (self) {
|
||||
zonesInfo = self.zonesDic[cacheKey];
|
||||
}
|
||||
zonesInfo = [zonesInfo copy];
|
||||
return zonesInfo;
|
||||
}
|
||||
|
||||
- (void)setZonesInfo:(QNZonesInfo *)info forKey:(NSString *)key {
|
||||
if (info == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
@synchronized (self) {
|
||||
self.zonesDic[key] = info;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)preQuery:(QNUpToken *)token on:(QNPrequeryReturn)ret {
|
||||
[self query:[QNConfiguration defaultConfiguration] token:token on:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, QNZonesInfo * _Nullable zonesInfo) {
|
||||
if (!ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (responseInfo.isOK) {
|
||||
ret(0, responseInfo, metrics);
|
||||
} else {
|
||||
ret(responseInfo.statusCode, responseInfo, metrics);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)query:(QNConfiguration *)config token:(QNUpToken *)token on:(QNQueryReturn)ret {
|
||||
if (token == nil || ![token isValid]) {
|
||||
ret([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], nil, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
QNUploadRegionRequestMetrics *cacheMetrics = [QNUploadRegionRequestMetrics emptyMetrics];
|
||||
[cacheMetrics start];
|
||||
|
||||
|
||||
NSString *cacheKey = [self makeCacheKey:config akAndBucket:token.index];
|
||||
QNZonesInfo *zonesInfo = [[QNAutoZone zoneShareCache] cacheForKey:cacheKey];
|
||||
|
||||
// 临时的 zonesInfo 仅能使用一次
|
||||
if (zonesInfo != nil && zonesInfo.isValid && !zonesInfo.isTemporary) {
|
||||
[cacheMetrics end];
|
||||
[self setZonesInfo:zonesInfo forKey:cacheKey];
|
||||
ret([QNResponseInfo successResponse], cacheMetrics, zonesInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
kQNWeakSelf;
|
||||
QNSingleFlight *singleFlight = [QNAutoZone UCQuerySingleFlight];
|
||||
[singleFlight perform:token.index action:^(QNSingleFlightComplete _Nonnull complete) {
|
||||
kQNStrongSelf;
|
||||
QNRequestTransaction *transaction = [self createUploadRequestTransaction:config token:token];
|
||||
|
||||
kQNWeakSelf;
|
||||
kQNWeakObj(transaction);
|
||||
[transaction queryUploadHosts:^(QNResponseInfo *_Nullable responseInfo, QNUploadRegionRequestMetrics *_Nullable metrics, NSDictionary *_Nullable response) {
|
||||
kQNStrongSelf;
|
||||
kQNStrongObj(transaction);
|
||||
|
||||
QNUCQuerySingleFlightValue *value = [[QNUCQuerySingleFlightValue alloc] init];
|
||||
value.responseInfo = responseInfo;
|
||||
value.response = response;
|
||||
value.metrics = metrics;
|
||||
complete(value, nil);
|
||||
|
||||
[self destroyUploadRequestTransaction:transaction];
|
||||
}];
|
||||
|
||||
} complete:^(id _Nullable value, NSError *_Nullable error) {
|
||||
kQNStrongSelf;
|
||||
|
||||
QNResponseInfo *responseInfo = [(QNUCQuerySingleFlightValue *) value responseInfo];
|
||||
NSDictionary *response = [(QNUCQuerySingleFlightValue *) value response];
|
||||
QNUploadRegionRequestMetrics *metrics = [(QNUCQuerySingleFlightValue *) value metrics];
|
||||
|
||||
if (responseInfo && responseInfo.isOK) {
|
||||
QNZonesInfo *zonesInfo = [QNZonesInfo infoWithDictionary:response];
|
||||
if ([zonesInfo isValid]) {
|
||||
[self setZonesInfo:zonesInfo forKey:cacheKey];
|
||||
[[QNAutoZone zoneShareCache] cache:zonesInfo forKey:cacheKey atomically:false];
|
||||
ret(responseInfo, metrics, zonesInfo);
|
||||
} else {
|
||||
responseInfo = [QNResponseInfo errorResponseInfo:NSURLErrorCannotDecodeRawData errorDesc:[NSString stringWithFormat:@"origin response:%@", responseInfo]];
|
||||
ret(responseInfo, metrics, nil);
|
||||
}
|
||||
} else {
|
||||
if (self.defaultZone != nil) {
|
||||
// 备用只能用一次
|
||||
QNZonesInfo *info = [self.defaultZone getZonesInfoWithToken:token];
|
||||
[self setZonesInfo:info forKey:cacheKey];
|
||||
responseInfo = [QNResponseInfo successResponseWithDesc:[NSString stringWithFormat:@"origin response:%@", responseInfo]];
|
||||
ret(responseInfo, metrics, info);
|
||||
} else if (zonesInfo != nil) {
|
||||
// 缓存有,但是失效也可使用
|
||||
[self setZonesInfo:zonesInfo forKey:cacheKey];
|
||||
responseInfo = [QNResponseInfo successResponseWithDesc:[NSString stringWithFormat:@"origin response:%@", responseInfo]];
|
||||
ret(responseInfo, metrics, zonesInfo);
|
||||
} else {
|
||||
ret(responseInfo, metrics, nil);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (QNRequestTransaction *)createUploadRequestTransaction:(QNConfiguration *)config token:(QNUpToken *)token {
|
||||
if (config == nil) {
|
||||
config = [QNConfiguration defaultConfiguration];
|
||||
}
|
||||
|
||||
NSArray *hosts = nil;
|
||||
if (self.ucHosts && self.ucHosts.count > 0) {
|
||||
hosts = [self.ucHosts copy];
|
||||
} else {
|
||||
hosts = kQNPreQueryHosts;
|
||||
}
|
||||
QNRequestTransaction *transaction = [[QNRequestTransaction alloc] initWithConfig:config
|
||||
uploadOption:[QNUploadOption defaultOptions]
|
||||
hosts:hosts
|
||||
regionId:QNZoneInfoEmptyRegionId
|
||||
key:@""
|
||||
token:token];
|
||||
@synchronized (self) {
|
||||
[self.transactions addObject:transaction];
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
- (void)destroyUploadRequestTransaction:(QNRequestTransaction *)transaction {
|
||||
if (transaction) {
|
||||
@synchronized (self) {
|
||||
[self.transactions removeObject:transaction];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)makeCacheKey:(QNConfiguration *)config akAndBucket:(NSString *)akAndBucket {
|
||||
NSString *key = akAndBucket;
|
||||
if (config != nil) {
|
||||
key = [NSString stringWithFormat:@"%@:%d",key, config.accelerateUploading];
|
||||
}
|
||||
|
||||
NSString *hosts = @"";
|
||||
for (NSString *host in self.ucHosts) {
|
||||
if (!host) {
|
||||
continue;
|
||||
}
|
||||
hosts = [NSString stringWithFormat:@"%@:%@", hosts, host];
|
||||
}
|
||||
NSString *cacheKey = [NSString stringWithFormat:@"%@:%@", hosts, key];
|
||||
return [QNUrlSafeBase64 encodeString:cacheKey];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user