Skip to content

Instantly share code, notes, and snippets.

@pixlwave
Last active August 29, 2015 14:15
Show Gist options
  • Save pixlwave/5a635b6070faccb1cdf8 to your computer and use it in GitHub Desktop.
Save pixlwave/5a635b6070faccb1cdf8 to your computer and use it in GitHub Desktop.
Swift style initializers for RubyMotion
class NSObject
def self.with(args = {})
args.count == 0 ? method = "init" : method = "initWith"
objc_args = []
args.each do |a|
a[0] = a[0][0].capitalize + a[0][1..-1] if objc_args.size < 1
method << a[0] << ":"
objc_args << a[1]
end
self.alloc.send(method, *objc_args)
end
end
@colinta
Copy link

colinta commented Feb 13, 2015

Actually, initialize is not usually called on Obj-C built-in classes. You could try overriding def self.new. new is an objective-c method. But I've seen this cause pretty bad errors when including cocoapods that rely on the default new method. Plus, by default new doesn't take any arguments - you should at least support that by providing args={}.

In the end, though, I would be very careful, these extensions can be risky.

@henderea
Copy link

Maybe you could do something like this:

class NSObject

  #feel free to come up with a better name as long as it isn't "new"
  #snew (short for swift_new) is just a name i came up with
  def self.snew(args = {})
    args.count == 0 ? methods = "init" : method = "initWith"
    objc_args = []

    args.each do |a|
      a[0] = a[0][0].capitalize + a[0][1..-1] if objc_args.size < 1

      method << a[0] << ":"
      objc_args << a[1]
    end

    self.alloc.send(method, *objc_args)
  end

end

@pixlwave
Copy link
Author

Ok, taking both comments on board, I've stopped using initialize and am now using self.with. So you call

label = UILabel.with(frame: [[50, 100], [100, 30]])
color = UIColor.with(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.9)

Which actually reads better anyway 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment