Swift generic table view data source and delegate, protocol backed NSManagedObjects, cannot obtain entity attribute, runtime error










2














The Problem



break point screenshot




*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]:
this class is not key value coding-compliant for the key active.'




Thanks to @GrahamPerks answer to this SO question, I inserted an exception breakpoint in my code, which now pauses execution at this line...



static var entityActive: Bool 
return entity.value(forKey: "active") as! Bool // <-- PAUSES AT THIS LINE



This obviously needs further explanation...



Background



I'm writing a Core Data app that uses a generic table view data source and delegate, more or less set up per Florian Kugler's book "Core Data", published in 2017 by objc.io.



I have successfully linked three separate UITableViewControllers to this generic data source / delegate. I am using a single main storyboard and these three controllers are linked to three UISplitViewController master/detail views.



I have deleted the automatically generated dataSource and delegate connections within the storyboard UITableViews (although whether I leave or remove these connections, seems to make no difference).



If I comment out the code for the static var entityActive above, the project will successfully Build and Run.



My code uses the UITableViewDelegate method tableView(_, willDisplay:, forRowAt:) to change the .textColor of text and .backgroundColor of cells, based on an attribute "active", stored as a boolean Scalar Type value with each entity.



For clarity, I'm trying to get the "active" attribute (every entity in my data model has a common attribute "active") for each NSManagedObject for the entity. The value of that "active" attribute (Bool true or false) for each entity is then used to format the cell in the if...else statement in the following code.



To attempt to maximise code reuse and minimise code repetition, I have also placed this delegate method in my generic data source / delegate class.



func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

let entityObjectActive = T.entityActive

if entityObjectActive == true
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.textColor = UIColor.darkGray
cell.backgroundColor = UIColor.white
else if entityObjectActive == false
cell.textLabel?.textColor = UIColor.lightGray
cell.detailTextLabel?.textColor = UIColor.lightGray
cell.backgroundColor = UIColor.clear





The compiler doesn't complain.



I seem to be able to use the generic type T (representing Core Data entities) to associate the static property entityActive with my instance of entityObjectActive - so this seems to work...



let entityObjectActive = T.entityActive


To confirm, I have the following:



generic data source class....



class MyDataSource<T: Managed, 
Delegate: TableViewDataSourceDelegate>:
NSObject,
UITableViewDataSource,
UITableViewDelegate,
NSFetchedResultsControllerDelegate

// lots of code...



protocol...



protocol Managed: class, NSFetchRequestResult 
static var entity: NSEntityDescription get
static var entityActive: Bool get
}


and extension...



extension Managed where Self: NSManagedObject 
static var entity: NSEntityDescription return entity()
static var entityActive: Bool
return entity.value(forKey: "active") as! Bool




Attempts at Problem Solving



I've done some reading attempting to resolve my problem, including a review of many blogs (on how to set up generics in general and generic table view data sources) and a lot of SO Q&A, in particular...



How to fix Error: this class is not key value coding-compliant for the key tableView.'



Uncaught exception: This class is not key value coding-compliant



setValue:forUndefinedKey: this class is not key value coding-compliant for the key



It seems that all the SO Q&A are directly related to an issue with IB connections within storyboards. Maybe this is my issue too - but if that is the case it seems to me to be very well hidden.



Any assistance or advice please?



PS: I'm learning Swift after being a long time coder in Obj-C and I'm really struggling with the Generics Protocols Extensions paradigm shift, so it could be that my use of generic types is incorrect?










share|improve this question



















  • 1




    Are you sure you can access a static variable using key-value coding? Shouldn't it be accessed as Managed.entity when it's static?
    – Joakim Danielson
    Nov 13 '18 at 6:33










  • @JoakimDanielson thanks for your question but honestly I'm not sure, I'm new to Swift and generics, self taught on Obj-C and always preferred blocks to protocols in Obj-C, so part of my problem may be a general and basic lack of understanding of static variables, protocols and KVC. (PS tried your suggestion but could not make it work.)
    – andrewbuilder
    Nov 13 '18 at 9:53







  • 1




    Per your extension, entity is an NSEntityDescription: there's no active property for NSEntityDescriptions which is why you get the error. Do you in fact mean to get the active attribute for the NSManagedObject?
    – pbasdf
    Nov 13 '18 at 10:39










  • @pbasdf correct, I'm trying to get the active attribute (every entity in my data model has a common active attribute) for the NSManagedObject.
    – andrewbuilder
    Nov 13 '18 at 10:41






  • 1




    I think your entityActive should not be static: it's a property of Managed objects, not the Managed class. Your willDisplayCell code therefore needs to identify which Managed object is required - presumably using the indexPath to look up in the datasource.
    – pbasdf
    Nov 13 '18 at 10:55















