2009-05-10 15 views
8

मैंने मैक पर अभी विकास शुरू कर दिया है और कोको को एक उपयोगी और विचारशील रूपरेखा पाया है, लेकिन इसकी HTTP कार्यक्षमता ने मुझे परेशान किया है।समझदार प्रतिक्रिया के साथ परमाणु, एसिंक्रोनस HTTP फ़ाइल पोस्ट?

मेरे पास HTTP GET विधि का उपयोग कर मेरे वेबसर्वर से फ़ाइल डाउनलोड करने के लिए एक NSURLConnection ऑब्जेक्ट है। NSURLConnect का एसिंक्रोनस कनेक्शन बहुत अच्छा है, मुझे बहुत सारी प्रतिक्रिया मिलती है, मुझे प्रत्येक एनएनडीएटी ऑब्जेक्ट के रूप में प्राप्त किया जाता है जिसे मैं क्लाइंट एंड पर फ़ाइल को परमाणु रूप से पुनर्निर्माण करने के लिए उपयोग कर सकता हूं और, महत्वपूर्ण रूप से, उपयोगकर्ता को प्रगति रिपोर्ट के साथ प्रदान करता हूं: [myData लंबाई ]।

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

मेरा प्रश्न है, इसलिए, कोको का उपयोग करके HTTP पोस्ट फ़ाइल अपलोड के लिए एक सरल और सुरुचिपूर्ण समाधान है जो प्रतिक्रिया का एक अच्छा सौदा और फ़ाइलों को एक-दूसरे के बजाय भाग-पढ़ने के लिए क्षमता प्रदान करता है? या क्या मुझे अपनी खुद की कक्षा निम्न स्तर की नेटवर्किंग कार्यक्षमता से लिखनी चाहिए?

धन्यवाद!

+0

उन्हें अपने धागे में क्यों न जाने दें? आप यह सुनिश्चित करने के लिए एनएसओपरेशन का उपयोग कर सकते हैं कि आप निर्माण/प्रबंधन/आदि नहीं बना रहे हैं। जिन धागे की आपको आवश्यकता नहीं है। POST ऑपरेशन से आप किस तरह की डेटा फीडबैक की उम्मीद करते हैं? –

+0

अब तक अपलोड किए गए डेटा की मात्रा। मैं संभावित रूप से बड़ी फाइलों से निपट रहा हूं, इसलिए मुझे उपयोगकर्ता को प्रगति पट्टी या पसंद के साथ प्रदान करने की आवश्यकता है। थ्रेडिंग इतना मुद्दा नहीं है, फाइलों को लोड करने और प्रतिक्रिया प्राप्त करने की क्षमता अधिक है। बेतुका तेज़ उत्तर के लिए प्रॉप्स! – Dani

+0

आह, ठीक है! मैं शायद खुद को कुछ रोल करूँगा। मुझे पूरा यकीन है कि मैंने एक बार POST कार्यक्षमता के साथ NSURL के लिए एक सभ्य वर्ग देखा, लेकिन मुझे याद नहीं है कि ... शायद कोई एक सभ्य उत्तर जोड़ देगा, लेकिन आप इसे थोड़ा सा Google करना चाहेंगे। मुझे याद है कि यह मुझे खुद को खोजने के लिए थोड़ा खोद गया। –

उत्तर

2

मैंने NSURLConnection के बजाय CFNetwork फ़ंक्शंस के साथ जाने का निर्णय लिया। Async अधिसूचनाओं और विशिष्ट विशेषताओं (उदाहरण के लिए प्रमाणीकरण) में थोड़ा अधिक लचीलापन प्रतीत होता है। दुर्भाग्य से यह थोड़ा और अधिक जटिल (चलाने के उदाहरण के लिए मेरे मन झटका छोरों) है तो मैं सुझाव है कि आप CFNetwork संदर्भ गाइड को पढ़ने के लिए यदि आप यह तरीका अपनाते हैं:

http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/Introduction/Introduction.html

