2013-03-23 6 views
10

मुझे 5 एमबी फ़ाइल डाउनलोड करने में समस्या का सामना करना पड़ रहा है, आईओएस 6.1 के साथ आईफोन 5 पर 2 मिनट लगते हैं।NSURLConnection बहुत लंबे समय से डाउनलोड

आईओएस 4 एस का उपयोग उसी आईओएस संस्करण के साथ करते हुए इसमें केवल 10 सेकंड लगते हैं, दोनों वाईफाई का उपयोग कर रहे हैं।

मैंने NSRLRequest के विभिन्न कैश नीति और टाइमआउट अंतराल की कोशिश की है, यह कुछ भी नहीं बदला है, यह अभी भी काफी समय ले रहा है। डाउनलोड HTTP से अधिक है।

मैं NSURLConnection कक्षा का उपयोग कर रहा हूं, इस "बड़ी" फ़ाइल को डाउनलोड करने से पहले मैं दो अन्य डाउनलोड कर रहा हूं।

पता नहीं कि समय कम करने के लिए और क्या महत्वपूर्ण हो सकता है।

अग्रिम धन्यवाद।

कोड:

@interface MyClass : NSObject <NSURLConnectionDelegate> 
{ 
    @private id delegate; 
    NSURLConnection *connection; 
    NSMutableData* responseData; 
    //... 
} 


#import "MyClass.h" 

@implementation MyClass 

-(void)getObj1:(id)delegateObj 
{ 
    delegate = delegateObj; 

    NSString *url = @"..."; 

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:120.0]; 

    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

    if(connection) 
    { 
     responseData = [NSMutableData data]; 
    } 
} 

-(void)getObj2:(*String)somesString 
{ 

    NSString *url = @"..."; 

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:120.0]; 

    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

    if(connection) 
    { 
    responseData = [NSMutableData data]; 
    } 
} 

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    //.... 
} 


-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [responseData appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    if(firstRequest) 
    { 
     //save data from first request and set responseData clear 
     [self getObj2:@"..."]; 
    } 
} 

और कुछ विशेष के बिना अन्य लोगों, मुझे आशा है कि यह पर्याप्त

हो जाएगा मैं इस पोस्ट https://devforums.apple.com/message/754875#754875 पाया है, लेकिन अभी भी मेरे लिए ठीक काम नहीं करता। हालांकि अब मैं इस अजीब स्थिति को बेहतर ढंग से समझता हूं।

+0

आपका कोड महत्वपूर्ण है। यदि आप पोस्ट बना सकते हैं और अनुरोध कैसे शुरू कर सकते हैं, और प्रतिनिधि विधियां पोस्ट कर सकते हैं। –

+0

कोई विचार? हो सकता है कि मेरे संपादन से यह लिंक मदद करेगा, मैं विचारों से बाहर हूं – Meryl

+0

_two_ अलग-अलग डाउनलोड करने के लिए आपको अपने 'MyClass' की _two_ ऑब्जेक्ट्स बनाना चाहिए। आप जल्दी से इवर को भ्रमित कर सकते हैं। साथ ही, सुनिश्चित करें कि आप उस थ्रेड पर [[NSURLConnection alloc] init ...] को आमंत्रित करते हैं जहां आप प्रतिनिधि को निष्पादित करना चाहते हैं। संभवतः मुख्य धागा - अन्यथा आपको यह जानने की आवश्यकता है कि उस उद्देश्य के लिए द्वितीयक धागा कैसे सेट करें, जो थोड़ा मुश्किल है। – CouchDeveloper

उत्तर

0

क्या आपने AFNetworking को आजमाया है? यह NSURLConnection पर एक रैपर है। मुझे यकीन नहीं है कि यह आपको तेजी से डाउनलोड करने में मदद करेगा, लेकिन यह आपको NSURLConnection पर बढ़त देता है।

+0

इस विषय के आधार पर http://stackoverflow.com/questions/12570483/ios6-large-downloads-time-out?rq=1 मुझे लगता है कि यह मदद नहीं करेगा लेकिन मैं इसे अगले चरण में जांचने जा रहा हूं। उत्तर के लिए धन्यवाद। – Meryl

