2013-02-21 40 views
25

जब मेरा ऐप आईफोन पर चलता है तो यह एक बग है लेकिन सिम्युलेटर पर नहीं चलता है। मैं/दस्तावेज़ में फ़ाइल के सापेक्ष पथ निकालने के लिए होम निर्देशिका पथ की लंबाई का उपयोग कर रहा था। दुर्भाग्य से यह हमेशा आईफोन पर सही ढंग से काम नहीं करता है क्योंकि उपसर्ग "/ निजी" को होम पथ में जोड़ा जा रहा है। हालांकि, उपसर्ग के साथ या उसके बिना, एक ही फ़ाइल का संदर्भ ठीक है। निम्नलिखित कोड इस असंगतता को दर्शाता है। "/ निजी" का उद्देश्य क्या है और इसे आईओएस द्वारा कब प्रदान किया जाता है?आईओएस फ़ाइल पथ पर/निजी उपसर्ग क्या इंगित करता है?

- (IBAction)testHomepath:(id)sender { 
    NSFileManager *fmgr = [NSFileManager defaultManager]; 
    NSString *homePath = [NSString stringWithFormat:@"%@/Documents",NSHomeDirectory()]; 
    NSString *dirPath = [homePath stringByAppendingPathComponent:@"TempDir"]; 
    NSURL  *dirURL = [NSURL fileURLWithPath:dirPath]; 
    NSString *filePath = [dirPath stringByAppendingPathComponent:@"test.jpg"]; 
    [fmgr createDirectoryAtPath:dirPath withIntermediateDirectories:NO attributes:nil error:nil]; 
    [fmgr createFileAtPath:filePath contents:nil attributes:nil]; 
    NSArray *keys = [[NSArray alloc] initWithObjects:NSURLNameKey,nil]; 
    NSArray *files = [fmgr contentsOfDirectoryAtURL:dirURL includingPropertiesForKeys:keys options:0 error:nil]; 
    NSURL *f1 = (files.count>0)? [files objectAtIndex:0] : 0; 
    NSURL *f2 = (files.count>1)? [files objectAtIndex:1] : 0; 
    bool b0 = [fmgr fileExistsAtPath:filePath]; 
    bool b1 = [fmgr fileExistsAtPath:f1.path]; 
    bool b2 = [fmgr fileExistsAtPath:f2.path]; 

    NSLog(@"File exists=%d at path:%@",b0,filePath); 
    NSLog(@"File exists=%d at path:%@",b1,f1.path); 
    NSLog(@"File exists=%d at path:%@",b2,f2.path); 
} 

आईफोन पर चलते समय लॉग में लिखा गया है। मैं मैन्युअल रूप से उत्पादन से स्थान दिया गया लाइन 1 और 2.

2013-02-20 16:31:26.615 Test1[4059:907] File exists=1 at path:  /var/mobile/Applications/558B5D82-ACEB-457D-8A70-E6E00DB3A484/Documents/TempDir/test.jpg 
2013-02-20 16:31:26.622 Test1[4059:907] File exists=1 at path:/private/var/mobile/Applications/558B5D82-ACEB-457D-8A70-E6E00DB3A484/Documents/TempDir/test.jpg 
2013-02-20 16:31:26.628 Test1[4059:907] File exists=0 at path:(null) 

के बीच अंतर को दिखाने के लिए निम्नलिखित जब (कोई "/ निजी") सिम्युलेटर पर चल लॉग में लिखा है:

2013-02-20 16:50:38.730 Test1[7224:c07] File exists=1 at path:/Users/kenm/Library/Application Support/iPhone Simulator/6.1/Applications/C6FDE177-958C-4BF5-8770-A4D3FBD281F1/Documents/TempDir/test.jpg 
2013-02-20 16:50:38.732 Test1[7224:c07] File exists=1 at path:/Users/kenm/Library/Application Support/iPhone Simulator/6.1/Applications/C6FDE177-958C-4BF5-8770-A4D3FBD281F1/Documents/TempDir/.DS_Store 
2013-02-20 16:50:38.733 Test1[7224:c07] File exists=1 at path:/Users/kenm/Library/Application Support/iPhone Simulator/6.1/Applications/C6FDE177-958C-4BF5-8770-A4D3FBD281F1/Documents/TempDir/test.jpg 
+4

