Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Mac Sample / AppDelegate.m @ be116d22

History | View | Annotate | Download (16.5 kB)

1
//
2
//  AppDelegate.m
3
//
4
//  Created by Ben Copsey on 09/07/2008.
5
//  Copyright 2008 All-Seeing Interactive Ltd. All rights reserved.
6
//
7

    
8
#import "AppDelegate.h"
9
#import "ASIHTTPRequest.h"
10
#import "ASIFormDataRequest.h"
11
#import "ASINetworkQueue.h"
12
#import "ASIDownloadCache.h"
13
#import "ASIWebPageRequest.h"
14

    
15
@interface AppDelegate ()
16
- (void)updateBandwidthUsageIndicator;
17
- (void)URLFetchWithProgressComplete:(ASIHTTPRequest *)request;
18
- (void)URLFetchWithProgressFailed:(ASIHTTPRequest *)request;
19
- (void)imageFetch1Complete:(ASIHTTPRequest *)request;
20
- (void)imageFetch2Complete:(ASIHTTPRequest *)request;
21
- (void)imageFetch3Complete:(ASIHTTPRequest *)request;
22
- (void)topSecretFetchComplete:(ASIHTTPRequest *)request;
23
- (void)authSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
24
- (void)postFinished:(ASIHTTPRequest *)request;
25
- (void)postFailed:(ASIHTTPRequest *)request;
26
- (void)fetchURL:(NSURL *)url;
27
- (void)tableViewDataFetchFinished:(ASIHTTPRequest *)request;
28
- (void)rowImageDownloadFinished:(ASIHTTPRequest *)request;
29
- (void)webPageFetchFailed:(ASIHTTPRequest *)request;
30
- (void)webPageFetchSucceeded:(ASIHTTPRequest *)request;
31
@end
32

    
33
@implementation AppDelegate
34

    
35

    
36
- (id)init
37
{
38
	[super init];
39
	networkQueue = [[ASINetworkQueue alloc] init];
40
	[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateBandwidthUsageIndicator) userInfo:nil repeats:YES];
41
	return self;
42
}
43

    
44
- (void)dealloc
45
{
46
	[networkQueue release];
47
	[super dealloc];
48
}
49

    
50

    
51
- (IBAction)simpleURLFetch:(id)sender
52
{
53
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]] autorelease];
54
	
55
	//Customise our user agent, for no real reason
56
	[request addRequestHeader:@"User-Agent" value:@"ASIHTTPRequest"];
57
	[request setDelegate:self];
58
	[request startSynchronous];
59
	if ([request error]) {
60
		[htmlSource setString:[[request error] localizedDescription]];
61
	} else if ([request responseString]) {
62
		[htmlSource setString:[request responseString]];
63
	}
64
}
65

    
66

    
67

    
68
- (IBAction)URLFetchWithProgress:(id)sender
69
{
70
	[startButton setTitle:@"Stop"];
71
	[startButton setAction:@selector(stopURLFetchWithProgress:)];
72
	
73
	NSString *tempFile = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"The Great American Novel.txt.download"];
74
	if ([[NSFileManager defaultManager] fileExistsAtPath:tempFile]) {
75
		[[NSFileManager defaultManager] removeItemAtPath:tempFile error:nil];
76
	}
77
	
78
	[self resumeURLFetchWithProgress:self];
79
}
80

    
81

    
82
- (IBAction)stopURLFetchWithProgress:(id)sender
83
{
84
	[startButton setTitle:@"Start"];
85
	[startButton setAction:@selector(URLFetchWithProgress:)];
86
	[[self bigFetchRequest] cancel];
87
	[self setBigFetchRequest:nil];
88
	[resumeButton setEnabled:YES];
89
}
90

    
91
- (IBAction)resumeURLFetchWithProgress:(id)sender
92
{
93
	[fileLocation setStringValue:@"(Request running)"];
94
	[resumeButton setEnabled:NO];
95
	[startButton setTitle:@"Stop"];
96
	[startButton setAction:@selector(stopURLFetchWithProgress:)];
97
	
98
	// Stop any other requests
99
	[networkQueue reset];
100
	
101
	[self setBigFetchRequest:[ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_resume"]]];
102
	[[self bigFetchRequest] setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"The Great American Novel.txt"]];
103
	[[self bigFetchRequest] setTemporaryFileDownloadPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"The Great American Novel.txt.download"]];
104
	[[self bigFetchRequest] setAllowResumeForFileDownloads:YES];
105
	[[self bigFetchRequest] setDelegate:self];
106
	[[self bigFetchRequest] setDidFinishSelector:@selector(URLFetchWithProgressComplete:)];
107
	[[self bigFetchRequest] setDidFailSelector:@selector(URLFetchWithProgressFailed:)];
108
	[[self bigFetchRequest] setDownloadProgressDelegate:progressIndicator];
109
	[[self bigFetchRequest] startAsynchronous];
110
}
111

    
112
- (void)URLFetchWithProgressComplete:(ASIHTTPRequest *)request
113
{
114
	[fileLocation setStringValue:[NSString stringWithFormat:@"File downloaded to %@",[request downloadDestinationPath]]];
115
	[startButton setTitle:@"Start"];
116
	[startButton setAction:@selector(URLFetchWithProgress:)];
117
}
118

    
119
- (void)URLFetchWithProgressFailed:(ASIHTTPRequest *)request
120
{
121
	if ([[request error] domain] == NetworkRequestErrorDomain && [[request error] code] == ASIRequestCancelledErrorType) {
122
		[fileLocation setStringValue:@"(Request paused)"];
123
	} else {
124
		[fileLocation setStringValue:[NSString stringWithFormat:@"An error occurred: %@",[[request error] localizedDescription]]];
125
		[startButton setTitle:@"Start"];
126
		[startButton setAction:@selector(URLFetchWithProgress:)];
127
	}
128
}
129

    
130
- (IBAction)fetchThreeImages:(id)sender
131
{
132
	[imageView1 setImage:nil];
133
	[imageView2 setImage:nil];
134
	[imageView3 setImage:nil];
135
	
136
	[networkQueue reset];
137
	[networkQueue setDownloadProgressDelegate:progressIndicator];
138
	[networkQueue setDelegate:self];
139
	[networkQueue setShowAccurateProgress:([showAccurateProgress state] == NSOnState)];
140
	
141
	ASIHTTPRequest *request;
142
	
143
	request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/images/small-image.jpg"]] autorelease];
144
	[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"1.png"]];
145
	[request setDownloadProgressDelegate:imageProgress1];
146
	[request setDidFinishSelector:@selector(imageFetch1Complete:)];
147
	[request setDelegate:self];
148
	[networkQueue addOperation:request];
149
	
150
	request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/images/medium-image.jpg"]] autorelease];
151
	[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"2.png"]];
152
	[request setDownloadProgressDelegate:imageProgress2];
153
	[request setDidFinishSelector:@selector(imageFetch2Complete:)];
154
	[request setDelegate:self];
155
	[networkQueue addOperation:request];
156
	
157
	request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/images/large-image.jpg"]] autorelease];
158
	[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"3.png"]];
159
	[request setDownloadProgressDelegate:imageProgress3];
160
	[request setDidFinishSelector:@selector(imageFetch3Complete:)];
161
	[request setDelegate:self];
162
	[networkQueue addOperation:request];
163
	
164
	
165
	[networkQueue go];
