প্রকারটি কীভাবে এনএসএফচেকরেক্সটেন্সে প্রয়োগ করতে হবে?


102

সুইফট 2 এ নিম্নলিখিত কোডটি কাজ করছিল:

let request = NSFetchRequest(entityName: String)

তবে সুইফ্ট 3 এ এটি ত্রুটি দেয়:

জেনেরিক প্যারামিটার "রেজাল্টটাইপ" অনুমান করা যায়নি

কারণ NSFetchRequestএখন একটি জেনেরিক টাইপ। তাদের নথিতে তারা এটি লিখেছেন:

let request: NSFetchRequest<Animal> = Animal.fetchRequest

সুতরাং যদি আমার রেজাল্ট ক্লাসটি উদাহরণস্বরূপ হয় তবে Levelকীভাবে আমি সঠিকভাবে অনুরোধ করব?

কারণ এটি কাজ করছে না:

let request: NSFetchRequest<Level> = Level.fetchRequest

1
নতুন বৈশিষ্ট্যগুলির সাথে লিঙ্ক করুন, যেখানে আমি কোডটি পেয়েছি: বিকাশকারী
অ্যাপ্লিকেশন

1
এটি একটি পদ্ধতি, সুতরাং এটি হওয়া উচিতlet request: NSFetchRequest<Level> = Level.fetchRequest()
সুলতান

5
বা ঠিকlet request = Level.fetchRequest()
মার্টিন আর

2
@ মার্টিনআর এটি সংকলনটি পাস করবে না কারণ এটি উত্সাহযুক্ত।
সুলতান

6
@ মার্টিনআর মনে হচ্ছে স্ট্যাক ওভারফ্লো সদস্যরা আপনাকে অনেক ভালবাসে তারা আপনাকে অন্ধভাবে উপড়ে ফেলবে। : পি
BangOperator

উত্তর:


129
let request: NSFetchRequest<NSFetchRequestResult> = Level.fetchRequest()

অথবা

let request: NSFetchRequest<Level> = Level.fetchRequest()

আপনি কোন সংস্করণ চান তা নির্ভর করে

আপনাকে জেনেরিক প্রকারটি নির্দিষ্ট করতে হবে কারণ অন্যথায় পদ্ধতি কলটি অস্পষ্ট।

প্রথম সংস্করণটির জন্য সংজ্ঞা দেওয়া হয়েছে NSManagedObject, দ্বিতীয় সংস্করণটি প্রতিটি বস্তুর জন্য একটি এক্সটেনশন ব্যবহার করে স্বয়ংক্রিয়ভাবে উত্পন্ন হয়, যেমন:

extension Level {
    @nonobjc class func fetchRequest() -> NSFetchRequest<Level> {
        return NSFetchRequest<Level>(entityName: "Level");
    }

    @NSManaged var timeStamp: NSDate?
}

পুরো বিষয়টি হ'ল স্ট্রিং কনস্ট্যান্টের ব্যবহার সরানো।


1
সুতরাং প্রতিটি সত্তার জন্য, আমার কি এক্সটেনশন কোড যুক্ত করা দরকার? নাকি তা স্বয়ংক্রিয়ভাবে ঘটে? সুতরাং আমার যদি একটি "কুকুর" সত্তা এবং "ক্যাট" সত্তা থাকে তবে আমার কি "এক্সটেনশন কুকুর {@ ননোবজক ...}" এবং "এক্সটেনশন ক্যাট {@ ননোবজ্যাক ...}" দরকার?
ডেভ জি

@ ডেভজি সেই এক্সটেনশনটি স্বয়ংক্রিয়ভাবে আপনার জন্য উত্পন্ন হয়।
সুলতান

1
ঠিক আছে, তবে আমি কিছুটা বিভ্রান্ত কারণ আমি 'fetchRequest = NSFetchRequest <myEntityName> (#Name: "myEntityName")' চেষ্টা করেছিলাম এবং আমি ত্রুটি পেয়েছি "অঘোষিত ধরণের" myEntityName "
ডেভ জি

4
দ্রষ্টব্য: পদ্ধতিটি ফ্যাচ-র্যুইয়েস্ট () কেবলমাত্র আইওএস 10
dzensik

@ সুলতান হাই, আমি যখন আপনার কোড দিয়ে চেষ্টা করেছি, নীচের ত্রুটি ঘটে। Type 'Project Name' does not conform to protocol 'NSFetchRequestResult'
স্বেটোস্লাভ আতানাসভ

56

আমি মনে করি এটি করে এটি কাজ করেছিলাম:

let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Level")

অন্তত এটি ডেটাবেস থেকে ডেটা সংরক্ষণ এবং লোড করে।

তবে এটি অনুভব করে যে এটি কোনও উপযুক্ত সমাধান নয়, তবে এটি আপাতত কাজ করে।


