কীভাবে সুইফটে এনএসডোকামেন্ট ডিরেক্টরিটি সন্ধান করবেন?


162

আমি কোড সহ ডকুমেন্টস ফোল্ডারে যাওয়ার চেষ্টা করছি:

var documentsPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory:0,NSSearchPathDomainMask:0,true)

তবে এক্সকোড ত্রুটি দেয়: Cannot convert expression's type 'AnyObject[]!' to type 'NSSearchPathDirectory'

আমি কোডটিতে কী ভুল তা বোঝার চেষ্টা করছি।


1
এই প্রশ্নের বেশ কয়েকটি সম্পাদনা ছিল যা সম্ভাব্য সমাধান যোগ করছিল। পুরো ব্যাপারটাই একটা গোলযোগ ছিল। আমি স্বচ্ছতার জন্য প্রথম সংস্করণে ফিরে এসেছি। উত্তরগুলি কোনও প্রশ্নের সাথে সম্পর্কিত নয় এবং উত্তর হিসাবে পোস্ট করা উচিত। কেউ যদি আমার রোলব্যাকটি খুব মূলগত মনে করে তবে আমি আলোচনার জন্য উপলব্ধ। ধন্যবাদ।
এরিক আয়া

উত্তর:


254

স্পষ্টতই, সংকলকটি NSSearchPathDirectory:0একটি অ্যারে বলে মনে করে এবং অবশ্যই এটি NSSearchPathDirectoryপরিবর্তে প্রকারটি প্রত্যাশা করে । অবশ্যই সহায়ক ত্রুটি বার্তা নয়।

তবে কারণগুলি হিসাবে:

প্রথমত, আপনি যুক্তির নাম এবং প্রকারগুলি গুলিয়ে ফেলছেন। ফাংশন সংজ্ঞা একবার দেখুন:

func NSSearchPathForDirectoriesInDomains(
    directory: NSSearchPathDirectory,
    domainMask: NSSearchPathDomainMask,
    expandTilde: Bool) -> AnyObject[]!
  • directoryএবং domainMaskনামগুলি, আপনি প্রকারগুলি ব্যবহার করছেন তবে আপনার সেগুলি যাইহোক ফাংশনের জন্য রেখে দেওয়া উচিত। এগুলি প্রাথমিকভাবে পদ্ধতিতে ব্যবহৃত হয়।
  • এছাড়াও, সুইফটটি দৃ strongly়ভাবে টাইপ করা হয়েছে, সুতরাং আপনার কেবল 0 ব্যবহার করা উচিত নয় instead পরিবর্তে এনামের মানটি ব্যবহার করুন।
  • এবং শেষ অবধি, এটি একটি অ্যারে দেয়, কেবল একটি একক পথ নয়।

যাতে আমাদের ছেড়ে যায় (সুইফট ২.০-এর জন্য আপডেট হয়েছে):

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]

এবং সুইফট 3 এর জন্য:

let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]

এই উত্তরটি Xcode 6.0 এ ব্যর্থ হয়েছে। নিক্ষিপ্ত হতে হবেNSString বরং করাString
ড্যানিয়েল টি।

1
@DanielT। মাত্র আবার চেষ্টা Stringকরে এক্সকোড 6.0 এবং 6.1 এ কাজ করে। সাধারণত, Stringএবং NSStringসুইফটে স্বয়ংক্রিয়ভাবে ব্রিজ হয়। হতে পারে আপনি কাস্ট করতে ছিল NSStringঅন্য কারণে।
nschum

আপনি কি এটি খেলার মাঠে চেষ্টা করেছেন বা কোনও আসল অ্যাপে? ফলাফল আলাদা। কোডটি Stringখেলার মাঠে একটিতে কাস্ট করে , তবে কোনও অ্যাপে নয়। প্রশ্ন দেখুন ( স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 26450003/… )
ড্যানিয়েল টি

উভয়, আসলে। সুইফ্টে একটি সূক্ষ্ম বাগ হতে পারে, আমি মনে করি ... আমি নিরাপদ থাকার জন্য উত্তরটি সম্পাদনা করব। :) ধন্যবাদ
nschum