166
}
167

    
168
- (void)updateBandwidthUsageIndicator
169
{
170
	[bandwidthUsed setStringValue:[NSString stringWithFormat:@"%luKB / second",[ASIHTTPRequest averageBandwidthUsedPerSecond]/1024]];
171
}
172

    
173
- (IBAction)throttleBandwidth:(id)sender
174
{
175
	if ([(NSButton *)sender state] == NSOnState) {
176
		[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
177
	} else {
178
		[ASIHTTPRequest setMaxBandwidthPerSecond:0];
179
	}
180
}
181

    
182

    
183
- (void)imageFetch1Complete:(ASIHTTPRequest *)request
184
{
185
	NSImage *img = [[[NSImage alloc] initWithContentsOfFile:[request downloadDestinationPath]] autorelease];
186
	if (img) {
187
		[imageView1 setImage:img];
188
	}
189
}
190

    
191
- (void)imageFetch2Complete:(ASIHTTPRequest *)request
192
{
193
	NSImage *img = [[[NSImage alloc] initWithContentsOfFile:[request downloadDestinationPath]] autorelease];
194
	if (img) {
195
		[imageView2 setImage:img];
196
	}
197
}
198

    
199

    
200
- (void)imageFetch3Complete:(ASIHTTPRequest *)request
201
{
202
	NSImage *img = [[[NSImage alloc] initWithContentsOfFile:[request downloadDestinationPath]] autorelease];
203
	if (img) {
204
		[imageView3 setImage:img];
205
	}
206
}
207

    
208

    
209
- (IBAction)fetchTopSecretInformation:(id)sender
210
{
211
	[networkQueue reset];
212
	
213
	[progressIndicator setDoubleValue:0];
214
	
215
	ASIHTTPRequest *request;
216
	request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/top_secret/"]] autorelease];
217
	[request setDidFinishSelector:@selector(topSecretFetchComplete:)];
218
	[request setDelegate:self];
219
	[request setUseKeychainPersistence:[keychainCheckbox state]];
220
	[request startAsynchronous];
221

    
222
}
223

    
224
- (void)topSecretFetchComplete:(ASIHTTPRequest *)request
225
{
226
	if (![request error]) {
227
		[topSecretInfo setStringValue:[request responseString]];
228
		[topSecretInfo setFont:[NSFont boldSystemFontOfSize:13]];
229
	}
230
}
231

    
232
- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request
233
{
234
	[realm setStringValue:[request authenticationRealm]];
235
	[host setStringValue:[[request url] host]];
236

    
237
	[NSApp beginSheet: loginWindow
238
		modalForWindow: window
239
		modalDelegate: self
240
		didEndSelector: @selector(authSheetDidEnd:returnCode:contextInfo:)
241
		contextInfo: request];
242
}
243

    
244
- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request
245
{
246
	[realm setStringValue:[request proxyAuthenticationRealm]];
247
	[host setStringValue:[request proxyHost]];
248
	
249
	[NSApp beginSheet: loginWindow
250
	   modalForWindow: window
251
		modalDelegate: self
252
	   didEndSelector: @selector(authSheetDidEnd:returnCode:contextInfo:)
253
		  contextInfo: request];
254
}
255

    
256

    
257
- (IBAction)dismissAuthSheet:(id)sender {
258
    [[NSApplication sharedApplication] endSheet: loginWindow returnCode: [(NSControl*)sender tag]];
259
}
260

    
261
- (void)authSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
262
{
263
	ASIHTTPRequest *request = (ASIHTTPRequest *)contextInfo;
264
    if (returnCode == NSOKButton) {
265
		if ([request authenticationNeeded] == ASIProxyAuthenticationNeeded) {
266
			[request setProxyUsername:[[[username stringValue] copy] autorelease]];
267
			[request setProxyPassword:[[[password stringValue] copy] autorelease]];			
268
		} else {
269
			[request setUsername:[[[username stringValue] copy] autorelease]];
270
			[request setPassword:[[[password stringValue] copy] autorelease]];
271
		}
272
		[request retryUsingSuppliedCredentials];
273
    } else {
274
		[request cancelAuthentication];
275
	}
276
    [loginWindow orderOut: self];
277
}
278

    
279
- (IBAction)postWithProgress:(id)sender
280
{	
281
	//Create a 1MB file
282
	NSMutableData *data = [NSMutableData dataWithLength:1024*1024];
283
	NSString *path = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"bigfile"];
284
	[data writeToFile:path atomically:NO];
285
	
286
	
287
	[networkQueue reset];
288
	[networkQueue setShowAccurateProgress:YES];
289
	[networkQueue setUploadProgressDelegate:progressIndicator];
290
	[networkQueue setRequestDidFailSelector:@selector(postFailed:)];
291
	[networkQueue setRequestDidFinishSelector:@selector(postFinished:)];
292
	[networkQueue setDelegate:self];
293
	
294
	ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]] autorelease];
