Basic implementation of File upload and download features in iOS development-backup
Source: Internet
Author: User
<span id="Label3"></p><p><p>Thank the great God for sharing</p></p><p><p></p></p><p><p>This article mainly introduces the iOS development in the file upload and download the basic implementation of the function, and the download aspect of the large file of multi-threaded breakpoint download, the need for friends can refer to the next</p></p><p><p></p></p><p><p><strong>Uploading of files</strong></p></p><p><p>Note: when a file is uploaded using a post request, the data to be uploaded is usually stored in the request Body. This article describes how to implement a file upload in iOS development without the help of a third-party Framework.</p></p><p><p>Because of the complexity of the process, only some of the key code is Posted.</p></p><p><p>Key code for the host Controller:</p></p><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>Yyviewcontroller.m<br>#import "YYViewController.h"<p><p></p></p><p><p>#define Yyencode (str) [str datausingencoding:nsutf8stringencoding]</p></p><p><p>@interface Yyviewcontroller ()</p></p><p><p>@end</p></p><br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>@implementation Yyviewcontroller<p><p></p></p><p><p>-(void) Viewdidload<br>{<br>[super viewdidload];<br>Additional setup after loading the view, typically from a nib.<br>}</p></p><p>-(void) upload: (nsstring *) name filename: (nsstring *) filename mimeType: (nsstring *) mimeType data: (nsdata *) data parmas :(nsdictionary *) Params<br>{<br>File Upload<br>Nsurl *url = [nsurl urlwithstring:@ "http://192.168.1.200:8080/YYServer/upload"];<br>Nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url];<br>Request. HttpMethod = @ "POST";<br><br>Set the request body<br>Nsmutabledata *body = [nsmutabledata data];<br> <br>/*************** File Parameter ***************/<br>Flag for parameter start<br>[body Appenddata:yyencode (@ "--yy\r\n")];<br>Name: Specify parameter name (must be consistent with server Side)<br>Filename: file name<br>NSString *disposition = [nsstring stringwithformat:@ "content-disposition:form-data; name=\"%@\ "; filename=\"%@\ "\ r \ n ", name, filename];<br>[body Appenddata:yyencode (disposition)];<br>NSString *type = [nsstring stringwithformat:@ "content-type:%@\r\n", mimeType];<br>[body Appenddata:yyencode (type)];<br><br>[body appenddata:yyencode (@ "\ r \ n")];<br>[body appenddata:data];<br>[body appenddata:yyencode (@ "\ r \ n")];<br><br>/*************** General parameter ***************/<br>[params enumeratekeysandobjectsusingblock:^ (id key, ID obj, BOOL *stop) {<br>Flag for parameter start<br>[body Appenddata:yyencode (@ "--yy\r\n")];<br>NSString *disposition = [nsstring stringwithformat:@ "content-disposition:form-data; name=\"%@\ "\ r \ n", key];<br>[body Appenddata:yyencode (disposition)];</p><p>[body appenddata:yyencode (@ "\ r \ n")];<br>[body Appenddata:yyencode (obj)];<br>[body appenddata:yyencode (@ "\ r \ n")];<br>}];<br><br>/*************** parameter End ***************/<br>yy--\r\n<br>[body Appenddata:yyencode (@ "--yy--\r\n")];<br>Request. Httpbody = body;<br><br>Set the request header<br>The length of the request body<br>[request setvalue:[nsstring stringwithformat:@ "%zd", body.length] forhttpheaderfield:@ "content-length"];<br>Declare that the POST request is a file upload<br>[request setvalue:@ "multipart/form-data; boundary=yy" forhttpheaderfield:@ "content-type"];<br><br>Send Request<br>[nsurlconnection sendasynchronousrequest:request queue:[nsoperationqueue mainqueue] completionHandler:^ ( Nsurlresponse *response, nsdata *data, nserror *connectionerror) {<br>If (data) {<br>Nsdictionary *dict = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingmutableleaves error:nil];<br>NSLog (@ "%@", dict);<br>} else {<br>NSLog (@ "upload failed");<br>}<br>}];<br>}</p><p>-(void) touchesbegan: (nsset *) touches withevent: (uievent *) Event<br>{<br>Socket Implementation Breakpoint Upload<br><br>Apache-tomcat-6.0.41/conf/web.xml Find mimeType for files<br>UIImage *image = [UIImage imagenamed:@ "test"];<br>NSData *filedata = uiimagepngrepresentation (image);<br>[self upload:@ "file" filename:@ "test.png" mimetype:@ "image/png" data:filedata parmas:@{@ "username": @ "123"}];<br><br>Send a request to a local file<br>Nsurl *fileurl = [[nsbundle mainbundle] urlforresource:@ "itcast.txt" withextension:nil];<br>Nsurlrequest *request = [nsurlrequest requestwithurl:fileurl];<br>Nsurlresponse *repsonse = nil;<br>NSData *data = [nsurlconnection sendsynchronousrequest:request returningresponse:&repsonse error:nil];<br><br>Get MimeType<br>NSLog (@ "%@", Repsonse. MIMEType);<br>[self upload:@ "file" filename:@ "itcast.txt" mimetype:repsonse. MIMEType Data:data parmas:@{<br>@ "username": @ "999",<br>@ "type": @ "XML"}];<br>}</p><p><p>@end</p></p><br>Additional Notes:<p><p></p></p><p><p>File upload request data format</p></p><p><p></p></p><p><p>MimeType of some files</p></p><p><p></p></p><p><p></p></p><p><p><strong>Multi-threaded Breakpoint Download<br></strong>Description: This article describes multi-threaded breakpoint downloads. The project uses Apple's own class to enable multiple threads to download a larger file at the same time. Because the implementation process is more complex, The complete code is posted below.</p></p><p><p>Implementation Ideas: Download start, Create a file with the same size to download (if the file to download is 100M, then create a 100M file in the sandbox, and then calculate the download volume of each segment, open multiple threads to download the data of each segment, write the corresponding file section).</p></p><p><p></p></p><p><p>The main classes used in the project are as Follows:</p></p><p><p></p></p><p><p>The implementation code is completed as Follows:</p></p><p><p>Code in the host Controller:</p></p><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>#import "YYViewController.h"<br>#import "YYFileMultiDownloader.h"<p><p></p></p><p><p>@interface Yyviewcontroller ()<br>@property (nonatomic, Strong) Yyfilemultidownloader *filemultidownloader;<br>@end</p></p><br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>@implementation Yyviewcontroller<br>-(yyfilemultidownloader *) Filemultidownloader<br>{<br>If (!_filemultidownloader) {<br>_filemultidownloader = [[yyfilemultidownloader alloc] init];<br>The file remote URL that needs to be downloaded<br>_filemultidownloader.url = @ "http://192.168.1.200:8080/MJServer/resources/jre.zip";<br>Where are the files saved?<br>NSString *caches = [nssearchpathfordirectoriesindomains (nscachesdirectory, nsuserdomainmask, YES) lastObject];<br>NSString *filepath = [caches stringbyappendingpathcomponent:@ "jre.zip"];<br>_filemultidownloader.destpath = filepath;<br>}<br>Return _filemultidownloader;<br>}<p><p></p></p><p><p>-(void) Viewdidload<br>{<br>[super viewdidload];<br><br>}</p></p><p><p>-(void) touchesbegan: (nsset *) touches withevent: (uievent *) Event<br>{<br>[self.filemultidownloader start];<br>}</p></p><p><p>@end</p></p><br>Customizing a base class<br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>YYFileDownloader.h file<br>#import <Foundation/Foundation.h><p><p></p></p><p><p>@interface Yyfiledownloader:nsobject<br>{<br>BOOL _downloading;<br>}<br>/**<br>* The remote URL of the file you want to download (the path to the connection Server)<br>*/<br>@property (nonatomic, copy) nsstring *url;<br>/**<br>* File storage path (where files are Downloaded)<br>*/<br>@property (nonatomic, copy) nsstring *destpath;</p></p><p><p>/**<br>* Is downloading (there is no download, only the inside of the downloader to Know)<br>*/<br>@property (nonatomic, readonly, getter = Isdownloading) BOOL downloading;</p></p><p><p>/**<br>* To monitor the download progress<br>*/<br>@property (nonatomic, copy) void (^progresshandler) (double progress);</p></p><p><p>/**<br>* Start (resume) Download<br>*/<br>-(void) start;</p></p><p><p>/**<br>* Pause Download<br>*/<br>-(void) pause;<br>@end</p></p><br>YYFILEDOWNLOADER.M file<br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>#import "YYFileDownloader.h"<p><p></p></p><p><p>@implementation Yyfiledownloader<br>@end</p></p><br>The Downloader class inherits from the Yyfiledownloader class<p><p></p></p><p><p>YYFileSingDownloader.h file</p></p><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>#import "YYFileDownloader.h"<p><p></p></p><p><p>@interface Yyfilesingledownloader:yyfiledownloader<br>/**<br>* Where to start<br>*/<br>@property (nonatomic, Assign) Long Long begin;<br>/**<br>* End of position<br>*/<br>@property (nonatomic, Assign) Long Long end;<br>@end</p></p><br>YYFILESINGDOWNLOADER.M file<br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>#import "YYFileSingleDownloader.h"<br>@interface Yyfilesingledownloader () <NSURLConnectionDataDelegate><br>/**<br>* Connection Object<br>*/<br>@property (nonatomic, Strong) nsurlconnection *conn;<p><p></p></p><p><p>/**<br>* File handle for writing data<br>*/<br>@property (nonatomic, Strong) Nsfilehandle *writehandle;<br>/**<br>* Length of the currently downloaded data<br>*/<br>@property (nonatomic, Assign) Long Long currentlength;<br>@end</p></p><br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>@implementation Yyfilesingledownloader<p><p></p></p><p><p>-(nsfilehandle *) Writehandle<br>{<br>If (!_writehandle) {<br>_writehandle = [nsfilehandle fileHandleForWritingAtPath:self.destPath];<br>}<br>Return _writehandle;<br>}</p></p><p><p>/**<br>* Start (resume) Download<br>*/<br>-(void) start<br>{<br>Nsurl *url = [nsurl URLWithString:self.url];<br>The default is a GET request<br>Nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url];<br>Set Request header information<br>NSString *value = [nsstring stringwithformat:@ "bytes=%lld-%lld", self.begin + self.currentlength, self.end];<br>[request Setvalue:value forhttpheaderfield:@ "Range"];<br>Self.conn = [nsurlconnection Connectionwithrequest:request delegate:self];<br><br>_downloading = YES;<br>}</p></p><p><p>/**<br>* Pause Download<br>*/<br>-(void) Pause<br>{<br>[self.conn cancel];<br>Self.conn = nil;<br><br>_downloading = NO;<br>}</p></p><p><p> <br> #pragma mark-nsurlconnectiondatadelegate proxy method <br>/** <br> * 1. When the response to the server is accepted (the server is connected) the <br> */is called <br>-(void) connection: (nsurlconnection *) connection didreceiveresponse: (nsurlresponse *) response <br> {<br> <br>} </p></p><p><p>/** <br> * 2. When the data that is accepted to the server is called (may be called multiple times, each call will only pass part of the Data) <br> */<br>-(void) connection: ( Nsurlconnection *) Connection Didreceivedata: (nsdata *) data <br> {<br> //move to Tail of file <br> [self.writehandle SeekToFileOffset:self.begin + self.currentlength]; <br> //start writing data from the currently moving position (end of File) <br> [self.writehandle writedata:data]; <br> &NBSP;&NBSP;&NBSP;&NBSP <br> //cumulative Length <br> self.currentlength + = data.length; <br> <br> //print Download Progress <br> Double progress = (double) self.currentlength/(self.end-self.begin); <br> if (self.progresshandler) {<br> Self.progresshandler (progress); <br> } <br>} </p></p><p><p>/**<br>* 3. When the Server's data is accepted, it is called<br>*/<br>-(void) connectiondidfinishloading: (nsurlconnection *) Connection<br>{<br>Emptying attribute values<br>Self.currentlength = 0;<br><br>Close the connection (no longer entering data into the File)<br>[self.writehandle closefile];<br>Self.writehandle = nil;<br>}</p></p><p><p>/**<br>* Request Error (failure) when the call (request timeout \ network \ No network, generally referred to as client Error)<br>*/<br>-(void) connection: (nsurlconnection *) connection didfailwitherror: (nserror *) error<br>{<br><br>}</p></p><p><p>@end</p></p><br>Design multi-threaded Downloader (use hmfilemultidownloader to open multiple threads to download a file simultaneously)<p><p></p></p><p><p>A multithreaded downloader downloads only one file</p></p><p><p>YYFileMultiDownloader.h file</p></p><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>#import "YYFileDownloader.h"<p><p></p></p><p><p>@interface Yyfilemultidownloader:yyfiledownloader<br><br>@end</p></p><br>YYFILEMULTIDOWNLOADER.M file<br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>#import "YYFileMultiDownloader.h"<br>#import "YYFileSingleDownloader.h"<p><p></p></p><p><p>#define YYMAXDOWNLOADCOUNT 4</p></p><p><p>@interface Yyfilemultidownloader ()<br>@property (nonatomic, Strong) Nsmutablearray *singledownloaders;<br>@property (nonatomic, Assign) Long Long totallength;<br>@end</p></p><br><span style="text-decoration: underline;"><span style="text-decoration: underline;">Copy Code</span></span>The code is as Follows:<br>@implementation Yyfilemultidownloader<p><p></p></p><p><p>-(void) GetFileSize<br>{<br>Nsmutableurlrequest *request = [nsmutableurlrequest Requestwithurl:[nsurl URLWithString:self.url];<br>Request. HttpMethod = @ "HEAD";<br><br>Nsurlresponse *response = nil;<br>#warning here to use an asynchronous request<br>[nsurlconnection sendsynchronousrequest:request Returningresponse:&response error:nil];<br>Self.totallength = response.expectedcontentlength;<br>}</p></p><p>-(nsmutablearray *) Singledownloaders<br>{<br>If (!_singledownloaders) {<br>_singledownloaders = [nsmutablearray array];<br><br>Get File size<br>[self getfilesize];<br><br>Number of downloads per path<br>A long long size = 0;<br>If (self.totallength% Yymaxdownloadcount = = 0) {<br>Size = self.totallength/yymaxdownloadcount;<br>} else {<br>Size = Self.totallength/yymaxdownloadcount + 1;<br>}<br><br>Create N Downloader<br>for (int i = 0; i<yymaxdownloadcount; i++) {<br>Yyfilesingledownloader *singledownloader = [[yyfilesingledownloader alloc] init];<br>Singledownloader.url = self.url;<br>Singledownloader.destpath = self.destpath;<br>Singledownloader.begin = i * size;<br>Singledownloader.end = Singledownloader.begin + size-1;<br>Singledownloader.progresshandler = ^ (double Progress) {<br>NSLog (@ "%d---%f", i, progress);<br>};<br>[_singledownloaders addobject:singledownloader];<br>}<br><br>Create a temporary file, such as the server file size<br>[[nsfilemanager defaultmanager] CreateFileAtPath:self.destPath Contents:nil attributes:nil];<br> <br>Let the length of Self.destpath file be self.totallengt<br>Nsfilehandle *handle = [nsfilehandle fileHandleForWritingAtPath:self.destPath];<br>[handle truncateFileAtOffset:self.totalLength];<br>}<br>Return _singledownloaders;<br>}</p><p><p>/**<br>* Start (resume) Download<br>*/<br>-(void) start<br>{<br>[self.singledownloaders makeobjectsperformselector: @selector (start)];<br><br>_downloading = YES;<br>}</p></p><p><p>/**<br>* Pause Download<br>*/<br>-(void) Pause<br>{<br>[self.singledownloaders makeobjectsperformselector: @selector (pause)];<br>_downloading = NO;<br>}</p></p><p><p>@end</p></p><br>Supplemental Instructions: How to get the size of the file that will be downloaded?<br><p><p></p></p><p><p></p></p><p><p>Basic implementation of File upload and download features in iOS development-backup</p></p></span>
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service