सबसे बुरी बात आप क्या कर सकते को अपने ऐप्लिकेशन के दस्तावेज़ निर्देशिका के लिए पथ है या हो सकता है के बारे में किसी भी मान्यताओं है। उस पथ के लिए एक विशिष्ट लंबाई की अपेक्षा करना भी बदतर है। बस दस्तावेज़ पथ निर्धारित करें और अपने सापेक्ष पथ प्राप्त करने के लिए पूर्ण पथ से हटा दें। – rmaddy

+0

@maddy, मैं एक विशिष्ट लंबाई संभालने नहीं था, सिर्फ इतना है कि करने के लिए पथ/दस्तावेज़ में परिवर्तन नहीं होता है, जो जोड़ने/निजी के रूप में केविन बेलार्ड नीचे बताया सिर्फ एक सिमलिंक है आईओएस द्वारा उल्लंघन किया जाता है। मैं विंडोज़ से आ रहा हूं जहां मैंने कभी ऐसा नहीं देखा है। अब, मैं/NSHomeDirectory() की सबस्ट्रिंग खोजने कर रहा हूँ/किसी भी पथ आईओएस में दस्तावेज मुझे देता है और उस रिश्तेदार पथ के बाद पथ स्ट्रिंग बुला। क्या आपको इसके साथ कोई समस्या दिखाई देती है या सापेक्ष पथ प्राप्त करने के बेहतर तरीके से पता है? – KenM

+1

आपका प्रश्न बताता है: _ मैं होम निर्देशिका पथ_ की लंबाई का उपयोग कर रहा था। आपको हमेशा उन दस्तावेज़ों के साथ काम करना चाहिए जो दस्तावेज़ निर्देशिका से संबंधित हैं। आपको कभी भी पूरा रास्ता नहीं बचना चाहिए। यदि आपके पास केवल सापेक्ष निर्देशिकाएं हैं, तो प्रक्रिया करने के लिए कुछ भी नहीं है। – rmaddy

उत्तर

1

/var/private/var पर सिर्फ एक सिम्लिंक है। तो पहला पथ तार्किक पथ है जिसे आपने एक्सेस करने का प्रयास किया था। दूसरी बात यह है कि symlinks के साथ एक ही रास्ता विस्तारित।

+0

संकेत के लिए धन्यवाद, लेकिन यह विपरीत है। मेरा जवाब देखें – Skotch

+0

@ स्कॉट: यह वास्तव में नहीं है। अपने उत्तर पर मेरी टिप्पणी देखें। –

+0

/var मैक ओएस एक्स पर लंबे समय तक/निजी/var के लिए एक सिम्लिंक रहा है। यह आईओएस अस्तित्व से पहले था। –

4

वास्तव में अपने प्रश्न का उत्तर करने के लिए:

मेरा मानना ​​है कि /private एक उपसर्ग जोड़ा गया है जब वे जारी किया ओएस एक्स (मुझे नहीं लगता कि यह NeXTSTEP में वहाँ था, लेकिन यह दशकों हो गया है)। ऐसा लगता है कि etc, var, और tmp (और, विचित्र रूप से, tftpboot; मुझे नहीं पता था कि मेरा पीबीजी 4 ऐसा कर सकता है), शायद उपयोगकर्ताओं को आश्चर्य नहीं है कि etc नामक यह मूर्ख फ़ोल्डर क्या है और इसे हटाने का प्रयास करें ।

डिवाइस पर, एप्पल /private/var/mobile में उपयोगकर्ता डेटा स्टोर करने का फैसला किया (उपयोगकर्ता नाम "मोबाइल" है)। मुझे यकीन है कि क्यों वे /Users/mobile या सिर्फ /mobile लेने नहीं था नहीं कर रहा हूँ, लेकिन यह /var/mobile एक "सामान्य" यूनिक्स पर होगा अधिक नहीं महत्व है।