295
	[request setPostValue:@"test" forKey:@"value1"];
296
	[request setPostValue:@"test" forKey:@"value2"];
297
	[request setPostValue:@"test" forKey:@"value3"];
298
	[request setFile:path forKey:@"file"];
299
	
300

    
301
	[networkQueue addOperation:request];
302
	[networkQueue go];
303
}
304

    
305
- (void)postFinished:(ASIHTTPRequest *)request
306
{
307
	[postStatus setStringValue:@"Post Finished"];
308
}
309
- (void)postFailed:(ASIHTTPRequest *)request
310
{
311
	[postStatus setStringValue:[NSString stringWithFormat:@"Post Failed: %@",[[request error] localizedDescription]]];
312
}
313

    
314

    
315
- (IBAction)reloadTableData:(id)sender
316
{
317
	[[self tableQueue] cancelAllOperations];
318
	[self setRowData:[NSMutableArray array]];
319
	[tableView reloadData];
320

    
321
	[self setTableQueue:[ASINetworkQueue queue]];
322
	
323
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/table-row-data.xml"]];
324
	[request setDownloadCache:[ASIDownloadCache sharedCache]];
325
	[request setDidFinishSelector:@selector(tableViewDataFetchFinished:)];
326
	[request setDelegate:self];
327
	[[self tableQueue] addOperation:request];
328
	[[self tableQueue] setDownloadProgressDelegate:progressIndicator];
329
	[[self tableQueue] go];
330
}
331

    
332
- (void)tableViewDataFetchFailed:(ASIHTTPRequest *)request
333
{
334
	if ([[request error] domain] != NetworkRequestErrorDomain || ![[request error] code] == ASIRequestCancelledErrorType) {
335
		[tableLoadStatus setStringValue:@"Loading data failed"];
336
	}
337
}
338

    
339
- (void)tableViewDataFetchFinished:(ASIHTTPRequest *)request
340
{
341
	NSXMLDocument *xml = [[[NSXMLDocument alloc] initWithData:[request responseData] options:NSXMLDocumentValidate error:nil] autorelease];
342
	for (NSXMLElement *row in [[xml rootElement] elementsForName:@"row"]) {
343
		NSMutableDictionary *rowInfo = [NSMutableDictionary dictionary];
344
		NSString *description = [[[row elementsForName:@"description"] objectAtIndex:0] stringValue];
345
		[rowInfo setValue:description forKey:@"description"];
346
		NSString *imageURL = [[[row elementsForName:@"image"] objectAtIndex:0] stringValue];
347
		ASIHTTPRequest *imageRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:imageURL]];
348
		[imageRequest setDownloadCache:[ASIDownloadCache sharedCache]];
349
		[imageRequest setDidFinishSelector:@selector(rowImageDownloadFinished:)];
350
		[imageRequest setDidFailSelector:@selector(tableViewDataFetchFailed:)];
351
		[imageRequest setDelegate:self];
352
		[imageRequest setUserInfo:rowInfo];
353
		[[self tableQueue] addOperation:imageRequest];
354
		[[self rowData] addObject:rowInfo];
355
	}
356
	[tableView reloadData];
