The basic implementation of uploading and downloading of files in IOS development _ios

Source: Internet
Author: User

Upload of files

Note: File uploads are used when post requests, usually to upload data stored in the request body. This article describes how to implement the file upload in iOS development without the help of a third party framework.

Because of the complexity of the process, only some of the key code is posted in this article.

Key code for the master controller:

Copy Code code as follows:

Yyviewcontroller.m
#import "YYViewController.h"

#define YYENCODE (str) [STR datausingencoding:nsutf8stringencoding]

@interface Yyviewcontroller ()

@end


Copy Code code as follows:

@implementation Yyviewcontroller

-(void) viewdidload
{
[Super Viewdidload];
Do no additional setup after loading the view, typically from a nib.
}

-(void) Upload: (NSString *) name filename: (nsstring *) filename mimetype: (NSString *) mimetype data: (NSData *) Data Parmas :(nsdictionary *) params
{
File Upload
Nsurl *url = [Nsurl urlwithstring:@ "Http://192.168.1.200:8080/YYServer/upload"];
Nsmutableurlrequest *request = [Nsmutableurlrequest Requestwithurl:url];
Request. HttpMethod = @ "POST";

Set up the request body
Nsmutabledata *body = [Nsmutabledata data];

/*************** file Parameters ***************/
Flags that start the argument
[Body Appenddata:yyencode (@ "--yy\r\n")];
Name: Specify parameter name (must be consistent with server side)
FileName: filename
NSString *disposition = [NSString stringwithformat:@ "content-disposition:form-data; name=\"%@\ "; filename=\"%@\ "\ r \ n", name, filename];
[Body Appenddata:yyencode (disposition)];
NSString *type = [NSString stringwithformat:@ content-type:
%@\r\n ", MimeType];
[Body Appenddata:yyencode (type)];

[Body Appenddata:yyencode (@ "\ r \ n")];
[Body appenddata:data];
[Body Appenddata:yyencode (@ "\ r \ n")];

/*************** General parameter ***************/
[Params enumeratekeysandobjectsusingblock:^ (ID key, id obj, BOOL *stop) {
Flags that start the argument
[Body Appenddata:yyencode (@ "--yy\r\n")];
NSString *disposition = [NSString stringwithformat:@ "content-disposition:form-data; name=\"
%@\ "\ r \ n", key];
[Body Appenddata:yyencode (disposition)];

[Body Appenddata:yyencode (@ "\ r \ n")];
[Body Appenddata:yyencode (obj)];
[Body Appenddata:yyencode (@ "\ r \ n")];
}];

/*************** parameter End ***************/
yy--\r\n
[Body Appenddata:yyencode (@ "--yy--\r\n")];
Request. Httpbody = body;

Set Request headers
Length of the request body
[Request setvalue:[nsstring stringwithformat:@ "%zd", Body.length] forhttpheaderfield:@ "Content-length"];
Declare this post request to be a file upload
[Request setvalue:@ "Multipart/form-data boundary=yy" forhttpheaderfield:@ "Content-type"];

Send Request
[Nsurlconnection sendasynchronousrequest:request queue:[nsoperationqueue Mainqueue] completionHandler:^ ( Nsurlresponse *response, NSData *data, Nserror *connectionerror) {
if (data) {
Nsdictionary *dict = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingmutableleaves Error:nil];
NSLog (@ "%@", dict);
} else {
NSLog (@ "upload failed");
}
}];
}

-(void) Touchesbegan: (Nsset *) touches withevent: (Uievent *) event
{
Socket Implementation Breakpoint Upload

Apache-tomcat-6.0.41/conf/web.xml Find a file mimetype
UIImage *image = [uiimage imagenamed:@ "test"];
NSData *filedata = uiimagepngrepresentation (image);
[Self upload:@ "file" filename:@ "Test.png" mimetype:@ "image/png" Data:filedata parmas:@{@ "username": @ "123"}];

Send a request to a local file
Nsurl *fileurl = [[NSBundle mainbundle] urlforresource:@ "Itcast.txt" withextension:nil];
Nsurlrequest *request = [Nsurlrequest Requestwithurl:fileurl];
Nsurlresponse *repsonse = nil;
NSData *data = [nsurlconnection sendsynchronousrequest:request returningresponse:&repsonse Error:nil];

Get MimeType
NSLog (@ "%@", repsonse.) MimeType);
[Self upload:@ ' file ' filename:@ ' Itcast.txt ' mimetype:repsonse. MimeType Data:data parmas:@{
@ "username": @ "999",
@ "type": @ "XML"}];
}

