2011-07-06 12 views
21

मुझे आईओएस एप्लिकेशन में पृष्ठभूमि में चलाने के लिए वीओआईपी सॉकेट मिल रहा है।आईओएस वीओआईपी सॉकेट पृष्ठभूमि में नहीं चलाएगा

मेरा कनेक्शन ठीक काम करता है, लेकिन जब मेरा ऐप पृष्ठभूमि में जाता है तो यह जाग नहीं जाएगा। यदि मैं ऐप बैक अप खोलता हूं, हालांकि, यह सोते समय प्राप्त होने वाले किसी भी संदेश का जवाब देता है।

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, 
            (CFStringRef) @"test.iusealocaltestserver.com", 
            5060, 
            &myReadStream, 
            &myWriteStream); 
CFReadStreamSetProperty ( myReadStream, 
          kCFStreamNetworkServiceType, 
          kCFStreamNetworkServiceTypeVoIP 
          ); 

CFSocketNativeHandle native; 
CFDataRef nativeProp = CFReadStreamCopyProperty(myReadStream, kCFStreamPropertySocketNativeHandle); 

CFDataGetBytes(nativeProp, CFRangeMake(0, CFDataGetLength(nativeProp)), (UInt8 *)&native); 
CFRelease(nativeProp); 

CFSocketRef theSocket = CFSocketCreateWithNative(kCFAllocatorDefault, native, 0, NULL, NULL); 

CFSocketGetContext(theSocket,&theContext);  


CFOptionFlags readStreamEvents = kCFStreamEventHasBytesAvailable | 
kCFStreamEventErrorOccurred  | 
kCFStreamEventEndEncountered | 
kCFStreamEventOpenCompleted; 

CFReadStreamSetClient(myReadStream, 
          readStreamEvents, 
          (CFReadStreamClientCallBack)&MyCFReadStreamCallback, 
         (CFStreamClientContext *)(&theContext)); 

CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetCurrent(), 
           kCFRunLoopCommonModes); 

तब मेरे कॉलबैक इस तरह की स्थापना की है:

static void MyCFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void *pInfo); 

static void MyCFReadStreamCallback (CFReadStreamRef stream, CFStreamEventType type, void *pInfo) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSLog(@"Callback Happened"); 

    [pool release]; 
} 

"कॉलबैक हुआ" और जब मैं डेटा प्राप्त बुलाया जा रहा है अनुप्रयोग है

मैं इस तरह मेरी धारा की स्थापना खुला है, लेकिन ऐसा नहीं होता है कि ऐप कम हो गया है। जब ऐप बैक अप आता है, हालांकि, यह कम से कम प्राप्त होने वाले किसी भी डेटा को संसाधित करता है।

मैंने info.plist पर वीओआईपी टैग जोड़ा। मेरा CFReadStreamSetProperty सच हो जाता है। मैं एक डिवाइस पर चल रहा हूं सिम्युलेटर नहीं। हालांकि यह अभी भी काम नहीं करता है, इसलिए मुझे नहीं पता कि मेरी समस्या क्या हो सकती है। मैंने शायद कुछ मूर्खतापूर्ण किया है, लेकिन मेरे कोड को जांचने के लिए ऑनलाइन कुछ भी नहीं है।

संपादित करें: मैं किसी भी उत्तर का परीक्षण नहीं कर सकता क्योंकि अब मैं इस परियोजना पर काम नहीं कर रहा हूं और मैक/आईओएस एसडीके तक पहुंच नहीं है। अगर किसी ऐसी समस्या वाले किसी व्यक्ति को नीचे दिए गए उत्तरों में से एक उपयोगी पाया गया है, तो मुझे बताएं और मैं इसे सबसे अच्छा जवाब दूंगा।

+0

+1: क्या आपने प्लेस्ट में "ऑडियो" टैग भी जोड़ा था? मैं बस मल्टीटास्किंग के बारे में एप्लिकेशन प्रोग्रामिंग गाइड से पढ़ रहा हूं लेकिन ऐसा लगता है कि यह अनियमित है। आशा है कि आपको जवाब मिलेगा। अच्छा प्रश्न। –

+0

मैं कोई ऑडियो नहीं चला रहा हूं (अभी तक) ताकि इससे कोई फर्क नहीं पड़ता। लेकिन मैंने वैसे भी कोशिश की और यह काम नहीं किया। कम से कम मुझे कोशिश करने के लिए कुछ देने के लिए धन्यवाद, मैं बस अपने सिर को घंटों तक तोड़ रहा हूं। – Joel

+0

क्या आप लाइव टाइमआउट हैंडलर को रखने के लिए कोड पोस्ट कर सकते हैं? –

उत्तर

28