यहाँ मेरी पोस्ट दिनचर्या, FWIW से कोड का एक टुकड़ा है :

// Create our URL 
CFStringRef url = CFSTR("Submit"); 
CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, url, baseUrl); 

// Create the message request (POST) 
CFStringRef requestMethod = CFSTR("POST"); 
CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1); 

// Connect the read socket to the HTTP request stream 
CFReadStreamRef myReadStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, myRequest, readStream); 
// TODO: why does this have to be done? 
succ &= CFReadStreamSetClient(myReadStream, 
    kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 
    (CFReadStreamClientCallBack) &MyReadCallBack, &myClientContext); 
CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 
succ &= CFReadStreamOpen(myReadStream); 

1

दुर्भाग्य से, आप काफी सही है कि NSURLConnection यहाँ कमजोर है कर रहे हैं। सबसे लचीला दृष्टिकोण जो मैं अनुशंसा करता हूं वह CocoaAsyncSocket है। इसका मतलब है कि अपना खुद का HTTP रोल करना, जो दुर्भाग्यपूर्ण है, लेकिन ज्यादातर मामलों में यह मुश्किल नहीं है। CocoaHTTPServer दिखाता है कि CocoaAsyncSocket के शीर्ष पर एक पूर्ण HTTP सर्वर कैसे बनाया जाए, और आपकी समस्या के लिए बहुत उपयोगी कोड हो सकता है। मैंने इन दोनों को बहुत उपयोगी पाया है।

वेबकिट की जांच करने के लायक एक और दृष्टिकोण है। एक अदृश्य वेब व्यू बनाएं, और loadRequest: एक पोस्ट। मैंने अनुमान लगाया है कि अनुमानित चेंज अधिसूचना प्रणाली में अपलोड करने का समय या केवल डाउनलोड करने का समय शामिल है, लेकिन यह एक कोशिश के लायक है।

1

आप CFHTTPMessageRef के आस-पास एक साधारण ओबीजेसी रैपर के लिए my toolkit repository on github के HTTPMessage सेक्शन पर एक नज़र डाल सकते हैं; अन्य चीजों के साथ यह आपको एक एनएसआईएनपुटस्ट्रीम ऑब्जेक्ट सौंप देगा, जो आपको सादा-सी कॉलबैक फ़ंक्शंस के बारे में सोचने से बचाता है।

जो आप पढ़ रहे हैं उसके आधार पर, आप एक एक्सएमएल (और एचटीएमएल) पार्सर के लिए एक ही भंडार के स्ट्रीमिंगएक्सएमएलएसर सेक्शन पर एक नज़र डालना चाहते हैं जो आपकी ओर से सीधे एनएसआईएनपुटस्ट्रीम से डेटा का विश्लेषण करेगा।

5

आप ASIHTTPRequest ढांचे को देखना चाहते हैं। मैंने इसे अपलोड करने के लिए उपयोग नहीं किया है, लेकिन ऐसा लगता है कि इसमें अधिक प्रतिक्रिया है और उपयोग बहुत सरल है।

2

ASIHTTPRequest मूल रूप से 2.x एपीआई में, इस उद्देश्य के लिए (POST प्रगति को ट्रैक करना) के लिए डिज़ाइन किया गया था, यह NSURLConnection के साथ संभव नहीं है।सीएफनेटवर्क के साथ खुद को रोल करने से इंटीग्रेट करना निश्चित रूप से आसान होगा, और आपको कई अन्य सामान मुफ्त में मिलेंगे (उदाहरण के लिए कई अनुरोधों में प्रगति ट्रैकिंग, डाउनलोड फिर से शुरू करना आदि)। :)

यदि आपके द्वारा अपलोड की जा रही फ़ाइलें बड़ी हैं, तो डिस्क से सीधे स्ट्रीमिंग के विकल्पों को देखना सुनिश्चित करें, इसलिए आपको डेटा को स्मृति में रखना नहीं है।

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