+0

मैंने कोशिश की है लेकिन यह अभी भी एक ही समय लेता है – Meryl

1

AFDownloadRequestOperation (AFNetworking "sublass") का उपयोग करें - आप ऑपरेशन रोक/फिर से शुरू कर सकते हैं।

यहाँ आप एक उदाहरण https://stackoverflow.com/a/12209618

+0

मेरे पास कोई एआरसी प्रोजेक्ट नहीं है और मुझे इस कक्षा – Meryl

0

आप सर्वर या सर्वर प्रतिक्रिया प्राप्त करने से डेटा डाउनलोड करने के लिए NSURLRequest अनुरोध के सेट पर अमल करने क़तार dispatch_async GCD इस्तेमाल किया है।

NSString *webURL = @"http://therealurl.appspot.com/?format=json&url=bit.ly/a"; 
NSURL *url = [NSURL URLWithString:webURL]; 
NSURLRequest *awesomeRequest = [NSURLRequest requestWithURL:url]; 
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:awesomeRequest delegate:self]; 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); 
dispatch_async(queue, ^{ 
    NSRunLoop *loop=[NSRunLoop currentRunLoop]; 
    [connection scheduleInRunLoop:loop forMode:NSRunLoopCommonModes]; 
    //[self processTheAwesomeness]; 
}); 
+1

के साथ कुछ समस्याएं हैं, एक कनेक्शन को 'शेड्यूल इनरुन लूप: फॉरमोड:' के माध्यम से निर्धारित नहीं किया जाना चाहिए, एक प्रेषण कतार में अपना रन लूप प्राप्त करने का प्रयास कर रहा है । यह काम नहीं करेगा क्योंकि रन लूप किसी भी समय गायब हो सकता है (यदि कोई भी लाभ उठाता है) और अंडरलेइंग थ्रेड किसी भी समय प्रतिनिधि से प्रतिनिधि को बदल सकता है। – CouchDeveloper

+0

उसने क्या कहा। यदि आप इस तरह के अपने शेड्यूलिंग को संभालना चाहते हैं और इसे मुख्य थ्रेड से दूर रखना चाहते हैं, तो आपको पृष्ठभूमि थ्रेड स्वयं को स्पॉन (और प्रबंधित) करने की आवश्यकता है। उस ने कहा, एक ही हस्तांतरण के मामले में, मुख्य धागे पर कोई अन्य महत्वपूर्ण गतिविधि नहीं होने के कारण, मुख्य धागे पर इसे निर्धारित करने का कोई कारण नहीं होगा। – ipmcc

0

मुझे यकीन नहीं है कि आपकी समस्या क्या है, लेकिन निम्न कोड मेरे लिए विश्वसनीय रूप से काम करता है।

- (id)init 
{ 
    self.downloadQueue = [[NSOperationQueue alloc] init]; 
    [self.downloadQueue setMaxConcurrentOperationCount:1]; 
} 

- (void)doDownload:(NSURL *)url 
{ 
    [self.downloadQueue addOperation:[NSBlockOperation blockOperationWithBlock:^{ 

    NSData *data =[NSData dataWithContentsOfURL:url]; 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     NSAutoreleasePool *mainQueuePool = [[NSAutoreleasePool alloc] init]; 

     ... update user interface ... 

     [mainQueuePool release]; 
    }); 

    }]]; 
} 
-1

मुझे लगता है कि यह आपके डिवाइस में एक समस्या है। किसी मित्र से एक और डिवाइस आज़माएं।

0

मैं एक समाधान का प्रस्ताव दूंगा जहां आपके पास किसी प्रकार का संचार प्रबंधक है जिसमें NSOperationQueue है, यह एक एकल प्रविष्टि बिंदु विधि के साथ हैंडल करता है जहां आप इसे एक यूआरएल देते हैं जहां सामग्री आप डाउनलोड करना चाहते हैं और सफलता और एक विफलता ब्लॉक। संचार प्रबंधक NSOperation बनाता है जहां आप NSURLRequest बनाते हैं और कॉलबैक को संभालते हैं।