2














The Problem



break point screenshot




*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]:
this class is not key value coding-compliant for the key active.'




Thanks to @GrahamPerks answer to this SO question, I inserted an exception breakpoint in my code, which now pauses execution at this line...



static var entityActive: Bool 
return entity.value(forKey: "active") as! Bool // <-- PAUSES AT THIS LINE



This obviously needs further explanation...



Background



I'm writing a Core Data app that uses a generic table view data source and delegate, more or less set up per Florian Kugler's book "Core Data", published in 2017 by objc.io.



I have successfully linked three separate UITableViewControllers to this generic data source / delegate. I am using a single main storyboard and these three controllers are linked to three UISplitViewController master/detail views.



I have deleted the automatically generated dataSource and delegate connections within the storyboard UITableViews (although whether I leave or remove these connections, seems to make no difference).



If I comment out the code for the static var entityActive above, the project will successfully Build and Run.



My code uses the UITableViewDelegate method tableView(_, willDisplay:, forRowAt:) to change the .textColor of text and .backgroundColor of cells, based on an attribute "active", stored as a boolean Scalar Type value with each entity.



For clarity, I'm trying to get the "active" attribute (every entity in my data model has a common attribute "active") for each NSManagedObject for the entity. The value of that "active" attribute (Bool true or false) for each entity is then used to format the cell in the if...else statement in the following code.



To attempt to maximise code reuse and minimise code repetition, I have also placed this delegate method in my generic data source / delegate class.



func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

let entityObjectActive = T.entityActive

if entityObjectActive == true
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.textColor = UIColor.darkGray
cell.backgroundColor = UIColor.white
else if entityObjectActive == false
cell.textLabel?.textColor = UIColor.lightGray
cell.detailTextLabel?.textColor = UIColor.lightGray
cell.backgroundColor = UIColor.clear





The compiler doesn't complain.



I seem to be able to use the generic type T (representing Core Data entities) to associate the static property entityActive with my instance of entityObjectActive - so this seems to work...



let entityObjectActive = T.entityActive


To confirm, I have the following:



generic data source class....



class MyDataSource<T: Managed, 
Delegate: TableViewDataSourceDelegate>:
NSObject,
UITableViewDataSource,
UITableViewDelegate,
NSFetchedResultsControllerDelegate

// lots of code...



protocol...



protocol Managed: class, NSFetchRequestResult 
static var entity: NSEntityDescription get
static var entityActive: Bool get
}


and extension...



extension Managed where Self: NSManagedObject 
static var entity: NSEntityDescription return entity()
static var entityActive: Bool
return entity.value(forKey: "active") as! Bool




Attempts at Problem Solving



I've done some reading attempting to resolve my problem, including a review of many blogs (on how to set up generics in general and generic table view data sources) and a lot of SO Q&A, in particular...



How to fix Error: this class is not key value coding-compliant for the key tableView.'



Uncaught exception: This class is not key value coding-compliant



setValue:forUndefinedKey: this class is not key value coding-compliant for the key



It seems that all the SO Q&A are directly related to an issue with IB connections within storyboards. Maybe this is my issue too - but if that is the case it seems to me to be very well hidden.



Any assistance or advice please?



PS: I'm learning Swift after being a long time coder in Obj-C and I'm really struggling with the Generics Protocols Extensions paradigm shift, so it could be that my use of generic types is incorrect?










share|improve this question



















  • 1




    Are you sure you can access a static variable using key-value coding? Shouldn't it be accessed as Managed.entity when it's static?
    – Joakim Danielson
    Nov 13 '18 at 6:33










  • @JoakimDanielson thanks for your question but honestly I'm not sure, I'm new to Swift and generics, self taught on Obj-C and always preferred blocks to protocols in Obj-C, so part of my problem may be a general and basic lack of understanding of static variables, protocols and KVC. (PS tried your suggestion but could not make it work.)
    – andrewbuilder
    Nov 13 '18 at 9:53







  • 1




    Per your extension, entity is an NSEntityDescription: there's no active property for NSEntityDescriptions which is why you get the error. Do you in fact mean to get the active attribute for the NSManagedObject?
    – pbasdf
    Nov 13 '18 at 10:39










  • @pbasdf correct, I'm trying to get the active attribute (every entity in my data model has a common active attribute) for the NSManagedObject.
    – andrewbuilder
    Nov 13 '18 at 10:41






  • 1




    I think your entityActive should not be static: it's a property of Managed objects, not the Managed class. Your willDisplayCell code therefore needs to identify which Managed object is required - presumably using the indexPath to look up in the datasource.
    – pbasdf
    Nov 13 '18 at 10:55













