Giter Club home page Giter Club logo

reflection's Introduction

Reflection [DEPRECATED]

Swift License Slack Travis Codecov Codebeat

Reflection provides an API for advanced reflection at runtime including dynamic construction of types.

Usage

import Reflection

struct Person {
  var firstName: String
  var lastName: String
  var age: Int
}

// Reflects the instance properties of type `Person`
let props = try properties(Person.self)

var person = Person(firstName: "John", lastName: "Smith", age: 35)

// Retrieves the value of `person.firstName`
let firstName: String = try get("firstName", from: person)

// Sets the value of `person.age`
try set(36, key: "age", for: &person)

// Creates a `Person` from a dictionary
let friend: Person = try construct(dictionary: ["firstName" : "Sarah",
                                                "lastName" : "Gates",
                                                "age" : 28])

Installation

import PackageDescription

let package = Package(
    dependencies: [
        .Package(url: "https://github.com/Zewo/Reflection.git", majorVersion: 0, minor: 15),
    ]
)

Advanced Usage

// `Reflection` can be extended for higher-level packages to do mapping and serializing.
// Here is a simple `Mappable` protocol that allows deserializing of arbitrary nested structures.

import Reflection

typealias MappableDictionary = [String : Any]

enum Error : ErrorProtocol {
    case missingRequiredValue(key: String)
}

protocol Mappable {
    init(dictionary: MappableDictionary) throws
}

extension Mappable {

    init(dictionary: MappableDictionary) throws {
        self = try construct { property in
            if let value = dictionary[property.key] {
                if let type = property.type as? Mappable.Type, let value = value as? MappableDictionary {
                    return try type.init(dictionary: value)
                } else {
                    return value
                }
            } else {
                throw Error.missingRequiredValue(key: property.key)
            }
        }
    }

}

struct Person : Mappable {
    var firstName: String
    var lastName: String
    var age: Int
    var phoneNumber: PhoneNumber
}

struct PhoneNumber : Mappable {
    var number: String
    var type: String
}

let dictionary = [
    "firstName" : "Jane",
    "lastName" : "Miller",
    "age" : 54,
    "phoneNumber" : [
        "number" : "924-555-0294",
        "type" : "work"
    ] as MappableDictionary
] as MappableDictionary

let person = try Person(dictionary: dictionary)

Support

If you need any help you can join our Slack and go to the #help channel. Or you can create a Github issue in our main repository. When stating your issue be sure to add enough details, specify what module is causing the problem and reproduction steps.

Community

Slack

The entire Zewo code base is licensed under MIT. By contributing to Zewo you are contributing to an open and engaged community of brilliant Swift programmers. Join us on Slack to get to know us!

License

This project is released under the MIT license. See LICENSE for details.

reflection's People

Contributors

antonmes avatar bradhilton avatar danappelxx avatar heyzooi avatar ole avatar paulofaria avatar wickwirew avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reflection's Issues

Swift 4.1

Getting some crashes in Swift 4.1 around:

    var numberOfFields: Int {
        return Int(pointer.pointee.numberOfFields)
    }

in NominalTypeDescriptor, trying to dig into what may have changed but I think there was some memory layout changes!

Xcode 11 'Package Resolution failed' error

Add Package Dependency feature in Xcode 11 gives the following error:

The package dependency graph can not be resolved; unable find any available tag for the following requirements:

https://github.com/Zewo/Reflection.git โ€” 0.18.1..<1.0.0

and I found that advice given to a similar error:

I believe this is because you've missed out the products and targets section in the Package.swift file. A simple example can be found in JGProgressHUD's Packages.swift

Reflection of deep nested object

I have a complex classes of this type

`public class Info: Codable {

public var user: UserModel?
public var data: String?

}

public struct UserModel: Codable {
public var username: String?
public var name: String?
}`

I want to access sub properties in this way "user.info", is it possibile?

var obj = Info() let xxx: String? = try? get("user.info", from: obj)

Swift 4.2

The nominal type descriptor metadata is going away completely in 4.2. So there's no longer a way to get field names and types with the method this package uses. There is a new runtime method swift_getFieldAt to retrieve this data, however it uses C++ std::function and is not callable from Swift. You'd need to create a C++ wrapper that exposes a C API to use this. I've opened a PR on Swift to fix this (and make the method easily callable from Swift), but I'm not sure if they will do anything about it: apple/swift#15565. Thought I would share this info, thanks for the cool package!

Classes as well as Structs

Any chance this can work with classes as well as structs? If not, is it because the functionality isn't possible, or just needs a PR?

How to handle Default values?

What if I have a declaration of a struct like this?

struct Person {
    var firstName: String = "Max"
    var lastName: String = "Alexander"
    var age: Int = 12
    var phoneNumber: String = "4159300285"
}

But then I try to construct it using:

let person: Person = try! construct(dictionary: [:])

It'll tell me there are missing keys from the input dictionary. I understand the error. But what if the keys are missing and I prefer to construct it with their default values that I have declared above?

Is there any way to handle this sort of behavior?

Xcode 10.2 and Swift 5 problem building

Hi,

on Xcosw 10.2 and in particular with swift 5 there's a serious problem.
Here is:
Undefined symbols for architecture x86_64: "_swift_getFieldAt", referenced from: closure #1 (Swift.Int) -> (Swift.String, Any.Type) in (extension in Reflection):Reflection.NominalType.fieldNamesAndTypes(for: Any.Type) -> [(Swift.String, Any.Type)]? in NominalType.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

I've searched on google and found this blog post:

https://www.jishuwen.com/d/2Elq/zh-hk
alibaba/HandyJSON#307

Can you help?

Thanks.

'Hashable.hashValue' is deprecated as a protocol requirement

Swift Compiler Warning has occurred.

Message:

  • 'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'HashedType' to 'Hashable' by implementing 'hash(into:)' instead

File location:

  • Properties.swift / HashedType / hashValue

Crashes if classes inherit from NSObject.

If you try to reflect an instance of a class that inherits from NSObject, it will crash while accessing a null pointer when trying to reflect NSObject.

The minimal example would be:

class Foobar: NSObject {
    var stringProperty: String = "foobar"
}

let instance = Foobar()
try! properties(instance)

I have an example traceback in the attached screenshot. I tried with Swift 3.3 and Swift 4.1.

screen shot 2018-08-08 at 14 48 22

I see that there's already a workaround in the superclass reflection where we exclude the SwiftObject superclass:

guard let superclass = superclass, String(describing: unsafeBitCast(superclass.pointer, to: Any.Type.self)) != "SwiftObject" else {

Would it make sense to exclude the NSObject superclass in the same way? Or is reflecting on classes inherited from NSObject in general not supported?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.