357
}
358

    
359
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
360
{
361
    return [[self rowData] count];
362
}
363

    
364
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
365
{
366
	if ([[aTableColumn identifier] isEqualToString:@"image"]) {
367
		return [[[self rowData] objectAtIndex:rowIndex] objectForKey:@"image"];
368
	} else {
369
		return [[[self rowData] objectAtIndex:rowIndex] objectForKey:@"description"];
370
	}
371
}
372

    
373

    
374
- (void)rowImageDownloadFinished:(ASIHTTPRequest *)request
375
{
376
	NSImage *image = [[[NSImage alloc] initWithData:[request responseData]] autorelease];
377
	[(NSMutableDictionary *)[request userInfo] setObject:image forKey:@"image"];
378
	[tableView reloadData]; // Not efficient, but I hate table view programming :)
379
}
380

    
381
- (IBAction)clearCache:(id)sender
382
{
383
	[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
384
	[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
385
}
386

    
387
- (IBAction)fetchWebPage:(id)sender
388
{
389
	[self fetchURL:[NSURL URLWithString:[urlField stringValue]]];
390

    
391
}
392

    
393
- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener
394
{
395
	// If this is a web page we've requested ourselves, let it load
396
	if ([[actionInformation objectForKey:WebActionNavigationTypeKey] intValue] == WebNavigationTypeOther) {
397
		[listener use];
398
		return;
399
	}
400

    
401
	// If the user clicked on a link, let's tell the webview to ignore it, and we'll load it ourselves
402
	[self fetchURL:[NSURL URLWithString:[[request URL] absoluteString] relativeToURL:[NSURL URLWithString:[urlField stringValue]]]];
403
	[listener ignore];
404
}
405

    
406
- (void)fetchURL:(NSURL *)url
407
{
408
	ASIWebPageRequest *request = [ASIWebPageRequest requestWithURL:url];
409
	[request setDidFailSelector:@selector(webPageFetchFailed:)];
410
	[request setDidFinishSelector:@selector(webPageFetchSucceeded:)];
411
	[request setDelegate:self];
412
	[request setShowAccurateProgress:NO];
413
	[request setDownloadProgressDelegate:progressIndicator];
414
	[request setUrlReplacementMode:([dataURICheckbox state] == NSOnState ? ASIReplaceExternalResourcesWithData : ASIReplaceExternalResourcesWithLocalURLs)];
415

    
416
	// It is strongly recommended that you set both a downloadCache and a downloadDestinationPath for all ASIWebPageRequests
417
	[request setDownloadCache:[ASIDownloadCache sharedCache]];
418
	[request setDownloadDestinationPath:[[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:request]];
419

    
420
	[[ASIDownloadCache sharedCache] setShouldRespectCacheControlHeaders:NO];
421
	[request startAsynchronous];
422
}
423

    
424
- (void)webPageFetchFailed:(ASIHTTPRequest *)request
425
{
426
	[[NSAlert alertWithError:[request error]] runModal];
427
}
428

    
429
- (void)webPageFetchSucceeded:(ASIHTTPRequest *)request
430
{
431
	NSURL *baseURL;
432
	if ([dataURICheckbox state] == NSOnState) {
433
		baseURL = [request url];
434

    
435
		// If we're using ASIReplaceExternalResourcesWithLocalURLs, we must set the baseURL to point to our locally cached file
436
	} else {
437
		baseURL = [NSURL fileURLWithPath:[request downloadDestinationPath]];
438
	}
439

    
440
	if ([request downloadDestinationPath]) {
441
		NSString *response = [NSString stringWithContentsOfFile:[request downloadDestinationPath] encoding:[request responseEncoding] error:nil];
442
		[webPageSource setString:response];
443
		[[webView mainFrame] loadHTMLString:response baseURL:baseURL];
444
	} else if ([request responseString]) {
445
		[webPageSource setString:[request responseString]];
446
		[[webView mainFrame] loadHTMLString:[request responseString] baseURL:baseURL];
447
	}
448

    
449
	[urlField setStringValue:[[request url] absoluteString]];
450
}
451

    
452

    
453
@synthesize bigFetchRequest;
454
@synthesize rowData;
455
@synthesize tableQueue;
456
@end