2












2








2







The Problem



break point screenshot




*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]:
this class is not key value coding-compliant for the key active.'




Thanks to @GrahamPerks answer to this SO question, I inserted an exception breakpoint in my code, which now pauses execution at this line...



static var entityActive: Bool 
return entity.value(forKey: "active") as! Bool // <-- PAUSES AT THIS LINE



This obviously needs further explanation...



Background



I'm writing a Core Data app that uses a generic table view data source and delegate, more or less set up per Florian Kugler's book "Core Data", published in 2017 by objc.io.



I have successfully linked three separate UITableViewControllers to this generic data source / delegate. I am using a single main storyboard and these three controllers are linked to three UISplitViewController master/detail views.



I have deleted the automatically generated dataSource and delegate connections within the storyboard UITableViews (although whether I leave or remove these connections, seems to make no difference).



If I comment out the code for the static var entityActive above, the project will successfully Build and Run.



My code uses the UITableViewDelegate method tableView(_, willDisplay:, forRowAt:) to change the .textColor of text and .backgroundColor of cells, based on an attribute "active", stored as a boolean Scalar Type value with each entity.



For clarity, I'm trying to get the "active" attribute (every entity in my data model has a common attribute "active") for each NSManagedObject for the entity. The value of that "active" attribute (Bool true or false) for each entity is then used to format the cell in the if...else statement in the following code.



To attempt to maximise code reuse and minimise code repetition, I have also placed this delegate method in my generic data source / delegate class.



func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

let entityObjectActive = T.entityActive

if entityObjectActive == true
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.textColor = UIColor.darkGray
cell.backgroundColor = UIColor.white
else if entityObjectActive == false
cell.textLabel?.textColor = UIColor.lightGray
cell.detailTextLabel?.textColor = UIColor.lightGray
cell.backgroundColor = UIColor.clear





The compiler doesn't complain.



I seem to be able to use the generic type T (representing Core Data entities) to associate the static property entityActive with my instance of entityObjectActive - so this seems to work...



let entityObjectActive = T.entityActive


To confirm, I have the following:



generic data source class....



class MyDataSource<T: Managed, 
Delegate: TableViewDataSourceDelegate>:
NSObject,
UITableViewDataSource,
UITableViewDelegate,
NSFetchedResultsControllerDelegate

// lots of code...



protocol...



protocol Managed: class, NSFetchRequestResult 
static var entity: NSEntityDescription get
static var entityActive: Bool get
}


and extension...



extension Managed where Self: NSManagedObject 
static var entity: NSEntityDescription return entity()
static var entityActive: Bool
return entity.value(forKey: "active") as! Bool




Attempts at Problem Solving



I've done some reading attempting to resolve my problem, including a review of many blogs (on how to set up generics in general and generic table view data sources) and a lot of SO Q&A, in particular...



How to fix Error: this class is not key value coding-compliant for the key tableView.'



Uncaught exception: This class is not key value coding-compliant



setValue:forUndefinedKey: this class is not key value coding-compliant for the key



It seems that all the SO Q&A are directly related to an issue with IB connections within storyboards. Maybe this is my issue too - but if that is the case it seems to me to be very well hidden.



Any assistance or advice please?



PS: I'm learning Swift after being a long time coder in Obj-C and I'm really struggling with the Generics Protocols Extensions paradigm shift, so it could be that my use of generic types is incorrect?










share|improve this question















The Problem



break point screenshot




*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]:
this class is not key value coding-compliant for the key active.'




Thanks to @GrahamPerks answer to this SO question, I inserted an exception breakpoint in my code, which now pauses execution at this line...



static var entityActive: Bool 
return entity.value(forKey: "active") as! Bool // <-- PAUSES AT THIS LINE



This obviously needs further explanation...



Background



I'm writing a Core Data app that uses a generic table view data source and delegate, more or less set up per Florian Kugler's book "Core Data", published in 2017 by objc.io.



I have successfully linked three separate UITableViewControllers to this generic data source / delegate. I am using a single main storyboard and these three controllers are linked to three UISplitViewController master/detail views.