जैसे ही कम्युनिकेशन मैनेजर कतार में ऑपरेशन डालता है, इसकी start विधि कहा जाता है। मेरे संचार प्रबंधक कार्यान्वयन में मैं NSMutableDictionary के माध्यम से प्रत्येक प्रारंभिक ऑपरेशन के ट्रैक ((कतार में ऑपरेशन डालने के अलावा) ट्रैक करता हूं ताकि आप एक या सभी ऑपरेशंस को रद्द कर सकें (इस उद्देश्य के लिए operationKey प्रदान किए गए नमूना कोड में। JSONOperation रिटर्न (सफलता के मामले में) संचारक के लिए एक एनएसएसटींग लेकिन यह किसी भी प्रकार का डेटा भी हो सकता है, उदाहरण के लिए मैं छवियों को डाउनलोड करने के लिए एक ही कक्षा का उपयोग करता हूं, इसलिए मैं डेटा ऑब्जेक्ट को वापस भेज दूंगा। नीचे आप पा सकते हैं एक उदाहरण के रूप में मेरा JSONOperation वर्ग।मुझे यह विचार पसंद है कि मैं अन्य फाइलों को जिस्ट पर रख सकता हूं।

मेरे NSOperation लग रहा है इस

@interface JSONOperation : NSOperation <NSURLConnectionDataDelegate, OperationDelegate> 
    + (instancetype)jsonOperationForProvider:(id)provider success:(OperationSuccessWithString)success failure:(OperationFailure)failure; 
@end 

#import "JSONOperation.h" 
#import "ProviderDelegate.h" 

@interface JSONOperation() 
@property (nonatomic, assign) BOOL executing; 
@property (nonatomic, assign) BOOL finished; 
@property (nonatomic, assign) BOOL cancelled; 

@property (nonatomic, strong) NSURL *url; 

@property (nonatomic, weak) id <ProviderDelegate> delegate; 
@property (nonatomic, strong) NSURLConnection *connection; 
@property (nonatomic, strong) NSMutableData *receivedData; 

@property (nonatomic, copy) OperationFailure failure; 
@property (nonatomic, copy) OperationSuccessWithString success; 
@end 

@implementation JSONOperation 

- (void)start 
{ 
    if ([self isCancelled]) 
{ 
    [self willChangeValueForKey:@"isFinished"]; 
    _finished = YES; 
    [self didChangeValueForKey:@"isFinished"]; 

    return; 
} 

    NSURLRequest *request = [NSURLRequest requestWithURL:self.url]; 
    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
    [self.connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 
    [self.connection start]; 

    [self willChangeValueForKey:@"isExecuting"]; 
    _executing = YES; 
    [self didChangeValueForKey:@"isExecuting"]; 
} 

- (NSMutableData *)receivedData 
{ 
    if (nil == _receivedData) { 
     _receivedData = [NSMutableData data]; 
    } 
    return _receivedData; 
} 

+ (instancetype)jsonOperationForProvider:(id <ProviderDelegate>)provider success:(OperationSuccessWithString)success failure:(OperationFailure)failure 
{ 
    NSAssert(nil != provider, @"provider parameter can't be nil"); 

    JSONOperation *operation = [[[self class] alloc] init]; 
    operation.delegate = provider; 
    operation.url = provider.contentURL; 
    operation.failure = failure; 
    operation.success = success; 

    return operation; 
} 

- (BOOL)isConcurrent { 
    return YES; 
} 

- (BOOL)isExecuting { 
    return _executing; 
} 

- (BOOL)isFinished { 
    return _finished; 
} 

- (BOOL)isCancelled { 
    return _cancelled; 
} 

#pragma mark - NSURLConnectionDataDelegate 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 

    if (_success) { 
     NSString *receivedText = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding]; 
     _receivedData = nil; 

     self.success(self, receivedText); 
    } 

    [self willChangeValueForKey:@"isFinished"]; 
    [self willChangeValueForKey:@"isExecuting"]; 

    _executing = NO; 
    _finished = YES; 

    [self didChangeValueForKey:@"isExecuting"]; 
    [self didChangeValueForKey:@"isFinished"]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [self.receivedData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    [connection cancel]; 
    _connection = nil; 
    _receivedData = nil; 
    _url = nil; 

    if (_failure) { 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      self.failure(self, error); 
    }]; 
    } 

    [self willChangeValueForKey:@"isFinished"]; 
    [self willChangeValueForKey:@"isExecuting"]; 

    _executing = NO; 
    _finished = YES; 

    [self didChangeValueForKey:@"isExecuting"]; 
    [self didChangeValueForKey:@"isFinished"]; 
} 

