2013-02-16 19 views
6

का उपयोग कर बड़ी छवियों को अपलोड करना मैं JSON का उपयोग कर किसी सर्वर पर एक छवि अपलोड करने के लिए इस फ़ंक्शन का उपयोग कर रहा हूं। ऐसा करने के लिए, मैं पहली बार छवि को NSData पर परिवर्तित करता हूं और फिर Base64 का उपयोग करके NSString पर परिवर्तित करता हूं। यह विधि ठीक काम करती है जब छवि बहुत बड़ी नहीं होती है, लेकिन जब मैं 2 एमबी छवि अपलोड करने का प्रयास करता हूं, तो यह क्रैश हो जाता है।बेस 64 और JSON

समस्या यह है कि सर्वर को मेरी छवि प्राप्त नहीं होती है, भले ही didReceiveResponse विधि को didReceiveData कहा जाता है जो (null) देता है। सबसे पहले मैंने सोचा कि यह एक समय मुद्दा था, लेकिन इसे 1000.0 तक भी सेट करना अभी भी काम नहीं करता है। कोई उपाय? आपके समय के लिए धन्यवाद!

- (void) imageRequest { 

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.myurltouploadimage.com/services/v1/upload.json"]]; 

    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString *path = [NSString stringWithFormat:@"%@/design%i.png",docDir, designNum]; 
    NSLog(@"%@",path); 

    NSData *imageData = UIImagePNGRepresentation([UIImage imageWithContentsOfFile:path]); 
    [Base64 initialize]; 
    NSString *imageString = [Base64 encode:imageData]; 

    NSArray *keys = [NSArray arrayWithObjects:@"design",nil]; 
    NSArray *objects = [NSArray arrayWithObjects:imageString,nil]; 
    NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; 

    NSError *error; 
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:kNilOptions error:&error]; 

    [request setHTTPMethod:@"POST"]; 
    [request setValue:[NSString stringWithFormat:@"%d",[jsonData length]] forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:jsonData]; 

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

    NSLog(@"Image uploaded"); 

} 

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

    NSLog(@"didReceiveResponse"); 

} 

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 

    NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]); 

} 
+0

आप php वेबपृष्ठ पर किसी भी लॉग जोड़ दिया है, कम से कम, यूआरएल कहा जाता है को देखने के लिए? एक फ़ाइल लॉग या एसक्यूएल लॉग की तरह? – Vinzius

+1

दरअसल, सर्वर-साइड प्रोग्रामर ने मुझे बताया कि यदि वेबसाइट को कोई डेटा प्राप्त होता है तो प्रतिक्रिया हमेशा वापस आती है। तो, मेरा निष्कर्ष यह है कि उसे अनुरोध भी प्राप्त नहीं होता है। –

+1

इसके अलावा: अक्षर का उपयोग करना चीजों को आसान/अधिक स्पष्ट बनाता है: 'NSDictionary * jsonDictionary = @ {@" design ": imageString};' – zaph

उत्तर

8

मैंने आखिरकार बेस 64 छवि को छोटे सबस्ट्रिंग में विभाजित करने का निर्णय लिया। ऐसा करने के लिए, और मुझे कई NSURLConnections की आवश्यकता थी, मैंने TagConnection नामक उप-वर्ग बनाया जो प्रत्येक कनेक्शन के लिए एक टैग देता है ताकि उनके बीच कोई संभावित भ्रम न हो।

फिर मैंने किसी भी समारोह से इसे एक्सेस करने के उद्देश्य से MyViewController में TagConnection संपत्ति बनाई। जैसा कि आप देख सकते हैं, -startAsyncLoad:withTag: फ़ंक्शन है जो TagConnection और -connection:didReceiveData: को आवंटित करता है और सर्वर से प्रतिक्रिया प्राप्त करते समय इसे हटा देता है।

-uploadImage फ़ंक्शन का जिक्र करते हुए, सबसे पहले, यह छवि को स्ट्रिंग में परिवर्तित करता है और फिर इसे विभाजित करता है और भाग को JSON अनुरोध के अंदर रखता है। इसे तब तक कहा जाता है जब तक वेरिएबल ऑफ़सेट स्ट्रिंग लम्बाई से बड़ा न हो, जिसका अर्थ है कि सभी भाग अपलोड किए गए हैं।

आप यह भी साबित कर सकते हैं कि हर बार सर्वर प्रतिक्रिया को जांचकर सफलतापूर्वक अपलोड किया गया है और सफलतापूर्वक लौटने पर -uploadImage फ़ंक्शन को कॉल कर रहा है।