আমি এই সমাধানটি আরও ভাল পছন্দ করি, কারণ আমার কাছে একটি একক পদ্ধতি ছিল যা পরামিতি হিসাবে সত্তার নাম নিয়েছিল এবং NSManagedObjects এর একটি অ্যারে ফিরে দিয়েছিল।
n_b

এটিকেও পছন্দ হয়েছে কারণ এটির জন্য কাস্টম ক্লাস তৈরির প্রয়োজন হয়নি। শুধু সত্তার নাম ব্যবহার করতে পারে!
লিয়াম বোলিং

আন্ডাররেটেড উত্তর। ধন্যবাদ!
ডেভিড চেলিডজে

33

আমি যে সহজ কাঠামোটি খুঁজে পেয়েছি যে 3.0 এ কাজ করে তা নিম্নরূপ:

let request = NSFetchRequest<Country>(entityName: "Country")

যেখানে তথ্য সত্তার প্রকারটি দেশ।

একটি কোর ডেটা ব্যাচডিলিটরেক্সেস্ট তৈরি করার চেষ্টা করার সময়, আমি খুঁজে পেলাম যে এই সংজ্ঞাটি কার্যকর হয় না এবং মনে হয় যে আপনাকে ফর্মটি দিয়ে যেতে হবে:

let request: NSFetchRequest<NSFetchRequestResult> = Country.fetchRequest()

যদিও ম্যানেজডঅবজেক্ট এবং ফেচরেইকুয়েস্টআরসাল্ট ফর্ম্যাটগুলি সমতুল্য বলে মনে করা হচ্ছে।


1
এই উত্তরে বর্ণিত প্রথম কাঠামোটি হ'ল আমি বর্তমানে সুইফট 3 / আইওএস 10 / এক্সকোড 8
ডেভিড এল

বিভিন্ন ফর্ম চেষ্টা করার পরে আমার অভিজ্ঞতা ছিল। তারা কোরডাটা উপস্থাপনায় অন্য কোনও ফর্মগুলি আবরণ করেছে? আগামীকাল এটি পরীক্ষা করার পরিকল্পনা করুন ...
রন ডিল

প্রথম উদাহরণটি হ'ল if #available(iOS 10.0) { ... }শর্তসাপেক্ষে ব্যবহার না করেই আমি খুঁজে পেলাম সহজ উপায়
ডিজেভি

12

এখানে কিছু জেনেরিক কোরডেটা পদ্ধতি রয়েছে যা আপনার প্রশ্নের উত্তর দিতে পারে:

import Foundation
import Cocoa

func addRecord<T: NSManagedObject>(_ type : T.Type) -> T
{
    let entityName = T.description()
    let context = app.managedObjectContext
    let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
    let record = T(entity: entity!, insertInto: context)
    return record
}

func recordsInTable<T: NSManagedObject>(_ type : T.Type) -> Int
{
    let recs = allRecords(T.self)
    return recs.count
}


func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
    let context = app.managedObjectContext
    let request = T.fetchRequest()
    do
    {
        let results = try context.fetch(request)
        return results as! [T]
    }
    catch
    {
        print("Error with request: \(error)")
        return []
    }
}

func query<T: NSManagedObject>(_ type : T.Type, search: NSPredicate?, sort: NSSortDescriptor? = nil, multiSort: [NSSortDescriptor]? = nil) -> [T]
{
    let context = app.managedObjectContext
    let request = T.fetchRequest()
    if let predicate = search
    {
        request.predicate = predicate
    }
    if let sortDescriptors = multiSort
    {
        request.sortDescriptors = sortDescriptors
    }
    else if let sortDescriptor = sort
    {
        request.sortDescriptors = [sortDescriptor]
    }

    do
    {
        let results = try context.fetch(request)
        return results as! [T]
    }
    catch
    {
        print("Error with request: \(error)")
        return []
    }
}


func deleteRecord(_ object: NSManagedObject)
{
    let context = app.managedObjectContext
    context.delete(object)
}

func deleteRecords<T: NSManagedObject>(_ type : T.Type, search: NSPredicate? = nil)
{
    let context = app.managedObjectContext

    let results = query(T.self, search: search)
    for record in results
    {
        context.delete(record)
    }
}

func saveDatabase()
{
    let context = app.managedObjectContext

    do
    {
        try context.save()
    }
    catch
    {
        print("Error saving database: \(error)")
    }
}

ধরে নিচ্ছি যে এই জাতীয় পরিচিতির জন্য NSManagedObject সেটআপ রয়েছে:

class Contact: NSManagedObject
{
    @NSManaged var contactNo: Int
    @NSManaged var contactName: String
}

এই পদ্ধতিগুলি নিম্নলিখিত উপায়ে ব্যবহার করা যেতে পারে:

let name = "John Appleseed"

let newContact = addRecord(Contact.self)
newContact.contactNo = 1
newContact.contactName = name

let contacts = query(Contact.self, search: NSPredicate(format: "contactName == %@", name))
for contact in contacts
{
    print ("Contact name = \(contact.contactName), no = \(contact.contactNo)")
}