I have deleted the automatically generated dataSource and delegate connections within the storyboard UITableViews (although whether I leave or remove these connections, seems to make no difference).



If I comment out the code for the static var entityActive above, the project will successfully Build and Run.



My code uses the UITableViewDelegate method tableView(_, willDisplay:, forRowAt:) to change the .textColor of text and .backgroundColor of cells, based on an attribute "active", stored as a boolean Scalar Type value with each entity.



For clarity, I'm trying to get the "active" attribute (every entity in my data model has a common attribute "active") for each NSManagedObject for the entity. The value of that "active" attribute (Bool true or false) for each entity is then used to format the cell in the if...else statement in the following code.



To attempt to maximise code reuse and minimise code repetition, I have also placed this delegate method in my generic data source / delegate class.



func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

let entityObjectActive = T.entityActive

if entityObjectActive == true
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.textColor = UIColor.darkGray
cell.backgroundColor = UIColor.white
else if entityObjectActive == false
cell.textLabel?.textColor = UIColor.lightGray
cell.detailTextLabel?.textColor = UIColor.lightGray
cell.backgroundColor = UIColor.clear





The compiler doesn't complain.



I seem to be able to use the generic type T (representing Core Data entities) to associate the static property entityActive with my instance of entityObjectActive - so this seems to work...



let entityObjectActive = T.entityActive


To confirm, I have the following:



generic data source class....



class MyDataSource<T: Managed, 
Delegate: TableViewDataSourceDelegate>:
NSObject,
UITableViewDataSource,
UITableViewDelegate,
NSFetchedResultsControllerDelegate

// lots of code...



protocol...



protocol Managed: class, NSFetchRequestResult 
static var entity: NSEntityDescription get
static var entityActive: Bool get
}


and extension...



extension Managed where Self: NSManagedObject 
static var entity: NSEntityDescription return entity()
static var entityActive: Bool
return entity.value(forKey: "active") as! Bool




Attempts at Problem Solving



I've done some reading attempting to resolve my problem, including a review of many blogs (on how to set up generics in general and generic table view data sources) and a lot of SO Q&A, in particular...



How to fix Error: this class is not key value coding-compliant for the key tableView.'



Uncaught exception: This class is not key value coding-compliant



setValue:forUndefinedKey: this class is not key value coding-compliant for the key



It seems that all the SO Q&A are directly related to an issue with IB connections within storyboards. Maybe this is my issue too - but if that is the case it seems to me to be very well hidden.



Any assistance or advice please?



PS: I'm learning Swift after being a long time coder in Obj-C and I'm really struggling with the Generics Protocols Extensions paradigm shift, so it could be that my use of generic types is incorrect?







ios swift uitableview generics core-data






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 10:56







andrewbuilder

















asked Nov 12 '18 at 23:50









andrewbuilderandrewbuilder

2,2181633




2,2181633







  • 1




    Are you sure you can access a static variable using key-value coding? Shouldn't it be accessed as Managed.entity when it's static?
    – Joakim Danielson
    Nov 13 '18 at 6:33










  • @JoakimDanielson thanks for your question but honestly I'm not sure, I'm new to Swift and generics, self taught on Obj-C and always preferred blocks to protocols in Obj-C, so part of my problem may be a general and basic lack of understanding of static variables, protocols and KVC. (PS tried your suggestion but could not make it work.)
    – andrewbuilder
    Nov 13 '18 at 9:53







  • 1




    Per your extension, entity is an NSEntityDescription: there's no active property for NSEntityDescriptions which is why you get the error. Do you in fact mean to get the active attribute for the NSManagedObject?
    – pbasdf
    Nov 13 '18 at 10:39










  • @pbasdf correct, I'm trying to get the active attribute (every entity in my data model has a common active attribute) for the NSManagedObject.
    – andrewbuilder
    Nov 13 '18 at 10:41






  • 1




    I think your entityActive should not be static: it's a property of Managed objects, not the Managed class. Your willDisplayCell code therefore needs to identify which Managed object is required - presumably using the indexPath to look up in the datasource.
    – pbasdf
    Nov 13 '18 at 10:55












  • 1




    Are you sure you can access a static variable using key-value coding? Shouldn't it be accessed as Managed.entity when it's static?
    – Joakim Danielson
    Nov 13 '18 at 6:33










  • @JoakimDanielson thanks for your question but honestly I'm not sure, I'm new to Swift and generics, self taught on Obj-C and always preferred blocks to protocols in Obj-C, so part of my problem may be a general and basic lack of understanding of static variables, protocols and KVC. (PS tried your suggestion but could not make it work.)
    – andrewbuilder
    Nov 13 '18 at 9:53







  • 1




    Per your extension, entity is an NSEntityDescription: there's no active property for NSEntityDescriptions which is why you get the error. Do you in fact mean to get the active attribute for the NSManagedObject?
    – pbasdf
    Nov 13 '18 at 10:39










  • @pbasdf correct, I'm trying to get the active attribute (every entity in my data model has a common active attribute) for the NSManagedObject.
    – andrewbuilder
    Nov 13 '18 at 10:41






  • 1




    I think your entityActive should not be static: it's a property of Managed objects, not the Managed class. Your willDisplayCell code therefore needs to identify which Managed object is required - presumably using the indexPath to look up in the datasource.
    – pbasdf
    Nov 13 '18 at 10:55