सिम्युलेटर पर, अपने उपयोगकर्ता खाते से /var (अच्छे कारण के लिए) नहीं लिख सकते हैं। उपयोगकर्ता डेटा ~/Library/Application Support/iPhone Simulator में कहीं भी संग्रहीत किया जाता है। एक बिंदु पर, उन्होंने विभिन्न सिम्युलेटर संस्करणों के लिए विभिन्न निर्देशिकाओं का उपयोग शुरू किया।

23

मैं डिबगर से करने की कोशिश की और कहा कि URLByResolvingSymlinksInPath "फिक्स" /private/ अलावा की खोज की।

(lldb) p (NSURL *)[NSURL fileURLWithPath:@"/private/var" isDirectory:YES] 
(NSURL *) $1 = 0x1fd9fc20 @"file://localhost/private/var/" 
(lldb) po [$1 URLByResolvingSymlinksInPath] 
$2 = 0x1fda0190 file://localhost/var/ 

(lldb) p (NSURL *)[NSURL fileURLWithPath:@"/var" isDirectory:YES] 
(NSURL *) $7 = 0x1fd9fee0 @"file://localhost/var/" 
(lldb) po [$7 URLByResolvingSymlinksInPath] 
$8 = 0x1fda2f50 file://localhost/var/ 

के रूप में आप देख सकते हैं, file://localhost/var क्या हम वास्तव में यहाँ चाहते हैं।

इस वजह से, यह स्पष्ट प्रतीत होता है कि /private/var/var पर एक सिम्लिंक है। हालांकि, @ केविन-बल्लार्ड बताते हैं कि यह सच नहीं है। मैं इस बात की पुष्टि है कि वह सही है, और /var/private/var (आह) के लिए सिमलिंक

(lldb) p (NSDictionary *)[[NSFileManager defaultManager] attributesOfItemAtPath:@"/var" error:nil] 
(NSDictionary *) $3 = 0x1fda11b0 13 key/value pairs 
(lldb) po $3 
$3 = 0x1fda11b0 { 
    ... 
    NSFileType = NSFileTypeSymbolicLink; 
} 

(lldb) p (NSDictionary *)[[NSFileManager defaultManager] attributesOfItemAtPath:@"/private/var" error:nil] 
(NSDictionary *) $5 = 0x1fda4820 14 key/value pairs 
(lldb) po $5 
$5 = 0x1fda4820 { 
    ... 
    NSFileType = NSFileTypeDirectory; 
} 

तो URLByResolvingSymlinksInPath यहाँ कुछ अजीब कर रहा है, लेकिन अब हम जानते हैं। इस विशेष समस्या के लिए, URLByResolvingSymlinksInPath अभी भी एक अच्छा समाधान की तरह लगता है जो सिम्युलेटर और डिवाइस दोनों के लिए काम करता है और अगर कुछ बदलता है तो भविष्य में काम करना जारी रखना चाहिए।

+2

'/ var' वास्तव में'/निजी/भी iOS पर var' एक सिमलिंक है। यह संभव है कि '-URLByResolvingSymlinksInPath' किसी भी तरह से एक और कैननिकल पथ प्रदान करने के लिए विशेष रूप से आ रहा है। –

+0

ठोस चर्चा; मैं पीडीएफ व्यूअर के भीतर फ़ाइलों को लोड करने में एक समस्या में भाग गया और यह सब सिमलिंक के चारों ओर घूम गया। एक बार जब मैं इस स्पष्टीकरण में आया तो समाधान निकल गया और समस्या हल हो गई। –

+1

ऐप्पल दस्तावेज़ जो 'URLByResolvingSymlinksInPath' अग्रणी '/ private' को हटा देता है। https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html#//apple_ref/doc/uid/20000301-SW32 –

2

में स्विफ्ट 3, URLstandardizedFileUrl संपत्ति है, जो किसी भी सिमलिंक हटाने और ./ की तरह पथ के भीतर रिश्तेदार भागों का समाधान हो जाएगा है।

documentation लेखन के रूप में बहुत बेकार है लेकिन ऐसा लगता है यह NSURL's standardized संपत्ति को equivialent है।