deleteRecords(Contact.self, search: NSPredicate(format: "contactName == %@", name))

recs = recordsInTable(Contact.self)
print ("Contacts table has \(recs) records")

saveDatabase()

পরিষ্কার এবং মার্জিত। আশা করি আমি এই 100 টি ভোট দিতে পারে! একটি টাচআপ, আপনি কী ভাবছেন তা অবাক করে, থ্রেড সুরক্ষার জন্য আমি প্রতিটি পদ্ধতিকে প্রসঙ্গে? .প্রফর্ম ({}) দিয়ে আবৃত করি। এটি অ্যাপল দ্বারা সুপারিশ করা হয়।
টিঙ্কারবেল

খুব OO না। যদি আপনি এগুলি এনএসম্যানেজডঅবজেক্ট কনট্যাক্টের একটি এক্সটেনশন হিসাবে লিখতে সক্ষম না হন, তবে এটি তখন একটি দুর্দান্ত সমাধান হতে পারে।
মোজ কুঠার

1
সবেমাত্র লক্ষ্য করা হয়েছে - আপনি যে সমস্ত রেকর্ডগুলি পুনরুদ্ধার করছেন তার সবগুলি গণনা করতে এবং তারপরে অ্যারে প্রবেশের সংখ্যা গণনা করতে - এটি সত্যই অক্ষম। আপনি সম্ভবত
কনটেক্সটকাউন্ট

এগুলি দুর্দান্ত সংযোজন এবং আরও বেশি ভোট হওয়া উচিত, তবে সম্ভবত এটি মূল প্রশ্ন থেকে দূরে একটি অপসারণ (যদিও এটি দরকারী) doesn't মুছুন ফাংশনটি পরিবর্তন করার জন্য আমি শক্তভাবে যা সুপারিশ করব তার NSManagedObjectIDপরিবর্তে মুছতে হবে instead সুতরাং মুছে ফেলার জন্য রেকর্ড অবজেক্টটি context.delete(record)যুক্ত করে আগে let record = context.object(with: record.objectID)ব্যবহার করুন।
পোস্টকোডিজম

6

এটি সুইফট ৩.০ এ সরিয়ে নেওয়ার সহজতম উপায়, কেবল যুক্ত করুন <Country>

(পরীক্ষিত এবং কাজ)

let request = NSFetchRequest<Country>(entityName: "Country")

0

আমার "রেজাল্টটাইপ" ছিল অনুমান ত্রুটি হতে পারে না। আমি প্রতিটি সত্তার কোডজেনকে "শ্রেণি সংজ্ঞা" তে সেট করে ডেটা মডেলটি পুনঃনির্মাণ করার পরে তারা সাফ হয়ে যায়। আমি এখানে ধাপে ধাপে নির্দেশাবলী সহ একটি সংক্ষিপ্ত লিখনআপ করেছি:

এক্সকোড 8-এ সুইফট 3 সহ সংশোধিত এনএসপার্সসিস্টেন্ট কনটেইনার সম্পর্কে একটি পরিষ্কার টিউটোরিয়াল খুঁজছি

"পুনর্নির্মাণ" দ্বারা আমি বোঝাতে চাইছি যে আমি নতুন এন্ট্রি এবং বৈশিষ্ট্য সহ একটি নতুন মডেল ফাইল তৈরি করেছি। কিছুটা ক্লান্তিকর, কিন্তু এটি কাজ করে!


0

আমার পক্ষে এখন পর্যন্ত যা সবচেয়ে ভাল কাজ করেছে তা হ'ল:

let request = Level.fetchRequest() as! NSFetchRequest<Level>

0

আমার একই সমস্যা ছিল এবং আমি এটি নিম্নলিখিত পদক্ষেপগুলি দিয়ে সমাধান করেছি:

  • আপনার xcdatamodeld ফাইলটি নির্বাচন করুন এবং ডেটা মডেল পরিদর্শকের কাছে যান
  • আপনার প্রথম সত্তা নির্বাচন করুন এবং বিভাগ শ্রেণিতে যান
  • নিশ্চিত করুন যে কোডজেন "ক্লাস সংজ্ঞা" নির্বাচিত হয়েছে।
  • আপনার উত্পন্ন সমস্ত সত্তা ফাইল সরান। আপনার আর দরকার নেই।

এটি করার পরে আমাকে আনতে / পুনরায় লেখার সমস্ত ঘটনাগুলি পুনরায় লিখে ফেলতে হয়েছিল কারণ এক্সকোড মনে হয় কোনওভাবে কোডজেনেটেড সংস্করণটির সাথে মিশে গেছে।

আছে HTH


0

সুইফট 3.0 এটি কাজ করা উচিত।

let request: NSFetchRequest<NSFetchRequestResult> = NSManagedObject.fetchRequest()
request.entity = entityDescription(context)
request.predicate = predicate
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.