1




1




Are you sure you can access a static variable using key-value coding? Shouldn't it be accessed as Managed.entity when it's static?
– Joakim Danielson
Nov 13 '18 at 6:33




Are you sure you can access a static variable using key-value coding? Shouldn't it be accessed as Managed.entity when it's static?
– Joakim Danielson
Nov 13 '18 at 6:33












@JoakimDanielson thanks for your question but honestly I'm not sure, I'm new to Swift and generics, self taught on Obj-C and always preferred blocks to protocols in Obj-C, so part of my problem may be a general and basic lack of understanding of static variables, protocols and KVC. (PS tried your suggestion but could not make it work.)
– andrewbuilder
Nov 13 '18 at 9:53





@JoakimDanielson thanks for your question but honestly I'm not sure, I'm new to Swift and generics, self taught on Obj-C and always preferred blocks to protocols in Obj-C, so part of my problem may be a general and basic lack of understanding of static variables, protocols and KVC. (PS tried your suggestion but could not make it work.)
– andrewbuilder
Nov 13 '18 at 9:53





1




1




Per your extension, entity is an NSEntityDescription: there's no active property for NSEntityDescriptions which is why you get the error. Do you in fact mean to get the active attribute for the NSManagedObject?
– pbasdf
Nov 13 '18 at 10:39




Per your extension, entity is an NSEntityDescription: there's no active property for NSEntityDescriptions which is why you get the error. Do you in fact mean to get the active attribute for the NSManagedObject?
– pbasdf
Nov 13 '18 at 10:39












@pbasdf correct, I'm trying to get the active attribute (every entity in my data model has a common active attribute) for the NSManagedObject.
– andrewbuilder
Nov 13 '18 at 10:41




@pbasdf correct, I'm trying to get the active attribute (every entity in my data model has a common active attribute) for the NSManagedObject.
– andrewbuilder
Nov 13 '18 at 10:41




1




1




I think your entityActive should not be static: it's a property of Managed objects, not the Managed class. Your willDisplayCell code therefore needs to identify which Managed object is required - presumably using the indexPath to look up in the datasource.
– pbasdf
Nov 13 '18 at 10:55




I think your entityActive should not be static: it's a property of Managed objects, not the Managed class. Your willDisplayCell code therefore needs to identify which Managed object is required - presumably using the indexPath to look up in the datasource.
– pbasdf
Nov 13 '18 at 10:55












1 Answer
1






active

oldest

votes


















0














Thanks to those whose comments pointed me towards this solution...



My REVISED protocol Managed...



protocol Managed: class, NSFetchRequestResult 
static var entity: NSEntityDescription get
var attributeActive: Bool get // <-- REMOVED static



My REVISED extension of Managed...



UPDATE - added var attributeActive to Managed extension...



extension Managed where Self: NSManagedObject 
static var entity: NSEntityDescription return entity()

var attributeActive: Bool
guard let attribute = self.value(forKey: "active") as? Bool else
return false // in case key "active" is not set

return attribute




UPDATE - deleted var attributeActive from managed object extensions as no longer required...



My REVISED extensions for each of my three Core Data Entities (the data of which is displayed in each of the three separate UITableViewControllers)...



extension <<DataModelEntity>>: Managed 
public var attributeActive: Bool
return self.active


@NSManaged public var active: Bool
@NSManaged public var <<OTHER DATA MODEL ENTITY ATTRIBUTES>> //...
// ...etc.



Maybe it is worth noting here for clarity that the Codegen value for each entity in the data model is set to Manual/None, so I have manually1 prepared classes and extensions for each entity.



1 When I write manually, I mean that I used the Create Managed Object Subclass... function under the Editor menu in Xcode and then manually entered my Managed protocol stubs.