मुझे आशा है कि यह एक उपयोगी उत्तर रहा है। धन्यवाद।

TagConnection.h

@interface TagConnection : NSURLConnection { 
    NSString *tag; 
} 

@property (strong, nonatomic) NSString *tag; 

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag; 

@end 

TagConnection.m

#import "TagConnection.h" 

@implementation TagConnection 

@synthesize tag; 

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag { 
    self = [super initWithRequest:request delegate:delegate startImmediately:startImmediately]; 

    if (self) { 
     self.tag = tag; 
    } 
    return self; 
} 

- (void)dealloc { 
    [tag release]; 
    [super dealloc]; 
} 

@end 

MyViewController।ज

#import "TagConnection.h" 

@interface MyViewController : UIViewController 

@property (strong, nonatomic) TagConnection *conn; 

MyViewController.m

#import "MyViewController.h" 

@interface MyViewController() 

@end 

@synthesize conn; 

bool stopSending = NO; 
int chunkNum = 1; 
int offset = 0; 

- (IBAction) uploadImageButton:(id)sender { 

    [self uploadImage]; 

} 

- (void) startAsyncLoad:(NSMutableURLRequest *)request withTag:(NSString *)tag { 

    self.conn = [[[TagConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:tag] autorelease]; 

} 

- (void) uploadImage { 

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.mywebpage.com/upload.json"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1000.0]; 

    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString *path = [NSString stringWithFormat:@"%@/design%i.png", docDir, designNum]; 
    NSLog(@"%@",path); 

    NSData *imageData = UIImagePNGRepresentation([UIImage imageWithContentsOfFile:path]); 
    [Base64 initialize]; 
    NSString *imageString = [Base64 encode:imageData]; 

    NSUInteger length = [imageString length]; 
    NSUInteger chunkSize = 1000; 

    NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset; 
    NSString *chunk = [imageString substringWithRange:NSMakeRange(offset, thisChunkSize)]; 
    offset += thisChunkSize; 

    NSArray *keys = [NSArray arrayWithObjects:@"design",@"design_id",@"fragment_id",nil]; 
    NSArray *objects = [NSArray arrayWithObjects:chunk,@"design_id",[NSString stringWithFormat:@"%i", chunkNum],nil]; 
    NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; 

    NSError *error; 
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:kNilOptions error:&error]; 

    [request setHTTPMethod:@"POST"]; 
    [request setValue:[NSString stringWithFormat:@"%d",[jsonData length]] forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:jsonData]; 

    [self startAsyncLoad:request withTag:[NSString stringWithFormat:@"tag%i",chunkNum]]; 

    if (offset > length) { 
     stopSending = YES; 
    } 

} 

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 

    NSError *error; 
    NSArray *responseData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
    if (!responseData) { 
     NSLog(@"Error parsing JSON: %@", error); 
    } else { 
     if (stopSending == NO) { 
      chunkNum++; 
      [self.conn cancel]; 
      self.conn = nil; 
      [self uploadImage]; 
     } else { 
      NSLog(@"---------Image sent---------"); 
     } 
    } 

} 

@end 
+1

क्या आप सर्वर साइड कोड के लिए भी मदद कर सकते हैं? मैं php पक्ष में ऐसा करने में असमर्थ हूं! –

+0

मुझे खेद है लेकिन यह मेरे ऊपर नहीं है। –

2

कृपया नहीं लगता है कि यह अंतिम विकल्प है, यह सिर्फ मेरी अवलोकन है:

यहाँ मेरे वर्तमान कोड है।

मुझे लगता है कि आपको पूर्ण डेटा की बजाय भाग में उस NSData को भेजना चाहिए। मैंने यूट्यूब वीडियो अपलोडिंग मामले में ऐसी पद्धति देखी है। वे कई एनएसडीटा के चंक्स में एनएसडीटा (वीडियो फाइल का एनएसडीटा) का बड़ा सेट भेजते हैं।

वे बड़े डेटा को अपलोड करने के लिए समान कार्यप्रणाली का उपयोग करते हैं।

तो यूट्यूब डेटा अपलोडिंग एपीआई के बारे में Google को करना चाहिए। और आपको उस विधि को खोजना चाहिए, यूट्यूब अपलोडर उपयोग करता है।

मुझे उम्मीद है कि यह आपकी मदद कर सकता है।

+0

ऐसा कुछ ?: http://stackoverflow.com/questions/2899020/split-nsdata-objects-into-other-nsdata-objects-with-a-given-size –

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