3
অ্যাপটি আবার চালানো অন্যরকম পথ তৈরি করে, কেন?: (1) /var/mobile/Containers/Data/Application/9E18A573-6429-434D-9B42-08642B643970/Documents(2)/var/mobile/Containers/Data/Application/77C8EA95-B77A-474D-8522-1F24F854A291/Documents
জ্যানোস

40

সুইফট 3.0 এবং 4.0

কোনও অ্যারে থেকে সরাসরি প্রথম উপাদান পাওয়া সম্ভাব্যভাবে ব্যতিক্রম ঘটায় যদি পথটি না পাওয়া যায়। সুতরাং কল করা firstএবং তারপরে আন-র্যাপ করা আরও ভাল সমাধান

if let documentsPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
    //This gives you the string formed path
}

if let documentsPathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
    //This gives you the URL of the path
}

32

আধুনিক প্রস্তাবটি হ'ল এনএসএসআরটি ভিত্তিক পাথের পরিবর্তে ফাইল এবং ডিরেক্টরিগুলির জন্য এনএসআরএলগুলি ব্যবহার করা:

এখানে চিত্র বর্ণনা লিখুন

সুতরাং অ্যাপ্লিকেশনটির জন্য একটি এনএসআরএল হিসাবে নথি ডিরেক্টরি পেতে:

func databaseURL() -> NSURL? {

    let fileManager = NSFileManager.defaultManager()

    let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)

    if let documentDirectory: NSURL = urls.first as? NSURL {
        // This is where the database should be in the documents directory
        let finalDatabaseURL = documentDirectory.URLByAppendingPathComponent("items.db")

        if finalDatabaseURL.checkResourceIsReachableAndReturnError(nil) {
            // The file already exists, so just return the URL
            return finalDatabaseURL
        } else {
            // Copy the initial file from the application bundle to the documents directory
            if let bundleURL = NSBundle.mainBundle().URLForResource("items", withExtension: "db") {
                let success = fileManager.copyItemAtURL(bundleURL, toURL: finalDatabaseURL, error: nil)
                if success {
                    return finalDatabaseURL
                } else {
                    println("Couldn't copy file to final location!")
                }
            } else {
                println("Couldn't find initial database in the bundle!")
            }
        }
    } else {
        println("Couldn't get documents directory!")
    }

    return nil
}

এটির ক্ষেত্রে প্রারম্ভিক ত্রুটি পরিচালনা করা রয়েছে, কারণ এ জাতীয় ক্ষেত্রে আপনার অ্যাপ্লিকেশন কী করবে তার উপর নির্ভর করে। তবে এটি ডাটাবেস ইউআরএল ফিরিয়ে আনতে ফাইল ইউআরএল এবং আরও আধুনিক এপিআই ব্যবহার করে, বান্ডেলটি ইতিমধ্যে উপস্থিত না থাকলে প্রাথমিক সংস্করণটি অনুলিপি করে, বা ত্রুটির ক্ষেত্রে শূন্য করে।


24

এক্সকোড 8.2.1 • সুইফ্ট 3.0.2

let documentDirectoryURL =  try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

এক্সকোড 7.1.1 • সুইফট 2.1

let documentDirectoryURL =  try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)

21

সাধারণত আমি এই এক্সটেনশনটি ব্যবহার করতে পছন্দ করি:

সুইফট 3.x এবং সুইফট 4.0 :

extension FileManager {
    class func documentsDir() -> String {
        var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as [String]
        return paths[0]
    }

    class func cachesDir() -> String {
        var paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true) as [String]
        return paths[0]
    }
}

সুইফট 2.x :

extension NSFileManager {
    class func documentsDir() -> String {
        var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as [String]
        return paths[0]
    }

    class func cachesDir() -> String {
        var paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true) as [String]
        return paths[0]
    }
}

এটাকে কোথায় ডাকবো?
বি সরবানা কুমার

আপনার কোডের প্রতিটি অংশে আপনার প্রয়োজন let path = FileManager.documentsDir()+("/"+"\(fileName)"):, আপনি থ্রেডের (মূল বা পটভূমি) পার্থক্য ছাড়াই এটি কল করতে পারেন।
আলেসান্দ্রো ওর্নানো