आप पृष्ठभूमि में अपने वीओआइपी आवेदन चलने देने के लिए चाहते हैं, plist फ़ाइल में उन लोगों के आधार सेटिंग्स को छोड़कर, आप TCP सॉकेट कौन है संपत्ति वीओआइपी को स्थापित करना है, की तुलना में आईओएस प्रणाली आप के लिए देखभाल इस सॉकेट ले जाएगा , जब आपका एप्लिकेशन पृष्ठभूमि में प्रवेश करता है, तो टीसीपी सॉकेट को छोड़कर हर चीज 'नींद' थी। और यदि वीओआईपी सर्वर कुछ डेटा भेजता है तो टीसीपी सॉकेट, आपका आवेदन 10 सेकंड के लिए जाग जाएगा। इस समय के दौरान, आप एक स्थानीय अधिसूचना पोस्ट कर सकते हैं।

केवल टीसीपी सॉकेट वीओआईपी सॉकेट के रूप में सेट किया जा सकता है। लेकिन मुझे पता है, ज्यादातर वीओआईपी आवेदन यूडीपी सॉकेट पर आधारित हैं। यदि आप डेटा सॉकेट से नियंत्रण सॉकेट को अलग नहीं करना चाहते हैं। आपको एक और टीसीपी सॉकेट बनाना चाहिए जो आपके आवेदन को 'जागृत' पर केंद्रित है, और मेरे व्यक्तिगत अनुभव से, यह 'जागृत' सिग्नल रखना और वास्तविक सिप नियंत्रण सिग्नल सिंक्रनाइज़ करना बहुत मुश्किल है, एप्लिकेशन हमेशा सिप आमंत्रण अनुरोध को याद करता है।

तो, सबसे अच्छा तरीका यूपीपी डेटा सॉकेट से सिप कंट्रोल सिंगल को अलग कर रहा है, इसे टीसीपी सॉकेट के रूप में बनाएं, यह सबसे अच्छा समाधान है, लेकिन ध्वनि डेटा स्थानांतरित करने के लिए टीसीपी सॉकेट का कभी भी उपयोग नहीं करें।

एक और गंदा तरीका: एप्लिकेशन को हर समय जागृत रखें। जैसा कि मैंने कहा था, प्रत्येक टीसीपी एकल आवेदन प्राप्त हुआ था कि 'वीओआईपी' टीसीपी सॉकेट, 10 सेकंड के लिए आवेदन जागृत रखेगा, इसलिए इस अवधि के अंत में (9 सेकेंड के बाद), आप पूछने के लिए सर्वर को प्रतिक्रिया भेज सकते हैं एक और सिग्नल के लिए, जब अगला सिग्नल आया, तो आवेदन 9 सेकंड के बाद फिर से जाग जाएगा, प्रतिक्रिया दोबारा भेजें। ऐसा करते रहें, आपका आवेदन हमेशा के लिए जाग जाएगा।

+11

सुनहरा ज्ञान –

+0

@ जोएल: क्या आप वॉयस डेटा प्राप्त करने में सक्षम हैं, जबकि ऐप बैकग्रो में चल रहा है und। यदि यह पोस्ट उपयोगी है तो कृपया यहां अपडेट करें और किसी भी पोस्ट को स्वीकार करें। – User97693321

+0

मुझे यकीन नहीं है कि 'पृष्ठभूमि में' क्या मतलब है, यदि ऐप पूरी तरह से पृष्ठभूमि में है (कॉल में नहीं), केवल टीसीपी डेटा प्राप्त किया जा सकता है। –

0

आपको Info.plist में <key>UIBackgroundModes</key><array><string>audio</string></array> सेट करने की आवश्यकता हो सकती है, और आपको यह सुनिश्चित करने की आवश्यकता है कि ऑडियो सत्र सक्रिय/चल रहा है/ऐप्स स्विच करने से पहले जो भी हो (धारणा यह है कि आप अचानक रिकॉर्डिंग/संगीत बजाना शुरू नहीं करेंगे/जो भी आपका ऐप पृष्ठभूमि में है)।

The docs कहता है कि "ऑडियो" आपको पृष्ठभूमि में ऑडियो चलाने देता है, लेकिन संभवतः यह रिकॉर्डिंग ऑडियो पर भी लागू होता है। यदि यह काम नहीं करता है, तो कुछ चीजें हैं जो आप कोशिश कर सकते हैं:

  • दोनों "voip" और "ऑडियो" सेट करें।
  • मौन प्ले करें (यह ऑडियो कतार API के साथ करना सबसे आसान हो सकता है)।
+0

मौन बजाना ऐप्पल द्वारा पता चला एक चाल है जो ऐप को स्टोर पर प्रकाशित होने से रोकता है (जब तक ऐप वास्तविक ऑडियो सुविधा प्रदान नहीं करता) – Albrecht

+0

एक VIOP सॉकेट वास्तविक ऑडियो सुविधा होगी, है ना? क्या आपके पास कोई सबूत है इस अस्वीकृति के बारे में? मैंने कभी भी कुछ भी नहीं देखा है। – Sneakyness

+0

इस धागे पर पहले उत्तर से http://stackoverflow.com/questions/5840365/how-can-an-ios-app-keep-a-tcp-connection -अलीव-अनिश्चित काल-जबकि-इन-द-बैकग्रो में ऐप्पल द्वारा चुप ऑडियो खेलने के लिए अस्वीकार किए जाने वाले ऐप की कहानी है: https://web.archive.org/web/20140806111426/http://tapbots.com/blog/पेस्टबॉट/पेस्टबॉट-संगीत-इन-बैकग्राउंड – RenniePet