Finally, my REVISED generic data source delegate class...



class MyDataSource<T: Managed, 
Delegate: TableViewDataSourceDelegate>:
NSObject,
UITableViewDataSource,
UITableViewDelegate,
NSFetchedResultsControllerDelegate

// lots of code...

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

let object = fetchedResultsController.object(at: indexPath)
let objectActive = object.attributeActive

if objectActive == true
cell.textLabel?.textColor = UIColor.black
cell.detailTextLabel?.textColor = UIColor.darkGray
cell.backgroundColor = UIColor.white
else if entityObjectActive == false
cell.textLabel?.textColor = UIColor.lightGray
cell.detailTextLabel?.textColor = UIColor.lightGray
cell.backgroundColor = UIColor.clear



// lots more code...




If anyone is still reading this essay, maybe you're interested in the reasons for this solution?



Frankly I'm still figuring out the details myself and plan to add a more concise / accurate reason in the future as my understanding improves regarding swift generics, protocols and extensions, but for now I provide the following...



As pointed out in comments, I was incorrectly attempting to get an entity property based on a data model attribute from an entity description. This is like trying to get the colour or size of a Lego brick by asking the Lego box for the characteristics of one of it's bricks. "Which brick?" might the box ask, if Lego boxes could ask such a thing.



Essentially I made a couple of errors. I didn't understand the effect the static definition had on my variables and I didn't properly understand how my Managed protocol and extension interacted with any classes that adopted that protocol.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53271766%2fswift-generic-table-view-data-source-and-delegate-protocol-backed-nsmanagedobje%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Thanks to those whose comments pointed me towards this solution...



    My REVISED protocol Managed...



    protocol Managed: class, NSFetchRequestResult 
    static var entity: NSEntityDescription get
    var attributeActive: Bool get // <-- REMOVED static



    My REVISED extension of Managed...



    UPDATE - added var attributeActive to Managed extension...



    extension Managed where Self: NSManagedObject 
    static var entity: NSEntityDescription return entity()

    var attributeActive: Bool
    guard let attribute = self.value(forKey: "active") as? Bool else
    return false // in case key "active" is not set

    return attribute




    UPDATE - deleted var attributeActive from managed object extensions as no longer required...



    My REVISED extensions for each of my three Core Data Entities (the data of which is displayed in each of the three separate UITableViewControllers)...



    extension <<DataModelEntity>>: Managed 
    public var attributeActive: Bool
    return self.active


    @NSManaged public var active: Bool
    @NSManaged public var <<OTHER DATA MODEL ENTITY ATTRIBUTES>> //...
    // ...etc.



    Maybe it is worth noting here for clarity that the Codegen value for each entity in the data model is set to Manual/None, so I have manually1 prepared classes and extensions for each entity.



    1 When I write manually, I mean that I used the Create Managed Object Subclass... function under the Editor menu in Xcode and then manually entered my Managed protocol stubs.



    Finally, my REVISED generic data source delegate class...



    class MyDataSource<T: Managed, 
    Delegate: TableViewDataSourceDelegate>:
    NSObject,
    UITableViewDataSource,
    UITableViewDelegate,
    NSFetchedResultsControllerDelegate

    // lots of code...

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

    let object = fetchedResultsController.object(at: indexPath)
    let objectActive = object.attributeActive

    if objectActive == true
    cell.textLabel?.textColor = UIColor.black
    cell.detailTextLabel?.textColor = UIColor.darkGray
    cell.backgroundColor = UIColor.white
    else if entityObjectActive == false
    cell.textLabel?.textColor = UIColor.lightGray
    cell.detailTextLabel?.textColor = UIColor.lightGray
    cell.backgroundColor = UIColor.clear



    // lots more code...




    If anyone is still reading this essay, maybe you're interested in the reasons for this solution?



    Frankly I'm still figuring out the details myself and plan to add a more concise / accurate reason in the future as my understanding improves regarding swift generics, protocols and extensions, but for now I provide the following...



    As pointed out in comments, I was incorrectly attempting to get an entity property based on a data model attribute from an entity description. This is like trying to get the colour or size of a Lego brick by asking the Lego box for the characteristics of one of it's bricks. "Which brick?" might the box ask, if Lego boxes could ask such a thing.



    Essentially I made a couple of errors. I didn't understand the effect the static definition had on my variables and I didn't properly understand how my Managed protocol and extension interacted with any classes that adopted that protocol.






    share|improve this answer



























      0














      Thanks to those whose comments pointed me towards this solution...



      My REVISED protocol Managed...



      protocol Managed: class, NSFetchRequestResult 
      static var entity: NSEntityDescription get
      var attributeActive: Bool get // <-- REMOVED static



      My REVISED extension of Managed...



      UPDATE - added var attributeActive to Managed extension...



      extension Managed where Self: NSManagedObject 
      static var entity: NSEntityDescription return entity()

      var attributeActive: Bool
      guard let attribute = self.value(forKey: "active") as? Bool else
      return false // in case key "active" is not set

      return attribute




      UPDATE - deleted var attributeActive from managed object extensions as no longer required...



      My REVISED extensions for each of my three Core Data Entities (the data of which is displayed in each of the three separate UITableViewControllers)...



      extension <<DataModelEntity>>: Managed 
      public var attributeActive: Bool
      return self.active


      @NSManaged public var active: Bool
      @NSManaged public var <<OTHER DATA MODEL ENTITY ATTRIBUTES>> //...
      // ...etc.



      Maybe it is worth noting here for clarity that the Codegen value for each entity in the data model is set to Manual/None, so I have manually1 prepared classes and extensions for each entity.



      1 When I write manually, I mean that I used the Create Managed Object Subclass... function under the Editor menu in Xcode and then manually entered my Managed protocol stubs.



      Finally, my REVISED generic data source delegate class...



      class MyDataSource<T: Managed, 
      Delegate: TableViewDataSourceDelegate>:
      NSObject,
      UITableViewDataSource,
      UITableViewDelegate,
      NSFetchedResultsControllerDelegate

      // lots of code...

      func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

      let object = fetchedResultsController.object(at: indexPath)
      let objectActive = object.attributeActive

      if objectActive == true
      cell.textLabel?.textColor = UIColor.black
      cell.detailTextLabel?.textColor = UIColor.darkGray
      cell.backgroundColor = UIColor.white
      else if entityObjectActive == false
      cell.textLabel?.textColor = UIColor.lightGray
      cell.detailTextLabel?.textColor = UIColor.lightGray
      cell.backgroundColor = UIColor.clear



      // lots more code...




      If anyone is still reading this essay, maybe you're interested in the reasons for this solution?



      Frankly I'm still figuring out the details myself and plan to add a more concise / accurate reason in the future as my understanding improves regarding swift generics, protocols and extensions, but for now I provide the following...



      As pointed out in comments, I was incorrectly attempting to get an entity property based on a data model attribute from an entity description. This is like trying to get the colour or size of a Lego brick by asking the Lego box for the characteristics of one of it's bricks. "Which brick?" might the box ask, if Lego boxes could ask such a thing.



      Essentially I made a couple of errors. I didn't understand the effect the static definition had on my variables and I didn't properly understand how my Managed protocol and extension interacted with any classes that adopted that protocol.






      share|improve this answer

























        0












        0








        0






        Thanks to those whose comments pointed me towards this solution...



        My REVISED protocol Managed...



        protocol Managed: class, NSFetchRequestResult 
        static var entity: NSEntityDescription get
        var attributeActive: Bool get // <-- REMOVED static



        My REVISED extension of Managed...



        UPDATE - added var attributeActive to Managed extension...



        extension Managed where Self: NSManagedObject 
        static var entity: NSEntityDescription return entity()

        var attributeActive: Bool
        guard let attribute = self.value(forKey: "active") as? Bool else
        return false // in case key "active" is not set

        return attribute




        UPDATE - deleted var attributeActive from managed object extensions as no longer required...



        My REVISED extensions for each of my three Core Data Entities (the data of which is displayed in each of the three separate UITableViewControllers)...



        extension <<DataModelEntity>>: Managed 
        public var attributeActive: Bool
        return self.active


        @NSManaged public var active: Bool
        @NSManaged public var <<OTHER DATA MODEL ENTITY ATTRIBUTES>> //...
        // ...etc.



        Maybe it is worth noting here for clarity that the Codegen value for each entity in the data model is set to Manual/None, so I have manually1 prepared classes and extensions for each entity.



        1 When I write manually, I mean that I used the Create Managed Object Subclass... function under the Editor menu in Xcode and then manually entered my Managed protocol stubs.



        Finally, my REVISED generic data source delegate class...



        class MyDataSource<T: Managed, 
        Delegate: TableViewDataSourceDelegate>:
        NSObject,
        UITableViewDataSource,
        UITableViewDelegate,
        NSFetchedResultsControllerDelegate

        // lots of code...

        func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

        let object = fetchedResultsController.object(at: indexPath)
        let objectActive = object.attributeActive

        if objectActive == true
        cell.textLabel?.textColor = UIColor.black
        cell.detailTextLabel?.textColor = UIColor.darkGray
        cell.backgroundColor = UIColor.white
        else if entityObjectActive == false
        cell.textLabel?.textColor = UIColor.lightGray
        cell.detailTextLabel?.textColor = UIColor.lightGray
        cell.backgroundColor = UIColor.clear



        // lots more code...




        If anyone is still reading this essay, maybe you're interested in the reasons for this solution?



        Frankly I'm still figuring out the details myself and plan to add a more concise / accurate reason in the future as my understanding improves regarding swift generics, protocols and extensions, but for now I provide the following...



        As pointed out in comments, I was incorrectly attempting to get an entity property based on a data model attribute from an entity description. This is like trying to get the colour or size of a Lego brick by asking the Lego box for the characteristics of one of it's bricks. "Which brick?" might the box ask, if Lego boxes could ask such a thing.



        Essentially I made a couple of errors. I didn't understand the effect the static definition had on my variables and I didn't properly understand how my Managed protocol and extension interacted with any classes that adopted that protocol.






        share|improve this answer














        Thanks to those whose comments pointed me towards this solution...



        My REVISED protocol Managed...



        protocol Managed: class, NSFetchRequestResult 
        static var entity: NSEntityDescription get
        var attributeActive: Bool get // <-- REMOVED static



        My REVISED extension of Managed...



        UPDATE - added var attributeActive to Managed extension...



        extension Managed where Self: NSManagedObject 
        static var entity: NSEntityDescription return entity()

        var attributeActive: Bool
        guard let attribute = self.value(forKey: "active") as? Bool else
        return false // in case key "active" is not set

        return attribute




        UPDATE - deleted var attributeActive from managed object extensions as no longer required...



        My REVISED extensions for each of my three Core Data Entities (the data of which is displayed in each of the three separate UITableViewControllers)...



        extension <<DataModelEntity>>: Managed 
        public var attributeActive: Bool
        return self.active


        @NSManaged public var active: Bool
        @NSManaged public var <<OTHER DATA MODEL ENTITY ATTRIBUTES>> //...
        // ...etc.



        Maybe it is worth noting here for clarity that the Codegen value for each entity in the data model is set to Manual/None, so I have manually1 prepared classes and extensions for each entity.



        1 When I write manually, I mean that I used the Create Managed Object Subclass... function under the Editor menu in Xcode and then manually entered my Managed protocol stubs.



        Finally, my REVISED generic data source delegate class...



        class MyDataSource<T: Managed, 
        Delegate: TableViewDataSourceDelegate>:
        NSObject,
        UITableViewDataSource,
        UITableViewDelegate,
        NSFetchedResultsControllerDelegate

        // lots of code...

        func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

        let object = fetchedResultsController.object(at: indexPath)
        let objectActive = object.attributeActive

        if objectActive == true
        cell.textLabel?.textColor = UIColor.black
        cell.detailTextLabel?.textColor = UIColor.darkGray
        cell.backgroundColor = UIColor.white
        else if entityObjectActive == false
        cell.textLabel?.textColor = UIColor.lightGray
        cell.detailTextLabel?.textColor = UIColor.lightGray
        cell.backgroundColor = UIColor.clear



        // lots more code...




        If anyone is still reading this essay, maybe you're interested in the reasons for this solution?



        Frankly I'm still figuring out the details myself and plan to add a more concise / accurate reason in the future as my understanding improves regarding swift generics, protocols and extensions, but for now I provide the following...



        As pointed out in comments, I was incorrectly attempting to get an entity property based on a data model attribute from an entity description. This is like trying to get the colour or size of a Lego brick by asking the Lego box for the characteristics of one of it's bricks. "Which brick?" might the box ask, if Lego boxes could ask such a thing.



        Essentially I made a couple of errors. I didn't understand the effect the static definition had on my variables and I didn't properly understand how my Managed protocol and extension interacted with any classes that adopted that protocol.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 14 '18 at 22:00

























        answered Nov 14 '18 at 7:24









        andrewbuilderandrewbuilder

        2,2181633




        2,2181633



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53271766%2fswift-generic-table-view-data-source-and-delegate-protocol-backed-nsmanagedobje%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

            Museum of Modern and Contemporary Art of Trento and Rovereto