@end


Supplementary Note:

File upload request data format

MimeType of some files

Multi-threaded Breakpoint Download
Description: This article describes multithreaded breakpoint downloads. The project uses the Apple-band class, which enables simultaneous opening of multiple threads to download a larger file. Because the implementation process is more complex, the complete code is posted below.

Realization: Download begins, create a file that is the same size as the file you want to download (if the file you want to download is 100M, create a 100M file in the sandbox, and then calculate the download amount for each segment, open multiple threads to download the data for each segment, and write the corresponding file section separately).

The main classes used in the project are as follows:

The completed implementation code is as follows:

Code in the primary controller:

Copy Code code as follows:

#import "YYViewController.h"
#import "YYFileMultiDownloader.h"

@interface Yyviewcontroller ()
@property (nonatomic, strong) Yyfilemultidownloader *filemultidownloader;
@end


Copy Code code as follows:

@implementation Yyviewcontroller
-(Yyfilemultidownloader *) Filemultidownloader
{
if (!_filemultidownloader) {
_filemultidownloader = [[Yyfilemultidownloader alloc] init];
File remote URL that needs to be downloaded
_filemultidownloader.url = @ "Http://192.168.1.200:8080/MJServer/resources/jre.zip";
Where is the file saved?
NSString *caches = [Nssearchpathfordirectoriesindomains (nscachesdirectory, Nsuserdomainmask, YES) lastObject];
NSString *filepath = [Caches stringbyappendingpathcomponent:@ "Jre.zip"];
_filemultidownloader.destpath = filepath;
}
return _filemultidownloader;
}

-(void) viewdidload
{
[Super Viewdidload];

}

-(void) Touchesbegan: (Nsset *) touches withevent: (Uievent *) event
{
[Self.filemultidownloader start];
}

@end


Customizing a base class
Copy Code code as follows:

YYFileDownloader.h file
#import <Foundation/Foundation.h>

@interface Yyfiledownloader:nsobject
{
BOOL _downloading;
}
/**
* The remote URL of the required download file (the path to connect to the server)
*/
@property (nonatomic, copy) NSString *url;
/**
* The storage path of the file (where the file is downloaded)
*/
@property (nonatomic, copy) NSString *destpath;

/**
* is downloading (there is no download, only the inside of the download to know)
*/
@property (Nonatomic, readonly, getter = isdownloading) BOOL downloading;

/**
* Used to monitor download progress
*/
@property (nonatomic, copy) void (^progresshandler) (double progress);

/**
* Start (Resume) Download
*/
-(void) start;

/**
* Suspend download
*/
-(void) pause;
@end


YYFILEDOWNLOADER.M file
Copy Code code as follows:

#import "YYFileDownloader.h"

@implementation Yyfiledownloader
@end


The download class inherits from the Yyfiledownloader class

YYFileSingDownloader.h file

Copy Code code as follows:

#import "YYFileDownloader.h"

@interface Yyfilesingledownloader:yyfiledownloader
/**
* Where to start
*/
@property (nonatomic, assign) long long begin;
/**
* End of position
*/
@property (nonatomic, assign) long long end;
@end


YYFILESINGDOWNLOADER.M file
Copy Code code as follows:

#import "YYFileSingleDownloader.h"
@interface Yyfilesingledownloader () <NSURLConnectionDataDelegate>
/**
* Connection Object
*/
@property (nonatomic, strong) nsurlconnection *conn;

/**
* File handle for writing data
*/
@property (nonatomic, strong) Nsfilehandle *writehandle;
/**
* The length of the currently downloaded data
*/
@property (nonatomic, assign) long long currentlength;
@end


Copy Code code as follows:

@implementation Yyfilesingledownloader

-(Nsfilehandle *) writehandle
{
if (!_writehandle) {
_writehandle = [Nsfilehandle FileHandleForWritingAtPath:self.destPath];
}
return _writehandle;
}

/**
* Start (Resume) Download
*/
-(void) Start
{
Nsurl *url = [Nsurl URLWithString:self.url];
The default is GET request
Nsmutableurlrequest *request = [Nsmutableurlrequest Requestwithurl:url];
Set Request header information
NSString *value = [NSString stringwithformat:@ "Bytes=%lld-%lld", Self.begin + self.currentlength, self.end];
[Request Setvalue:value forhttpheaderfield:@ "Range"];
Self.conn = [nsurlconnection connectionwithrequest:request delegate:self];

_downloading = YES;
}

/**
* Suspend download
*/
-(void) Pause
{
[Self.conn Cancel];
Self.conn = nil;

_downloading = NO;
}


#pragma mark-nsurlconnectiondatadelegate proxy method
/**
 *  1. The
 */is invoked when the response to the server (connected to the server) is received
-(void) connection: (Nsurlconnection *) connection didreceiveresponse: (nsurlresponse *) response
{
    
}

/**
 *  2. The data that is received to the server is invoked (may be invoked multiple times, and only partial data is passed each time)
 */
-(void) connection: ( Nsurlconnection *) connection didreceivedata: (NSData *) data
{
   //move to Tail of file
  & nbsp [Self.writehandle SeekToFileOffset:self.begin + self.currentlength];
   /Start writing data from the currently moving location (end of file)
    [Self.writehandle writedata:data];
 & nbsp; 
   //Cumulative length
    self.currentlength + = data.length;
  & nbsp
   //Print download Progress
    Double progress = (double) self.currentlength/(self.end-self.b Egin);
    if (self.progresshandler) {
        Self.progresshandler (progress);
   }
}

/**
* 3. When the server's data is accepted, it is called
*/
-(void) connectiondidfinishloading: (nsurlconnection *) connection
{
Empty property values
self.currentlength = 0;

Close the connection (no more data is entered into the file)
[Self.writehandle CloseFile];
Self.writehandle = nil;
}

/**
* Request error (failure) when called (Request timeout \ Disconnected network \ No network, generally refers to client error)
*/
-(void) connection: (Nsurlconnection *) connection didfailwitherror: (Nserror *) error
{

}

@end


Design multi-threaded Downloader (use Hmfilemultidownloader to open multiple threads and download a file simultaneously)

A multithreaded downloader downloads only one file

YYFileMultiDownloader.h file

Copy Code code as follows:

#import "YYFileDownloader.h"

@interface Yyfilemultidownloader:yyfiledownloader

@end


YYFILEMULTIDOWNLOADER.M file
Copy Code code as follows:

#import "YYFileMultiDownloader.h"
#import "YYFileSingleDownloader.h"

#define YYMAXDOWNLOADCOUNT 4

@interface Yyfilemultidownloader ()
@property (nonatomic, strong) Nsmutablearray *singledownloaders;
@property (nonatomic, assign) long long totallength;
@end


Copy Code code as follows:

@implementation Yyfilemultidownloader

-(void) getfilesize
{
Nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:[nsurl URLWithString:self.url]];
Request. HttpMethod = @ "Head";

Nsurlresponse *response = nil;
#warning here to use the asynchronous request
[Nsurlconnection sendsynchronousrequest:request returningresponse:&response Error:nil];
Self.totallength = Response.expectedcontentlength;
}

-(Nsmutablearray *) singledownloaders
{
if (!_singledownloaders) {
_singledownloaders = [Nsmutablearray array];

Get File size
[Self getfilesize];

The amount of downloads per path
Long long size = 0;
if (self.totallength% Yymaxdownloadcount = = 0) {
size = Self.totallength/yymaxdownloadcount;
} else {
Size = Self.totallength/yymaxdownloadcount + 1;
}

Create an n-download device
for (int i = 0; i<yymaxdownloadcount; i++) {
Yyfilesingledownloader *singledownloader = [[Yyfilesingledownloader alloc] init];
Singledownloader.url = Self.url;
Singledownloader.destpath = Self.destpath;
Singledownloader.begin = i * size;
Singledownloader.end = Singledownloader.begin + size-1;
Singledownloader.progresshandler = ^ (double progress) {
NSLog (@ "%d---%f", I, progress);
};
[_singledownloaders Addobject:singledownloader];
}

Create a temporary file that is as large as the server file
[[Nsfilemanager Defaultmanager] CreateFileAtPath:self.destPath contents:nil Attributes:nil];

Let the length of the Self.destpath file be self.totallengt
Nsfilehandle *handle = [Nsfilehandle FileHandleForWritingAtPath:self.destPath];
[Handle truncateFileAtOffset:self.totalLength];
}
return _singledownloaders;
}

/**
* Start (Resume) Download
*/
-(void) Start
{
[Self.singledownloaders makeobjectsperformselector: @selector (start)];

_downloading = YES;
}

/**
* Suspend download
*/
-(void) Pause
{
[Self.singledownloaders makeobjectsperformselector: @selector (pause)];
_downloading = NO;
}

@end


Supplemental Instructions: How do I get the size of the file that will be downloaded?

Related Article

Contact Us

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.