the way babel-plugin-transform-class-properties handle the properties - babeljs

why does babel-plugin-transform-class-properties add properties which the value is a function to the instance rather than the constructor's prototype?
class Bork {
//Property initializer syntax
instanceProperty = "bork";
boundFunction = () => {
return this.instanceProperty;
}
//Static class properties
static staticProperty = "babelIsCool";
static staticFunction = function() {
return Bork.staticProperty;
}
}
let myBork = new Bork;
//Property initializers are not on the prototype.
console.log(myBork.__proto__.boundFunction); // > undefined
//Bound functions are bound to the class instance.
console.log(myBork.boundFunction.call(undefined)); // > "bork"
//Static function exists on the class.
console.log(Bork.staticFunction()); // > "babelIsCool"
why the property "boundFunction" not on the prototype?

Related

Generic class call function

I am trying to create a wrapper for my API return wrapper class for my project.
these are my classes
class Wrapper<T> {
let message = "Hello World"
let wrapped = T.self
public func getData() -> T.Type {
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
class SecondObject {
let name = "Second Object"
public func getName() -> String {
return name
}
}
What I want to achieve is, is there any way I can call the Object function like this
let example = Wrapper<Object>()
example.getData().getNumber() // <<-- This is not working
let secondExample = Wrapper<SecondObject>()
secondExample.getData().getName() // <<-- This is not working
The error in my playground is this
error: instance member 'getNumber' cannot be used on type 'Object'
If you notice the Wrapper class, there is message property which will be used for all my API return object model
So my goal is, I could simply call the Wrapper class together with my object model class and just call the function that is inside the object model class.
I am still learning about generic in swift. What am I missing here?
You don't set wrapped to anything useful. You ned to set it to an instance of T. So you can pass a Tinto the constructor
class Wrapper<T>
{
let wrapped: T
init(wrapped: T)
{
self.wrapped = wrapped
}
}
Or you can have the class construct an instance of T, but if you want to do that, you need to tell it how to construct the instance. For example:
class Wrapper<T>
{
let wrapped: T
init()
{
self.wrapped = T() // << error!
}
}
won't work because the compiler knows nothing about T, not even if it has an init. You can change that with a protocol
protocol Initable
{
init()
}
class Wrapper<T: Initable>
{
let wrapped: T
init()
{
self.wrapped = T()
}
}
And you can apply the protocol to any type you like with an extension. In most cases the extension can be empty because mot types already have an init() method. For example:
class MyClass
{
init() { /* do stuff */ }
}
extension MyClass: Initable {}
class MyOtherClass
{
init(number: Int) { /* do stuff */ }
}
extension MyOtherClass: Initable
{
init() { self.init(number: 0) }
}
Another option is to supply a closure to the wrapper's init.
class Wrapper<T>
{
let wrapped: T
init(factory: ()-> T)
{
self.wrapped = factory()
}
}
let w = Wrapper() { return Array<Int>() }
Normally you'd only do this if you wanted to create multiple instances i.e. you'd keep a reference to the closure and call it each time you needed a new instance.
class Wrapper<T> {
private var wrapped: T // Storing your object of T type
init(value: T) { // init with instance of T
wrapped = value
}
public func getData() -> T { //returning instance of T
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
let o = Object()
let example = Wrapper(value: o) // Here we creating instance of Wrapper with instance of Object
example.getData().getNumber()
How about this , in your example changing the type of wrapped from non-optional to an optional variable type.
class Wrapper {
let message = "Hello World"
var wrapped : T?
public func getData() -> T? {
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
class SecondObject {
let name = "Second Object"
public func getName() -> String {
return name
}
}
and then using it as below
let example = Wrapper()
example.wrapped = Object()
let result1 = example.getData()?.getNumber() // ()
secondExample.wrapped = SecondObject()
let result2 = secondExample.getData()?.getName()
if let val1 = result1 , let val2 = result2 {
print("result1 = \(val1) result2 = \(val2)" )
}

How to initiate a singleton in Swift?

I have a class called HTTPHelper which is responsible for doing all my back end API requests. All methods in this class are class methods. As you know instance properties cannot be used from within a class method. I have some properties that need initialization with a do{}catch{} block which currently are being initiated from within an init(){} like so:
class HTTPHelper{
init(){
do {
//initiate property
} catch{}
}
}
My question is, is there a mechanism similar to an init(){} that would initiated a static property for a singleton?
You can assign a property to the result of a closure or function (note the = and () at the end to execute the closure—this is not the same as a computed property, where the value is re-created every time). Instead, the first time you access the property the value is lazily computed once using your function/closure and then stored in the property for future access.
class MyClass {
static let myProperty: String = {
do {
return try blah()
} catch {
// error handling
}
}()
}
Of course, this is just a special case of assigning the result of a function to a property:
class MyClass {
static let myProperty: String = MyClass.createMyString()
static func createMyString() -> String {
do {
return try blah()
} catch {
// error handling
}
}
}

is it possible to declare Computed property and Observers with class Label type?

I am new in swift anyone help me to understand
what is the purpose ? I should be used class label type !
is it possible to declare Computed property and Observers with class Label type ?
both ,either or neither ?
thank you
Type Properties can be created using either static or class keyword
Computed properties can be created using class as well as static keyword.
Property observers are not allowed using class keyword. They can only be used with static.
Example:
class First
{
class var x : Int{
return 3
}
static var y : Int{
return 2
}
// error: class stored properties not supported in classes
// class var z = 10 {
// willSet{
// print(newValue)
// }
// }
static var w = 30 {
willSet{
print(newValue)
}
}
}
Class Computed Property
You can declare a class computed property
class Foo {
class var p0: String { return "p0" }
}
Class Static Stored property
It is somehow possible but you need to use the static keyword
class Foo {
static var p0: String = "p0" {
didSet {
print("Did set p0")
}
}
}

Instance member cannot be used on type

I have the following class:
class ReportView: NSView {
var categoriesPerPage = [[Int]]()
var numPages: Int = { return categoriesPerPage.count }
}
Compilation fails with the message:
Instance member 'categoriesPerPage' cannot be used on type
'ReportView'
What does this mean?
Sometimes Xcode when overrides methods adds class func instead of just func. Then in static method you can't see instance properties. It is very easy to overlook it. That was my case.
You just have syntax error when saying = {return self.someValue}. The = isn't needed.
Use :
var numPages: Int {
get{
return categoriesPerPage.count
}
}
if you want get only you can write
var numPages: Int {
return categoriesPerPage.count
}
with the first way you can also add observers as set willSet & didSet
var numPages: Int {
get{
return categoriesPerPage.count
}
set(v){
self.categoriesPerPage = v
}
}
allowing to use = operator as a setter
myObject.numPages = 5
For anyone else who stumbles on this make sure you're not attempting to modify the class rather than the instance! (unless you've declared the variable as static)
eg.
MyClass.variable = 'Foo' // WRONG! - Instance member 'variable' cannot be used on type 'MyClass'
instanceOfMyClass.variable = 'Foo' // Right!
It is saying you have an instance variable (the var is only visible/accessible when you have an instance of that class) and you are trying to use it in the context of a static scope (class method).
You can make your instance variable a class variable by adding static/class attribute.
You instantiate an instance of your class and call the instance method on that variable.
Another example is, you have class like :
#obc class Album: NSObject {
let name:String
let singer:Singer
let artwork:URL
let playingSong:Song
// ...
class func getCurrentlyPlayingSongLyric(duration: Int = 0) -> String {
// ...
return playingSong.lyric
}
}
you will also get the same type of error like :
instance member x cannot be used on type x.
It's because you assign your method with "class" keyword (which makes your method a type method) and using like :
Album.getCurrentlyPlayingSongLyric(duration: 5)
but who set the playingSong variable before? Ok. You shouldn't use class keyword for that case :
// ...
func getCurrentlyPlayingSongLyric(duration: Int = 0) -> String {
// ...
return playingSong.lyric
}
// ...
Now you're free to go.
Your initial problem was:
class ReportView: NSView {
var categoriesPerPage = [[Int]]()
var numPages: Int = { return categoriesPerPage.count }
}
Instance member 'categoriesPerPage' cannot be used on type 'ReportView'
previous posts correctly point out, if you want a computed property, the = sign is errant.
Additional possibility for error:
If your intent was to "Setting a Default Property Value with a Closure or Function", you need only slightly change it as well. (Note: this example was obviously not intended to do that)
class ReportView: NSView {
var categoriesPerPage = [[Int]]()
var numPages: Int = { return categoriesPerPage.count }()
}
Instead of removing the =, we add () to denote a default initialization closure. (This can be useful when initializing UI code, to keep it all in one place.)
However, the exact same error occurs:
Instance member 'categoriesPerPage' cannot be used on type 'ReportView'
The problem is trying to initialize one property with the value of another. One solution is to make the initializer lazy. It will not be executed until the value is accessed.
class ReportView: NSView {
var categoriesPerPage = [[Int]]()
lazy var numPages: Int = { return categoriesPerPage.count }()
}
now the compiler is happy!
I kept getting the same error inspite of making the variable static.
Solution: Clean Build, Clean Derived Data, Restart Xcode. Or shortcut
Cmd + Shift+Alt+K
UserNotificationCenterWrapper.delegate = self
public static var delegate: UNUserNotificationCenterDelegate? {
get {
return UNUserNotificationCenter.current().delegate
}
set {
UNUserNotificationCenter.current().delegate = newValue
}
}
Just in case someone really needs a closure like that, it can be done in the following way:
var categoriesPerPage = [[Int]]()
var numPagesClosure: ()->Int {
return {
return self.categoriesPerPage.count
}
}

How to keep a reference to another object in the parameters of the class

I just start to learn Apple Swift language and can't understand:
How to keep a reference to another object in the parameters of class?
// List - my custom class
class RecordsList: NSObject {
var listObj: List!
init (inout list: List!)
{
self.listObj = list
}
func printData()
{
println(self.listObj.name)
}
}
var listObject = List()
listObject.name = "FirstValue"
RL = RecordsList(&listObject)
listObject.name = "SecondValue"
RL.printData()
// I expect: "SecondValue"
// But result: FirstValue =(
How can I get "SecondValue"?
In Swift objects are generally passed by reference, and only stuff like strings, ints, ... are passed by value... (Also structs are passed by value too!!!)
That means you don't need to create a special pointer to your object... If you just pass an object you already have set a pointer to the object (not a copy)
class TestClass {
var name: String?
}
class SecondTestClass {
var testClass: TestClass?
}
var testClass = TestClass()
var secondTestClass = SecondTestClass()
secondTestClass.testClass = testClass
testClass.name = "Worked"
var stringInObject = secondTestClass.testClass?.name
NSLog("\(stringInObject)")
And you are done :-)