Swift initializing lazy value - swift

I have class
struct Word {
let text : String
let added: Date
let willShow: Date
let folder: Phase
let bestTranslation: String
let translationsProvider: ()->[String]
lazy var allTranslations : [String] = {self.translationsProvider()}()
}
and initializer
extension Word {
init(_ definition: Definition, context translationProvider:
#escaping ()->[String]){
self.text = definition.text!
self.added = definition.added!
self.willShow = definition.willShow!
self.folder = Phase(rawValue: definition.folder)!
self.bestTranslation = definition.best?.text ?? ""
self.translationsProvider = translationProvider
}
}
I'm getting error
Return from initializer without initializing all stored properties
with description
'self.allTranslations.storage' not initialized
How can I fix that?

I wonder if this is possibly a compiler bug. I don't see the same error you are getting, but this will create a Swift compiler segmentation fault 11:
struct Test {
let foo: String
lazy var bar: String = { return "" }()
}
extension Test {
init(_ foo: String) {
self.foo = foo
}
}

Related

How do I get the value of a Published<String> in swift without using debugDescription?

I've got the following code, that runs in a playground.
I'm attempting to allow subscript access to #Published variables in a class.
The only way I've found so far to retrieve the String value in the below implementation of
getStringValue
is to use the debugDescription, and pull it out -- I've looked at the interface for Published, but can't find any way to retrieve the value in a func like getStringValue
Any pointers would be greatly appreciated :)
Edited to include an example of how it works with a non-published variable.
Cheers
import Foundation
import Combine
protocol PropertyReflectable {}
extension PropertyReflectable {
subscript(key: String) -> Any? {
return Mirror(reflecting: self).children.first { $0.label == key }?.value
}
}
class Foo : PropertyReflectable {
#Published var str: String = "bar"
var str2: String = "bar2"
}
// it seems like there should be a way to get the Published value without using debugDescription
func getStringValue(_ obj: Combine.Published<String>?) -> String? {
if obj == nil { return nil }
let components = obj.debugDescription.components(separatedBy: "\"")
return components[1]
}
let f = Foo()
let str = getStringValue(f["_str"] as? Published<String>)
print("got str: \(str!)")
// str == "bar" as expected
let str2 = f["str2"]!
print("got non-published string easily: \(str2)")
Published seems to be steeped in some compiler magic, for lack of a better wording, since it can only be used as a property wrapper inside classes.
That being said, would something like this work?
final class PublishedExtractor<T> {
#Published var value: T
init(_ wrapper: Published<T>) {
_value = wrapper
}
}
func extractValue<T>(_ published: Published<T>) -> T {
return PublishedExtractor(published).value
}

Reflection in swift 2

I have a class User:
import UIKit
import ObjectMapper
class User: NSObject, CustomStringConvertible, Mappable {
var FirstName: NSString! ;
var LastName: NSString! ;
required init?(_ map: Map){
}
func mapping(map: Map) {
FirstName <- map["FirstName"]
LastName <- map["LastName"]
}
override var description:String {
var s:String=""
//USE REFLECTION TO GET NAME AND VALUE OF DATA MEMBERS
for var index=1; index<reflect(self).count; ++index {
s += (reflect(self)[index].0 + ": "+reflect(self)[index].1.summary+"\t")
}
return s
}
}
In swift 1.2, I was using reflect() method to get array of all the data members with their names and values.
Now, after I have updated to swift 2, I am getting the following error:
'reflect' is unavailable: call the 'Mirror(reflecting:)' initializer
With some trials, I was able to get the count of data members by this: Int(Mirror(reflecting: self).children.count), but still, I am unable to get the member name and its value.
I have looked into the following resources:
https://netguru.co/blog/reflection-swift
http://nshipster.com/mirrortype/
UPDATE
I have found the an answer here: https://stackoverflow.com/a/32846514/4959077. But this doesn't tell how to find out the type of reflected value. If the value is int and we parse it into String then it gives error.
You may access the reflected attribute "label" name, value and type as follows:
let mirror = Mirror(reflecting: SomeObject)
var dictionary = [String: Any]()
for child in mirror.children {
guard let key = child.label else { continue }
let value: Any = child.value
dictionary[key] = value
switch value {
case is Int: print("integer = \(anyValue)")
case is String: print("string = \(anyValue)")
default: print("other type = \(anyValue)")
}
switch value {
case let i as Int: print("• integer = \(i)")
case let s as String: print("• string = \(s)")
default: print("• other type = \(anyValue)")
}
if let i = value as? Int {
print("•• integer = \(i)")
}
}
Note: per the question followup, three approaches to determine the type of the reflected value are shown.
I have a solution that finds the name and type of a property given any class that inherits from NSObject.
I wrote a lengthy explanation on StackOverflow here, and my project is available here on Github,
In short you can do something like this (but really check out the code Github):
public class func getTypesOfProperties(inClass clazz: NSObject.Type) -> Dictionary<String, Any>? {
var count = UInt32()
guard let properties = class_copyPropertyList(clazz, &count) else { return nil }
var types: Dictionary<String, Any> = [:]
for i in 0..<Int(count) {
guard let property: objc_property_t = properties[i], let name = getNameOf(property: property) else { continue }
let type = getTypeOf(property: property)
types[name] = type
}
free(properties)
return types
}

