Ben Copsey

* Prevent timeouts in low bandwidth situations when upload size > 128KB

* Ignore first 128KB of upload progress in upload progress delegates, to prevent erroneous reporting of progress
* Remove silly debug code that broke accurate progress on iPhone
... ... @@ -10,7 +10,11 @@
// Portions are based on the ImageClient example from Apple:
// See: http://developer.apple.com/samplecode/ImageClient/listing37.html
#import <CFNetwork/CFNetwork.h>
// Dammit, importing frameworks when you are targetting two platforms is a PITA
#if TARGET_OS_IPHONE
#import <CFNetwork/CFNetwork.h>
#endif
typedef enum _ASINetworkErrorType {
ASIConnectionFailureErrorType = 1,
... ... @@ -160,6 +164,8 @@ typedef enum _ASINetworkErrorType {
// Prevents the body of the post being built more than once (largely for subclasses)
BOOL haveBuiltPostBody;
unsigned long long uploadBufferSize;
}
#pragma mark init / dealloc
... ... @@ -298,4 +304,5 @@ typedef enum _ASINetworkErrorType {
@property (retain) ASIHTTPRequest *mainRequest;
@property (assign) BOOL showAccurateProgress;
@property (assign,readonly) unsigned long long totalBytesRead;
@property (assign) unsigned long long uploadBufferSize;
@end
... ...
... ... @@ -71,6 +71,7 @@ static NSError *ASIUnableToCreateRequestError;
requestAuthentication = NULL;
haveBuiltPostBody = NO;
request = NULL;
[self setUploadBufferSize:0];
[self setResponseHeaders:nil];
[self setTimeOutSeconds:10];
[self setUseKeychainPersistance:NO];
... ... @@ -184,6 +185,11 @@ static NSError *ASIUnableToCreateRequestError;
complete = NO;
if (!url) {
[self failWithError:ASIUnableToCreateRequestError];
return;
}
// Create a new HTTP request.
request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (CFStringRef)requestMethod, (CFURLRef)url, kCFHTTPVersion1_1);
if (!request) {
... ... @@ -346,8 +352,12 @@ static NSError *ASIUnableToCreateRequestError;
NSDate *now = [NSDate date];
// See if we need to timeout
if (lastActivityTime && timeOutSeconds > 0) {
if ([now timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) {
if (lastActivityTime && timeOutSeconds > 0 && [now timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) {
// Prevent timeouts before 128KB has been sent when the size of data to upload is greater than 128KB
// This is to workaround the fact that kCFStreamPropertyHTTPRequestBytesWrittenCount is the amount written to the buffer, not the amount actually sent
// This workaround prevents erroneous timeouts in low bandwidth situations (eg iPhone)
if (contentLength <= uploadBufferSize || (uploadBufferSize > 0 && lastBytesSent > uploadBufferSize)) {
[self failWithError:ASIRequestTimedOutError];
[self cancelLoad];
complete = YES;
... ... @@ -474,6 +484,25 @@ static NSError *ASIUnableToCreateRequestError;
return;
}
unsigned long long byteCount = [[(NSNumber *)CFReadStreamCopyProperty (readStream, kCFStreamPropertyHTTPRequestBytesWrittenCount) autorelease] unsignedLongLongValue];
// If this is the first time we've written to the buffer, byteCount will be the size of the buffer (currently seems to be 128KB on both Mac and iPhone)
// We will remove this from any progress display, as kCFStreamPropertyHTTPRequestBytesWrittenCount does not tell us how much data has actually be written
if (byteCount > 0 && uploadBufferSize == 0 && byteCount != postLength) {
[self setUploadBufferSize:byteCount];
SEL selector = @selector(setUploadBufferSize:);
if ([uploadProgressDelegate respondsToSelector:selector]) {
NSMethodSignature *signature = nil;
signature = [[uploadProgressDelegate class] instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:uploadProgressDelegate];
[invocation setSelector:selector];
[invocation setArgument:&byteCount atIndex:2];
[invocation invoke];
}
}
[cancelledLock unlock];
if (byteCount > lastBytesSent) {
[self setLastActivityTime:[NSDate date]];
... ... @@ -485,7 +514,13 @@ static NSError *ASIUnableToCreateRequestError;
if ([uploadProgressDelegate respondsToSelector:@selector(incrementUploadProgressBy:)]) {
unsigned long long value = 0;
if (showAccurateProgress) {
value = byteCount-lastBytesSent;
if (byteCount == postLength) {
value = byteCount+uploadBufferSize;
} else if (lastBytesSent > 0) {
value = ((byteCount-uploadBufferSize)-(lastBytesSent-uploadBufferSize));
} else {
value = 0;
}
} else {
value = 1;
updatedProgress = YES;
... ... @@ -501,7 +536,7 @@ static NSError *ASIUnableToCreateRequestError;
// We aren't using a queue, we should just set progress of the indicator
} else {
[ASIHTTPRequest setProgress:(double)(1.0*byteCount/postLength) forProgressIndicator:uploadProgressDelegate];
[ASIHTTPRequest setProgress:(double)(1.0*(byteCount-uploadBufferSize)/(postLength-uploadBufferSize)) forProgressIndicator:uploadProgressDelegate];
}
}
... ... @@ -602,7 +637,7 @@ static NSError *ASIUnableToCreateRequestError;
+ (void)setProgress:(double)progress forProgressIndicator:(id)indicator
{
SEL selector;
[progressLock lock];
... ... @@ -614,13 +649,12 @@ static NSError *ASIUnableToCreateRequestError;
[invocation setSelector:selector];
float progressFloat = (float)progress; // UIProgressView wants a float for the progress parameter
[invocation setArgument:&progressFloat atIndex:2];
[invocation invokeWithTarget:indicator];
// If we're running in the main thread, update the progress straight away. Otherwise, it's not that urgent
[invocation performSelectorOnMainThread:@selector(invokeWithTarget:) withObject:indicator waitUntilDone:[NSThread isMainThread]];
// Cocoa: NSProgressIndicator
// Cocoa: NSProgressIndicator
} else if ([indicator respondsToSelector:@selector(setDoubleValue:)]) {
selector = @selector(setDoubleValue:);
NSMethodSignature *signature = [[indicator class] instanceMethodSignatureForSelector:selector];
... ... @@ -1146,4 +1180,5 @@ static NSError *ASIUnableToCreateRequestError;
@synthesize totalBytesRead;
@synthesize showAccurateProgress;
@synthesize totalBytesRead;
@synthesize uploadBufferSize;
@end
... ...
... ... @@ -74,6 +74,11 @@
// Called during a request when authorisation fails to cancel any progress so far
- (void)decrementUploadProgressBy:(unsigned long long)bytes;
// Called when the first chunk of data is written to the upload buffer
// We ignore the first part chunk when tracking upload progress, as kCFStreamPropertyHTTPRequestBytesWrittenCount reports the amount of data written to the buffer, not the amount sent
// This is to workaround the first 128KB of data appearing in an upload progress delegate immediately
- (void)setUploadBufferSize:(unsigned long long)bytes;
// All ASINetworkQueues are paused when created so that total size can be calculated before the queue starts
// This method will start the queue
- (void)go;
... ...
... ... @@ -193,6 +193,16 @@
}
}
- (void)setUploadBufferSize:(unsigned long long)bytes
{
if (!uploadProgressDelegate) {
return;
}
uploadProgressTotalBytes -= bytes;
[self incrementUploadProgressBy:0];
}
- (void)incrementUploadSizeBy:(unsigned long long)bytes
{
if (!uploadProgressDelegate) {
... ...
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.02">
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">9F33</string>
<string key="IBDocument.InterfaceBuilderVersion">672</string>
<string key="IBDocument.AppKitVersion">949.34</string>
<string key="IBDocument.HIToolboxVersion">352.00</string>
<string key="IBDocument.SystemVersion">9G55</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.43</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="440"/>
<integer value="444"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilderKit</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1021">
... ... @@ -1055,7 +1064,7 @@ cmVhZC4</string>
<object class="NSTabViewItem" id="725395930">
<string key="NSIdentifier">Item 2</string>
<object class="NSView" key="NSView" id="624078948">
<reference key="NSNextResponder" ref="495298985"/>
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
... ... @@ -1208,7 +1217,6 @@ cmVhZC4</string>
</object>
</object>
<string key="NSFrame">{{10, 33}, {441, 243}}</string>
<reference key="NSSuperview" ref="495298985"/>
</object>
<string key="NSLabel">Queue</string>
<reference key="NSColor" ref="482475293"/>
... ... @@ -1323,7 +1331,7 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<object class="NSTabViewItem" id="409502867">
<string key="NSIdentifier">Item 4</string>
<object class="NSView" key="NSView" id="408528501">
<nil key="NSNextResponder"/>
<reference key="NSNextResponder" ref="495298985"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
... ... @@ -1365,20 +1373,21 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
</object>
</object>
<string key="NSFrame">{{10, 33}, {441, 243}}</string>
<reference key="NSSuperview" ref="495298985"/>
</object>
<string key="NSLabel">Upload</string>
<reference key="NSColor" ref="482475293"/>
<reference key="NSTabView" ref="495298985"/>
</object>
</object>
<reference key="NSSelectedTabViewItem" ref="725395930"/>
<reference key="NSSelectedTabViewItem" ref="409502867"/>
<reference key="NSFont" ref="584670792"/>
<int key="NSTvFlags">0</int>
<bool key="NSAllowTruncatedLabels">YES</bool>
<bool key="NSDrawsBackground">YES</bool>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="624078948"/>
<reference ref="408528501"/>
</object>
</object>
</object>
... ... @@ -3420,7 +3429,6 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>354.IBPluginDependency</string>
<string>354.ImportedFromIB2</string>
<string>371.IBEditorWindowLastContentRect</string>
<string>371.IBPluginDependency</string>
<string>371.IBWindowTemplateEditedContentRect</string>
<string>371.NSWindowTemplate.visibleAtLaunch</string>
<string>371.editorWindowContentRectSynchronizationRect</string>
... ... @@ -3428,7 +3436,6 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>381.IBPluginDependency</string>
<string>384.IBPluginDependency</string>
<string>390.IBEditorWindowLastContentRect</string>
<string>390.IBPluginDependency</string>
<string>390.IBWindowTemplateEditedContentRect</string>
<string>390.NSWindowTemplate.visibleAtLaunch</string>
<string>390.editorWindowContentRectSynchronizationRect</string>
... ... @@ -3458,6 +3465,12 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>436.IBPluginDependency</string>
<string>437.IBPluginDependency</string>
<string>438.IBPluginDependency</string>
<string>439.IBPluginDependency</string>
<string>440.IBPluginDependency</string>
<string>441.IBPluginDependency</string>
<string>442.IBPluginDependency</string>
<string>443.IBPluginDependency</string>
<string>444.IBPluginDependency</string>
<string>451.IBPluginDependency</string>
<string>452.IBPluginDependency</string>
<string>453.IBPluginDependency</string>
... ... @@ -3673,7 +3686,6 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>{{267, 307}, {480, 337}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{267, 307}, {480, 337}}</string>
<reference ref="9"/>
<string>{{235, -51}, {480, 337}}</string>
... ... @@ -3681,7 +3693,6 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{21, 629}, {279, 182}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{21, 629}, {279, 182}}</string>
<integer value="0"/>
<string>{{793, -129}, {279, 182}}</string>
... ... @@ -3746,6 +3757,12 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
... ...
... ... @@ -9,7 +9,7 @@ It provides:
* Easy access to request and response HTTP headers
* Progress delegates (NSProgressIndicators and UIProgressViews) to show information about download AND upload progress
* Auto-magic management of upload and download progress indicators for operation queues
* Basic + Digest authentication support, credentials are automatically for the duration of a session, and can be stored for later in the Keychain.
* Basic + Digest authentication support, credentials are automatically re-used for the duration of a session, and can be stored for later in the Keychain.
* Cookie support
* Based on NSOperation to make queuing requests and background operation easy
* Basic unit tests (more to come!)
... ...
//
// UploadViewController.h
// asi-http-request
//
// Created by Ben Copsey on 31/12/2008.
// Copyright 2008 All-Seeing Interactive. All rights reserved.
//
#import <UIKit/UIKit.h>
@class ASINetworkQueue;
@interface UploadViewController : UIViewController {
ASINetworkQueue *networkQueue;
IBOutlet UIProgressView *progressIndicator;
}
- (IBAction)performLargeUpload:(id)sender;
@end
... ...
//
// UploadViewController.m
// asi-http-request
//
// Created by Ben Copsey on 31/12/2008.
// Copyright 2008 All-Seeing Interactive. All rights reserved.
//
#import "UploadViewController.h"
#import "ASIFormDataRequest.h"
#import "ASINetworkQueue.h"
@implementation UploadViewController
- (void)awakeFromNib
{
networkQueue = [[ASINetworkQueue alloc] init];
}
- (IBAction)performLargeUpload:(id)sender
{
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
[networkQueue setUploadProgressDelegate:progressIndicator];
[networkQueue setDelegate:self];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]] autorelease];
[request setPostValue:@"test" forKey:@"value1"];
[request setPostValue:@"test" forKey:@"value2"];
[request setPostValue:@"test" forKey:@"value3"];
[request setTimeOutSeconds:20];
[request setData:[NSMutableData dataWithLength:1024*1024] forKey:@"1mb-of-crap"];
[networkQueue addOperation:request];
[networkQueue go];
}
- (void)dealloc {
[networkQueue release];
[super dealloc];
}
@end
... ...
This diff was suppressed by a .gitattributes entry.
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.02">
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">528</int>
<string key="IBDocument.SystemVersion">9F33</string>
<string key="IBDocument.InterfaceBuilderVersion">672</string>
<string key="IBDocument.AppKitVersion">949.34</string>
<string key="IBDocument.HIToolboxVersion">352.00</string>
<string key="IBDocument.SystemVersion">9G55</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.43</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="106"/>
... ... @@ -14,6 +14,15 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="841351856">
... ... @@ -40,13 +49,13 @@
<object class="IBUITabBarController" id="1034742383">
<object class="IBUISimulatedTabBarMetrics" key="IBUISimulatedBottomBarMetrics"/>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<object class="IBUIViewController" key="IBUISelectedViewController" id="268481961">
<object class="IBUITabBarItem" key="IBUITabBarItem" id="807309489">
<string key="IBUITitle">Queue</string>
<object class="IBUIViewController" key="IBUISelectedViewController" id="629097222">
<object class="IBUITabBarItem" key="IBUITabBarItem" id="859844916">
<string key="IBUITitle">Upload</string>
<reference key="IBUITabBar"/>
</object>
<reference key="IBUIParentViewController" ref="1034742383"/>
<string key="IBUINibName">Queue</string>
<string key="IBUINibName">UploadProgress</string>
</object>
<object class="NSMutableArray" key="IBUIViewControllers">
<bool key="EncodedWithXMLCoder">YES</bool>
... ... @@ -58,7 +67,15 @@
<reference key="IBUIParentViewController" ref="1034742383"/>
<string key="IBUINibName">Synchronous</string>
</object>
<reference ref="268481961"/>
<object class="IBUIViewController" id="268481961">
<object class="IBUITabBarItem" key="IBUITabBarItem" id="807309489">
<string key="IBUITitle">Queue</string>
<reference key="IBUITabBar"/>
</object>
<reference key="IBUIParentViewController" ref="1034742383"/>
<string key="IBUINibName">Queue</string>
</object>
<reference ref="629097222"/>
</object>
<object class="IBUITabBar" key="IBUITabBar" id="795333663">
<nil key="NSNextResponder"/>
... ... @@ -138,6 +155,7 @@
<reference ref="795333663"/>
<reference ref="1024858337"/>
<reference ref="268481961"/>
<reference ref="629097222"/>
</object>
<reference key="parent" ref="957960031"/>
</object>
... ... @@ -179,6 +197,20 @@
<reference key="object" ref="532797962"/>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">124</int>
<reference key="object" ref="629097222"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="859844916"/>
</object>
<reference key="parent" ref="1034742383"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">125</int>
<reference key="object" ref="859844916"/>
<reference key="parent" ref="629097222"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
... ... @@ -196,6 +228,7 @@
<string>109.IBPluginDependency</string>
<string>110.IBPluginDependency</string>
<string>111.IBPluginDependency</string>
<string>124.CustomClassName</string>
<string>2.IBAttributePlaceholdersKey</string>
<string>2.IBEditorWindowLastContentRect</string>
<string>2.IBPluginDependency</string>
... ... @@ -215,6 +248,7 @@
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>UploadViewController</string>
<object class="NSMutableDictionary">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
... ... @@ -250,7 +284,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">123</int>
<int key="maxID">125</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
... ... @@ -266,6 +300,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>accurateProgress</string>
<string>imageView1</string>
<string>imageView2</string>
<string>imageView3</string>
... ... @@ -273,6 +308,7 @@
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UISwitch</string>
<string>UIImageView</string>
<string>UIImageView</string>
<string>UIImageView</string>
... ... @@ -301,6 +337,22 @@
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">UploadViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">performLargeUpload:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">progressIndicator</string>
<string key="NS.object.0">UIProgressView</string>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">UploadViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">iPhoneSampleAppDelegate</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
... ...
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.02">
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">528</int>
<string key="IBDocument.SystemVersion">9F33</string>
<string key="IBDocument.InterfaceBuilderVersion">672</string>
<string key="IBDocument.AppKitVersion">949.34</string>
<string key="IBDocument.HIToolboxVersion">352.00</string>
<string key="IBDocument.SystemVersion">9G55</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.43</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="1"/>
... ... @@ -14,6 +14,15 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
... ... @@ -237,9 +246,9 @@
<reference ref="138477738"/>
<reference ref="496427125"/>
<reference ref="602749642"/>
<reference ref="963091686"/>
<reference ref="365204290"/>
<reference ref="104706742"/>
<reference ref="963091686"/>
</object>
<reference key="parent" ref="360949347"/>
</object>
... ... @@ -317,7 +326,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>QueueViewController</string>
<string>UIResponder</string>
<string>{{901, 368}, {320, 480}}</string>
<string>{{639, 368}, {320, 480}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.02">
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">528</int>
<string key="IBDocument.SystemVersion">9F33</string>
<string key="IBDocument.InterfaceBuilderVersion">672</string>
<string key="IBDocument.AppKitVersion">949.34</string>
<string key="IBDocument.HIToolboxVersion">352.00</string>
<string key="IBDocument.SystemVersion">9G55</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.43</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="1"/>
... ... @@ -14,6 +14,15 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
... ... @@ -97,7 +106,7 @@ YSB0aHJlYWQuA</string>
<bool key="IBUICanCancelContentTouches">NO</bool>
<bool key="IBUIBouncesZoom">NO</bool>
<bool key="IBUIEditable">NO</bool>
<string key="IBUIText"/>
<string key="IBUIText">HTML source will be here</string>
<reference key="IBUIFont" ref="467718481"/>
</object>
</object>
... ... @@ -208,7 +217,7 @@ YSB0aHJlYWQuA</string>
<bool key="EncodedWithXMLCoder">YES</bool>
<string>SynchronousViewController</string>
<string>UIResponder</string>
<string>{{714, 372}, {320, 480}}</string>
<string>{{639, 372}, {320, 480}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
... ...
This diff is collapsed. Click to expand it.