/
IconManager.m
121 lines (106 loc) · 3.99 KB
/
IconManager.m
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
//
// IconManager.m
// AppSales
//
// Created by Ole Zorn on 20.07.11.
// Copyright 2011 omz:software. All rights reserved.
//
#import "IconManager.h"
@interface IconManager ()
- (void)dequeueDownload;
@end
@implementation IconManager
- (id)init
{
self = [super init];
if (self) {
queue = dispatch_queue_create("app icon download", NULL);
iconCache = [NSMutableDictionary new];
downloadQueue = [NSMutableArray new];
BOOL isDir = NO;
[[NSFileManager defaultManager] fileExistsAtPath:[self iconDirectory] isDirectory:&isDir];
if (!isDir) {
[[NSFileManager defaultManager] createDirectoryAtPath:[self iconDirectory] withIntermediateDirectories:YES attributes:nil error:NULL];
}
}
return self;
}
+ (id)sharedManager
{
static id sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}
- (NSString *)iconDirectory
{
NSString *appSupportPath = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject];
NSString *iconDirectory = [appSupportPath stringByAppendingPathComponent:@"AppIcons"];
return iconDirectory;
}
- (UIImage *)iconForAppID:(NSString *)appID
{
if ([appID length] < 4) {
NSLog(@"Invalid app ID for icon download (%@)", appID);
return nil;
}
UIImage *cachedIcon = [iconCache objectForKey:appID];
if (cachedIcon) {
return cachedIcon;
}
NSString *iconPath = [[self iconDirectory] stringByAppendingPathComponent:appID];
UIImage *icon = [[[UIImage alloc] initWithContentsOfFile:iconPath] autorelease];
if (icon) {
return icon;
}
[downloadQueue addObject:appID];
[self dequeueDownload];
return [UIImage imageNamed:@"GenericApp.png"];
}
- (void)dequeueDownload
{
if ([downloadQueue count] == 0 || isDownloading) return;
NSString *nextAppID = [[[downloadQueue objectAtIndex:0] copy] autorelease];
[downloadQueue removeObjectAtIndex:0];
dispatch_async(queue, ^ {
NSString *iconURLStringPNG = [NSString stringWithFormat:@"http://images.appshopper.com/icons/%@/%@.png", [nextAppID substringToIndex:3], [nextAppID substringFromIndex:3]];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *iconData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:iconURLStringPNG]] returningResponse:&response error:&error];
if (!iconData) {
response = nil; error = nil;
NSString *iconURLStringJPG = [NSString stringWithFormat:@"http://images.appshopper.com/icons/%@/%@.jpg", [nextAppID substringToIndex:3], [nextAppID substringFromIndex:3]];
iconData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:iconURLStringJPG]] returningResponse:&response error:&error];
}
UIImage *icon = [UIImage imageWithData:iconData];
if (iconData && icon) {
dispatch_async(dispatch_get_main_queue(), ^ {
//Download was successful, write icon to file
NSString *iconPath = [[self iconDirectory] stringByAppendingPathComponent:nextAppID];
[iconData writeToFile:iconPath atomically:YES];
[iconCache setObject:icon forKey:nextAppID];
[[NSNotificationCenter defaultCenter] postNotificationName:IconManagerDownloadedIconNotification object:self userInfo:[NSDictionary dictionaryWithObject:nextAppID forKey:kIconManagerDownloadedIconNotificationAppID]];
});
} else if (response) {
dispatch_async(dispatch_get_main_queue(), ^ {
//There was a response, but the download was not successful, write the default icon, so that we won't try again and again...
NSString *defaultIconPath = [[NSBundle mainBundle] pathForResource:@"GenericApp" ofType:@"png"];
NSString *iconPath = [[self iconDirectory] stringByAppendingPathComponent:nextAppID];
[[NSFileManager defaultManager] copyItemAtPath:defaultIconPath toPath:iconPath error:NULL];
});
}
dispatch_async(dispatch_get_main_queue(), ^ {
isDownloading = NO;
[self dequeueDownload];
});
});
}
- (void)dealloc
{
dispatch_release(queue);
[iconCache release];
[super dealloc];
}
@end