14

সুইফট ২.২ এর সাথে কাজ করে এমন উদাহরণ দেখায় এমন প্রত্যেকের জন্য, আধুনিক সহ অ্যাবিজার্ন কোড ত্রুটি ধরায় চেষ্টা করে

func databaseURL() -> NSURL? {

    let fileManager = NSFileManager.defaultManager()

    let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)

    if let documentDirectory:NSURL = urls.first { // No use of as? NSURL because let urls returns array of NSURL
        // This is where the database should be in the documents directory
        let finalDatabaseURL = documentDirectory.URLByAppendingPathComponent("OurFile.plist")

        if finalDatabaseURL.checkResourceIsReachableAndReturnError(nil) {
            // The file already exists, so just return the URL
            return finalDatabaseURL
        } else {
            // Copy the initial file from the application bundle to the documents directory
            if let bundleURL = NSBundle.mainBundle().URLForResource("OurFile", withExtension: "plist") {

                do {
                    try fileManager.copyItemAtURL(bundleURL, toURL: finalDatabaseURL)
                } catch let error as NSError  {// Handle the error
                    print("Couldn't copy file to final location! Error:\(error.localisedDescription)")
                }

            } else {
                print("Couldn't find initial database in the bundle!")
            }
        }
    } else {
        print("Couldn't get documents directory!")
    }

    return nil
}

আপডেট আমি মিস করেছি যে নতুন সুইফট ২.০-তে গার্ড রয়েছে (অ্যানালগ ব্যতীত রুবি), সুতরাং প্রহরী সহ এটি অনেক খাটো এবং আরও পাঠযোগ্য

func databaseURL() -> NSURL? {

let fileManager = NSFileManager.defaultManager()
let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)

// If array of path is empty the document folder not found
guard urls.count != 0 else {
    return nil
}

let finalDatabaseURL = urls.first!.URLByAppendingPathComponent("OurFile.plist")
// Check if file reachable, and if reacheble just return path
guard finalDatabaseURL.checkResourceIsReachableAndReturnError(nil) else {
    // Check if file is exists in bundle folder
    if let bundleURL = NSBundle.mainBundle().URLForResource("OurFile", withExtension: "plist") {
        // if exist we will copy it
        do {
            try fileManager.copyItemAtURL(bundleURL, toURL: finalDatabaseURL)
        } catch let error as NSError { // Handle the error
            print("File copy failed! Error:\(error.localizedDescription)")
        }
    } else {
        print("Our file not exist in bundle folder")
        return nil
    }
    return finalDatabaseURL
}
return finalDatabaseURL 
}

13

আরও সুবিধাজনক সুইফট 3 পদ্ধতি:

let documentsUrl = FileManager.default.urls(for: .documentDirectory, 
                                             in: .userDomainMask).first!

1
বা এমনকিFileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
আইলিয়ান ওনোফ্রেই

7
আমি যখনই ডকুমেন্টস ডিরেক্টরিতে কোনও ইউআরএল পেতে চাইছি তখনই নতুন ফাইল পরিচালককে ইনস্ট্যান্ট করা দরকার বলে আমি মনে করি না।
আন্দ্রে গর্দিভ

1
আমি ভেবেছিলাম এটি একই জিনিস। ধন্যবাদ!
Iulian Onofrei

5

এক্সকোড 8 বি 4 সুইফট 3.0

let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)

3

সাধারণত আমি নীচে সুইফট 3-তে পছন্দ করি কারণ আমি ফাইলের নাম যুক্ত করতে পারি এবং সহজেই একটি ফাইল তৈরি করতে পারি

let fileManager = FileManager.default
if let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
    let databasePath = documentsURL.appendingPathComponent("db.sqlite3").path
    print("directory path:", documentsURL.path)
    print("database path:", databasePath)
    if !fileManager.fileExists(atPath: databasePath) {
        fileManager.createFile(atPath: databasePath, contents: nil, attributes: nil)
    }
}

1
absoluteStringভূল. কোনও ফাইলের URL ফাইলের পাথ পেতে আপনার .pathসম্পত্তিটি পেতে হবে
লিও ডাবাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.