Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some tweaks to the machine.swift.motemplate #204

Merged
merged 3 commits into from
Jun 16, 2014
Merged

Some tweaks to the machine.swift.motemplate #204

merged 3 commits into from
Jun 16, 2014

Conversation

DaveWoodCom
Copy link
Contributor

Fixes a few issues I came across while trying out the swift modifications.

@grasmeyer
Copy link

I experienced the same problems, but I ended up implementing entityName as a class var. It makes the syntax cleaner, since you don't need the extra () for the method. Also, your update to the convenience init method has problems when using a base class. See the code below

class var entityName: String {
    return "<$name$>"
}

init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
}

convenience init(managedObjectContext: NSManagedObjectContext!) {
    let entity = NSEntityDescription.entityForName("<$name$>", inManagedObjectContext: managedObjectContext)
    self.init(entity: entity, insertIntoManagedObjectContext: managedObjectContext)
}

@grasmeyer
Copy link

I found a problem with the code listed in the comment above. Returning entityName as a class var won't work because Swift doesn't allow a class var to override more than one superclass declaration. This is a problem if the base class, an abstract entity, and a subentity all declare entityName as a class var. It works fine if we use a class method for entityName instead.

I solved this for now by adding the following class method to my base class:

class func nameOfEntity() -> String {
    return ""
}

Then I added the following to machine.swift.motemplate:

override class func nameOfEntity() -> String {
    return "<$name$>"
}

When I was doing this in Objective-C, I implemented the following class method in my base class:

+ (NSString *)entityName
{
return NSStringFromClass(self);
}

This won't work in Swift, because it returns the mangled class name. I haven't found a way to return the demangled class name dynamically from Swift (Radar: 17252482).

Even if I wasn't using a base class, the current Swift templates would still fail to compile, because the method declaration would need to be prefixed by "override" if the entity is a subentity of an abstract entity. This issue will apply to other function declarations in the Swift mogenerator template in the future as it evolves.

@DaveWoodCom
Copy link
Contributor Author

When I was looking at this last week, I was seeing lots of issues when using a base class.

I have a feeling it's going to be a bad idea to use a base class for managed objects in Swift. Because of the way Swift handles inheritance of init methods (i.e., if you include a designated init method in a subclass, none of the designated init's from the super class will be inherited). Also, the fact that you have to declare whether a subclass overrides a function (with the override keyword) based on whether the super class has it already or not, means a base class will have to conform to specific specs in order to not create conflicts with the mogenerated classes.

In Swift, we may have to avoid using a base class and instead use a protocol or something. I haven't got time right now to look into it further to confirm any of this, but will try on the weekend.

@grasmeyer
Copy link

Done. rdar://17252482

This would be unfortunate, since my base class implements quite a few convenience methods that I don't want to add to all of my mogenerator machine classes. One solution would be to have mogenerator automatically create a machine base class that includes the original declarations of all methods that will be overridden. Then you could add your own convenience methods to the human base class. This would require a new template, and changes to the source code. Another alternative might be to implement the convenience methods in an Extension of NSManagedObject.

@a2
Copy link
Contributor

a2 commented Jun 13, 2014

Bump

@a2 a2 mentioned this pull request Jun 16, 2014
@rentzsch rentzsch merged commit 6a5f27b into rentzsch:master Jun 16, 2014
@rentzsch
Copy link
Owner

Thanks for the patch @DaveWoodCom, sorry about the delay in merging it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants