-
Notifications
You must be signed in to change notification settings - Fork 6
/
iOSAppAssetsDownloader.obj-c.c.txt
168 lines (141 loc) · 4.77 KB
/
iOSAppAssetsDownloader.obj-c.c.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright 2004-present Facebook. All Rights Reserved.
#import <Foundation/Foundation.h>
#import <FBProvider/FBClassProvidable.h>
typedef void (^succesBlock)(NSString *urlString);
typedef void (^failureBlock)(NSString *urlString, NSString *errorMessage);
@interface FBWebRTCAssetDownloader : NSObject<FBClassProvidable>
- (instancetype)init;
- (void)downloadFileIfNotExistsAsync:(NSString *)urlString
withSuccess:(succesBlock)successBlock
orFailure:(failureBlock)failureBlock;
- (NSString *)urlToFilePath:(NSString *)urlString;
- (BOOL)fileExistsForUrl:(NSString *)urlString;
- (BOOL)removeFileForUrl:(NSString *)urlString;
@end
////////////////////////////////////////////////////////////////////////
// Copyright 2004-present Facebook. All Rights Reserved.
#import "FBWebRTCAssetDownloader.h"
#import <FBProvider/FBProviderMapData.h>
static NSString *FBWebRTCAssetPathForFileName(NSString *fileName)
{
NSString *relativePath = [@"/FBMessenger.bundle/" stringByAppendingString:fileName];
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *pathToBundle = mainBundle.resourcePath;
return [pathToBundle stringByAppendingString:relativePath];
}
static NSString *FBWebRTCUrlToHash(NSString *urlString)
{
int h = 0;
int len = (int)urlString.length;
for (int i = 0; i < len; i++) {
h = (31 * h) + [urlString characterAtIndex:i];
}
NSString *outString = [[NSString alloc] initWithFormat:@"%d", h];
return outString;
}
@interface FBWebRTCAssetDownloader () {
NSString *_errorMessage;
dispatch_queue_t _queue;
}
@end
@implementation FBWebRTCAssetDownloader
- (instancetype)init
{
if (self = [super init]) {
_queue = dispatch_queue_create("com.facebook.messenger.FBWebRTCAssetDownloaderQueue",
DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (instancetype)initWithProviderMapData:(FBProviderMapData *)mapData
{
return [self init];
}
- (void)downloadFileIfNotExistsAsync:(NSString *)urlString
withSuccess:(succesBlock)successBlock
orFailure:(failureBlock)failureBlock
{
dispatch_async(_queue, ^(void) {
[self _downloadFileIfNotExists:urlString
withSuccess:successBlock
orFailure:failureBlock];
});
}
- (NSString *)urlToFilePath:(NSString *)urlString
{
NSString *hash = FBWebRTCUrlToHash(urlString);
NSString *name = [@"fb_voicemail_asset_" stringByAppendingString:hash];
NSString *path = FBWebRTCAssetPathForFileName(name);
return path;
}
- (BOOL)fileExistsForUrl:(NSString *)urlString
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [self urlToFilePath:urlString];
return [fileManager fileExistsAtPath:path];
}
- (BOOL)removeFileForUrl:(NSString *)urlString
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [self urlToFilePath:urlString];
return [fileManager removeItemAtPath:path error:NULL];
}
# pragma mark - private
- (void)_downloadFileIfNotExists:(NSString *)urlString
withSuccess:(succesBlock)successBlock
orFailure:(failureBlock)failureBlock
{
BOOL exists = [self fileExistsForUrl:urlString];
if (exists) {
successBlock(urlString);
} else {
[self _downloadAndCacheForUrl:urlString
withSuccess:successBlock
orFailure:failureBlock];
}
}
- (void)_downloadAndCacheForUrl:(NSString *)urlString
withSuccess:(succesBlock)successBlock
orFailure:(failureBlock)failureBlock
{
// downloading...
NSData *data = [self _downloadFileForUrl:urlString];
if (data) {
// downloaded, caching...
if ([self _cacheData:data forUrl:urlString]) {
successBlock(urlString);
} else {
// caching failed
failureBlock(urlString, @"error writing to disk");
}
} else {
// download failed
failureBlock(urlString, _errorMessage);
}
}
- (NSData *)_downloadFileForUrl:(NSString *)urlString
{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:NULL
error:&error];
if (error == nil) {
return data;
} else {
_errorMessage = [error localizedDescription];
return nil;
}
}
- (BOOL)_cacheData:(NSData *)data forUrl:(NSString *)urlString
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [self urlToFilePath:urlString];
BOOL fileExists = [fileManager fileExistsAtPath:path];
if (!fileExists) {
return [data writeToFile:path atomically:YES];
} else {
return NO;
}
}
@end