#pragma mark - OperationDelegate 

- (NSString *)operationKey 
{ 
    return [self.url absoluteString]; 
} 

- (id)provider 
{ 
    return _delegate; 
} 

- (void)cancelOperation 
{ 
    _failure = nil; 
    _success = nil; 

    [self.connection cancel]; 
    _connection = nil; 

    _receivedData = nil; 
    _url = nil; 

    [self willChangeValueForKey:@"isCancelled"]; 
    [self willChangeValueForKey:@"isFinished"]; 
    [self willChangeValueForKey:@"isExecuting"]; 

    _executing = NO; 
    _finished = YES; 
    _cancelled = YES; 

    [self didChangeValueForKey:@"isCancelled"]; 
    [self didChangeValueForKey:@"isExecuting"]; 
    [self didChangeValueForKey:@"isFinished"]; 
} 

@end 

संपादित की तरह - Gist Sample files

0
मेरे अनुभव AFNetworking में अच्छी

करता downloads.I से निपटने में एक awsome काम 10+ साथ फाइलों पर एक डाउनलोड आपरेशन उपयोग कर रहा हूँ एमबी आकार। इसलिए मैं दृढ़ता से इसका उपयोग करने का सुझाव देता हूं।

My answer on stack to show progressbar .See जवाब मैं कहाँ दोनों तरीकों को लागू AFNetworking और NSUrlconnection साथ है.आप दोनों तरीकों से कोशिश कर सकते हैं और प्रगति देख सकते हैं और यदि आप ऐसा आप कर सकते हैं यह संख्या ट्रैक करने बाइट्स प्रत्येक packet.By में डाउनलोड करने के गणना कर सकते हैं विश्लेषण करें कि यह डाउनलोड समय में कैसे भिन्न होता है। इसे आजमाएं

+0

@ मेरिल: इसे आज़माएं और जानें कि यह कैसे चला गया –

0

NSURLRequest के लिए दूरस्थ फ़ाइल को संपीड़ित करने के लिए बस gzip का उपयोग करने का प्रयास करें। यह नाटकीय रूप से आपके कनेक्शन को तेज करेगा।

इसका उपयोग करने के लिए, आपको इसे सर्वर पर स्थापित करने की आवश्यकता है, और अच्छी खबर यह है कि यदि आप अपने सर्वर पर apache2 का उपयोग कर रहे हैं, तो यह डिफ़ॉल्ट रूप से आता है। http://www.feedthebot.com/tools/gzip/

अगर जवाब हाँ है, Xcode में अपने ऑब्जेक्टिव-सी कोड में कोड जोड़ना आगे बढ़ना: अपने सर्वर/यूआरएल gzip संपीड़न सक्षम था सुनिश्चित करने के लिए, इस ऑनलाइन उपकरण के साथ यह परीक्षण परीक्षण करने के लिए। अपने कोड में इस लाइन के बाद:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:120.0]; 

सिर्फ इस जोड़ें:

// Create a mutable copy of the immutable request and add more headers 
NSMutableURLRequest *mutableRequest = [request mutableCopy]; 

//add gzip compression 
[mutableRequest addValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"]; 

// Now set our request variable with an (immutable) copy of the altered request 
request = [mutableRequest copy]; 

यह काफ़ी अपनी प्रतिक्रिया समय में तेजी लाने जाएगा, और यदि आप एक छोटे NSURLRequest या NSURLConnection कार्य के लिए AFNetworking उपयोग करने की आवश्यकता नहीं है।

संबंधित मुद्दे