5

मैं एक ही परिदृश्य के साथ अटक गया था।
मेरी समस्या यह थी कि मैंने एक वीओआईपी सॉकेट के रूप में एक सॉकेट से कॉन्फ़िगर किया है।

आप Apple's documentations about voip पर देख सकते हैं कि वे कहते हैं:

मुझे लगता है कि वे केवल एक ही सॉकेट के अनुसार आपके ऐप्स जाग रहे "वीओआईपी के उपयोग के लिए आवेदन के सॉकेट की एक कॉन्फ़िगर करें"।

अन्य सभी सामान उल्लेख अभी भी सही है:

  • kCFStreamNetworkServiceTypeVoIP
  • 'Info.plist' UIBackgroundModes: वीओआईपी, ऑडियो
  • 'जानकारी।plist 'UIRequiresPersistentWifi कुंजी
  • सिम्युलेटर
0

से अधिक कार्य नहीं करेगा आप अपने आवेदन प्रतिनिधि में एक 'applicationDidEnterBackground:' है। मुझे पूरा यकीन है कि मैंने कहीं पढ़ा है (जो मुझे नहीं मिल रहा है), कि आपको आईओएस के लिए यह परिभाषित करने की आवश्यकता है कि आप पृष्ठभूमि मोड का समर्थन करते हैं। आपको इसमें कुछ भी लागू करने की आवश्यकता नहीं है।

उदा।

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
} 
+0

यह यूआईपीप्लिकेशन डिलेगेट प्रोटोकॉल से सिर्फ एक विधि है। यह वैकल्पिक और इस प्रश्न से असंबंधित है। – gurooj

3

मुझे भी एक ही समस्या का सामना करना पड़ रहा है। लेकिन मेरे मामले में सब कुछ ठीक काम कर रहा है, जब तक कि नेटवर्क में परिवर्तन न हो। मैंने नेटवर्क परिवर्तनों का पता लगाने के लिए सेब "पहुंचने योग्यता" वर्ग का उपयोग किया। यदि ऐप पृष्ठभूमि में है तो मेरी सॉकेट काम कर रही है भले ही मैंने मैन्युअल रूप से निम्नलिखित के लिए अपना नेटवर्क स्विच किया हो।

  1. वाईफ़ाई -> 3 जी
  2. 3g -> वाईफ़ाई

कुछ समय के बाद, कहते हैं कि फिर से मैन्युअल रूप से कोशिश कर नेटवर्क स्विच im करते हैं। कुछ भी खुश नहीं है ऐसा लगता है कि मेरा ऐप नेटवर्क परिवर्तनों का पता नहीं लगा रहा है। मैंने नीचे सेब दस्तावेज़ पढ़ा।

1. यदि आपके ऐप की Info.plist फ़ाइल के लिए UIBackgroundModes कुंजी जोड़ें: मुझे यकीन है कि गलत (या) disunderstood चरण 3 और 6

कर एक वीओआईपी एप्लिकेशन को लागू करने के लिए कई आवश्यकताएं हैं हूँ। इस कुंजी का मान उस सरणी में सेट करें जिसमें वीओआईपी स्ट्रिंग शामिल है।

  1. कॉन्फ़िगर वीओआईपी उपयोग के लिए एप्लिकेशन की सॉकेट में से एक।

  2. पृष्ठभूमि में जाने से पहले, setKeepAliveTimeout: हैंडलर: समय-समय पर निष्पादित करने के लिए एक हैंडलर स्थापित करने के लिए विधि को कॉल करें।आपका ऐप इस सेवा कनेक्शन को बनाए रखने के लिए इस हैंडलर का उपयोग कर सकता है।

  3. सक्रिय उपयोग से और उससे संक्रमण को संभालने के लिए अपने ऑडियो सत्र को कॉन्फ़िगर करें।

5. iPhone पर एक बेहतर उपयोगकर्ता अनुभव सुनिश्चित करने, कोशिका आधारित फोन कॉल के संबंध में आपके व्यवहार को समायोजित करने के लिए कोर टेलीफोनी ढांचे का उपयोग; कोर टेलीफोनी फ्रेमवर्क संदर्भ देखें।

  1. अपने वीओआईपी अनुप्रयोग के लिए अच्छा प्रदर्शन को सुनिश्चित करने के लिए, नेटवर्क परिवर्तन का पता लगाने और अपने अनुप्रयोग जितना संभव हो उतना सोने के लिए अनुमति देने के लिए सिस्टम विन्यास ढांचे का उपयोग।
+0

मुझे एक ही समस्या का सामना करना पड़ रहा है। क्या आपको नेटवर्क परिवर्तन पर कॉलबैक न मिलने का कोई कारण मिला? मुझे लगता है कि जब ऐप पृष्ठभूमि में जाता है, तो आईओएस निलंबित राज्य में ऐप डालता है, यही कारण है कि ऐप नेटवर्क परिवर्तन का पता नहीं लगा सकता है। –