get the type/class of a property from its name in swift

Lets say I have this class:
class Node {
var value: String
var children: [Node]?
}
If I have the name of one of its properties (for example "children") how can I get its type? (In this case [Node]?)
I imagine having a global function like below will solve my needs:
func typeOfPropertyWithName(name: String, ofClass: AnyClass) -> AnyClass? {
//???
}
// Example usage:
var arrayOfNodesClass = typeOfPropertyWithName("children", Node.self)
Swift 2 (Note: Reflection changed):
import Foundation
enum PropertyTypes:String
{
case OptionalInt = "Optional<Int>"
case Int = "Int"
case OptionalString = "Optional<String>"
case String = "String"
//...
}
extension NSObject{
//returns the property type
func getTypeOfProperty(name:String)->String?
{
let type: Mirror = Mirror(reflecting:self)
for child in type.children {
if child.label! == name
{
return String(child.value.dynamicType)
}
}
return nil
}
//Property Type Comparison
func propertyIsOfType(propertyName:String, type:PropertyTypes)->Bool
{
if getTypeOfProperty(propertyName) == type.rawValue
{
return true
}
return false
}
}
custom class:
class Person : NSObject {
var id:Int?
var name : String?
var email : String?
var password : String?
var child:Person?
}
get the type of the "child" property:
let person = Person()
let type = person.getTypeOfProperty("child")
print(type!) //-> Optional<Person>
property type checking:
print( person.propertyIsOfType("email", type: PropertyTypes.OptionalInt) ) //--> false
print( person.propertyIsOfType("email", type: PropertyTypes.OptionalString) //--> true
or
if person.propertyIsOfType("email", type: PropertyTypes.OptionalString)
{
//true -> do something
}
else
{
//false -> do something
}
Reflection is achieved in Swift using the global reflect() function. When passing an instance of some type to reflect() it returns a MirrorType, which has a range of properties allowing you to analyze your instance:
var value: Any { get }
var valueType: Any.Type { get }
var objectIdentifier: ObjectIdentifier? { get }
var count: Int { get }
var summary: String { get }
var quickLookObject: QuickLookObject? { get }
var disposition: MirrorDisposition { get }
subscript(i: Int) -> (String, MirrorType) { get }
This seems to work:
func getTypeOfVariableWithName(name: String, inInstance instance: Any) -> String? {
let mirror = reflect(instance)
var variableCollection = [String: MirrorType]()
for item in 0..<mirror.count {
variableCollection[mirror[item].0] = mirror[item].1
}
if let type = variableCollection[name] {
let longName = _stdlib_getDemangledTypeName(type.value)
let shortName = split(longName, { $0 == "."}).last
return shortName ?? longName
}
return nil
}
Here's some example code on SwiftStub.
Edit:
The result for optional values is only "Optional".
The result for arrays is only "Array".
The result for dictionaries is only "Dictionary".
I'm not sure if it is possible to extract what kind of optional/array/dictionary it is. But I guess this would also be the case for custom data structures using generics.
Building on #PeterKreinz answer I needed to be able to check types of inherited properties as well so added a little to his above code:
extension NSObject {
// Returns the property type
func getTypeOfProperty (name: String) -> String? {
var type: Mirror = Mirror(reflecting: self)
for child in type.children {
if child.label! == name {
return String(child.value.dynamicType)
}
}
while let parent = type.superclassMirror() {
for child in parent.children {
if child.label! == name {
return String(child.value.dynamicType)
}
}
type = parent
}
return nil
}
}
Hope this may help someone.
Swift 3 update:
// Extends NSObject to add a function which returns property type
extension NSObject {
// Returns the property type
func getTypeOfProperty (_ name: String) -> String? {
var type: Mirror = Mirror(reflecting: self)
for child in type.children {
if child.label! == name {
return String(describing: type(of: child.value))
}
}
while let parent = type.superclassMirror {
for child in parent.children {
if child.label! == name {
return String(describing: type(of: child.value))
}
}
type = parent
}
return nil
}
}
The solution provided by #peter-kreinz using Swift's class Mirror works beautifully when you have an instance of a class, and want to know the types of the properties. However if you want to inspect the properties of a class without having an instance of it you might be interested in my solution.
I have a solution that finds the name and type of a property given any class that inherits from NSObject.
I wrote a lengthy explanation on StackOverflow here, and my project is available here on Github,
In short you can do something like this (but really check out the code Github):
public class func getTypesOfProperties(inClass clazz: NSObject.Type) -> Dictionary<String, Any>? {
var count = UInt32()
guard let properties = class_copyPropertyList(clazz, &count) else { return nil }
var types: Dictionary<String, Any> = [:]
for i in 0..<Int(count) {
guard let property: objc_property_t = properties[i], let name = getNameOf(property: property) else { continue }
let type = getTypeOf(property: property)
types[name] = type
}
free(properties)
return types
}

Closure : Use unresolved identifier 'self'

I'm parsing the Swift Language Guide tutorial (from Apple iOS dev library) and for every chapter I create a separate swift file.
In each file I create multiple functions where I isolate snippets of code that they provide. Everything worked on until testing the Strong Reference Cycles for Closures.
For some reason if the class that contains a closure (for a computed property) is declared inside a function, then the closure cannot see the "self" reference of the enclosing class. Any ideas why ?
It works fine if the class is not declared inside a function.
func strongRefClosure() {
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
println("\(name) is being deinitialized")
}
}
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
println(paragraph!.asHTML())
}
Looks very much like a bug (or at least, a behaviour of function-local structs/classes I can’t find documented). This works fine:
struct Foo {
let someVal = 5
lazy var someLazy: String = {
return toString(self.someVal)
}()
}
var foo = Foo()
foo.someLazy // string "5"
But this doesn’t:
func outer() {
struct Foo {
let someVal = 5
lazy var someLazy: String = {
// error: use of unresolved identifier 'self'
return toString(self.someVal)
}()
}
var foo = Foo()
foo.someLazy
}
An inner struct inside an outer struct works, though:
struct Outer {
struct Foo {
let someVal = 5
lazy var someLazy: String = {
return toString(self.someVal)
}()
}
var foo = Foo()
}
var outer = Outer()
outer.foo.someLazy
As #JeremyP says, you should file a radar.
For me, I have this bug in XCode 8GM, Swift 3, iOS 10.0.
tl;dr
Closure-as-instance-property has bug
Closure-as-computed-property is cured!
Actual code
Buggy:
let permissionStatusHandler = { (status: CKApplicationPermissionStatus, error: Error?) in
switch status {
case .granted:
self.fetchUserRecordID() // Buggy: Use of unresolved identifier 'self'
case .initialState:
self.requestDiscoverability() // Buggy: Use of unresolved identifier 'self'
case .couldNotComplete:
error.then { print(#function, $0.localizedDescription) }
fallthrough
case .denied:
self.iCloud.presentiCloudAlert(for: status)
}
}
Kosher:
var permissionStatusHandler: (CKApplicationPermissionStatus, Error?) -> () { return
{ (status: CKApplicationPermissionStatus, error: Error?) in
switch status {
case .granted:
self.fetchUserRecordID()
case .initialState:
self.requestDiscoverability()
case .couldNotComplete:
error.then { print(#function, $0.localizedDescription) }
fallthrough
case .denied:
self.iCloud.presentiCloudAlert(for: status)
}
}
}
Hope this helps some other soul out there.

What is the Swift equivalent of -[NSObject description]?

In Objective-C, one can add a description method to their class to aid in debugging:
#implementation MyClass
- (NSString *)description
{
return [NSString stringWithFormat:#"<%#: %p, foo = %#>", [self class], foo _foo];
}
#end
Then in the debugger, you can do:
po fooClass
<MyClass: 0x12938004, foo = "bar">
What is the equivalent in Swift? Swift's REPL output can be helpful:
1> class MyClass { let foo = 42 }
2>
3> let x = MyClass()
x: MyClass = {
foo = 42
}
But I'd like to override this behavior for printing to the console:
4> println("x = \(x)")
x = C11lldb_expr_07MyClass (has 1 child)
Is there a way to clean up this println output? I've seen the Printable protocol:
/// This protocol should be adopted by types that wish to customize their
/// textual representation. This textual representation is used when objects
/// are written to an `OutputStream`.
protocol Printable {
var description: String { get }
}
I figured this would automatically be "seen" by println but it does not appear to be the case:
1> class MyClass: Printable {
2. let foo = 42
3. var description: String { get { return "MyClass, foo = \(foo)" } }
4. }
5>
6> let x = MyClass()
x: MyClass = {
foo = 42
}
7> println("x = \(x)")
x = C11lldb_expr_07MyClass (has 1 child)
And instead I have to explicitly call description:
8> println("x = \(x.description)")
x = MyClass, foo = 42
Is there a better way?
To implement this on a Swift type you must implement the CustomStringConvertible protocol and then also implement a string property called description.
For example:
class MyClass: CustomStringConvertible {
let foo = 42
var description: String {
return "<\(type(of: self)): foo = \(foo)>"
}
}
print(MyClass()) // prints: <MyClass: foo = 42>
Note: type(of: self) gets the type of the current instances instead of explicitly writing ‘MyClass’.
Example of using CustomStringConvertible and CustomDebugStringConvertible protocols in Swift:
PageContentViewController.swift
import UIKit
class PageContentViewController: UIViewController {
var pageIndex : Int = 0
override var description : String {
return "**** PageContentViewController\npageIndex equals \(pageIndex) ****\n"
}
override var debugDescription : String {
return "---- PageContentViewController\npageIndex equals \(pageIndex) ----\n"
}
...
}
ViewController.swift
import UIKit
class ViewController: UIViewController
{
/*
Called after the controller's view is loaded into memory.
*/
override func viewDidLoad() {
super.viewDidLoad()
let myPageContentViewController = self.storyboard!.instantiateViewControllerWithIdentifier("A") as! PageContentViewController
print(myPageContentViewController)
print(myPageContentViewController.description)
print(myPageContentViewController.debugDescription)
}
...
}
Which print out:
**** PageContentViewController
pageIndex equals 0 ****
**** PageContentViewController
pageIndex equals 0 ****
---- PageContentViewController
pageIndex equals 0 ----
Note: if you have a custom class which does not inherit from any class included in UIKit or Foundation libraries, then make it inherit of NSObject class or make it conform to CustomStringConvertible and CustomDebugStringConvertible protocols.
Just use CustomStringConvertible and var description: String { return "Some string" }
works in Xcode 7.0 beta
class MyClass: CustomStringConvertible {
var string: String?
var description: String {
//return "MyClass \(string)"
return "\(self.dynamicType)"
}
}
var myClass = MyClass() // this line outputs MyClass nil
// and of course
print("\(myClass)")
// Use this newer versions of Xcode
var description: String {
//return "MyClass \(string)"
return "\(type(of: self))"
}
The answers relating to CustomStringConvertible are the way to go. Personally, to keep the class (or struct) definition as clean as possible, I would also separate out the description code into a separate extension:
class foo {
// Just the basic foo class stuff.
var bar = "Humbug!"
}
extension foo: CustomStringConvertible {
var description: String {
return bar
}
}
let xmas = foo()
print(xmas) // Prints "Humbug!"
class SomeBaseClass: CustomStringConvertible {
//private var string: String = "SomeBaseClass"
var description: String {
return "\(self.dynamicType)"
}
// Use this in newer versions of Xcode
var description: String {
return "\(type(of: self))"
}
}
class SomeSubClass: SomeBaseClass {
// If needed one can override description here
}
var mySomeBaseClass = SomeBaseClass()
// Outputs SomeBaseClass
var mySomeSubClass = SomeSubClass()
// Outputs SomeSubClass
var myOtherBaseClass = SomeSubClass()
// Outputs SomeSubClass
As described here, you can also use Swift's reflection capabilities to make your classes generate their own description by using this extension:
extension CustomStringConvertible {
var description : String {
var description: String = "\(type(of: self)){ "
let selfMirror = Mirror(reflecting: self)
for child in selfMirror.children {
if let propertyName = child.label {
description += "\(propertyName): \(child.value), "
}
}
description = String(description.dropLast(2))
description += " }"
return description
}
}
struct WorldPeace: CustomStringConvertible {
let yearStart: Int
let yearStop: Int
var description: String {
return "\(yearStart)-\(yearStop)"
}
}
let wp = WorldPeace(yearStart: 2020, yearStop: 2040)
print("world peace: \(wp)")
// outputs:
// world peace: 2020-2040