美文网首页码农的世界程序员
SPM开发的一个命令行工具——ModelMaker

SPM开发的一个命令行工具——ModelMaker

作者: e8b6cbadf7fb | 来源:发表于2018-05-05 18:27 被阅读19次

    在开发项目的过程中,必不可少地要创建Model,大部分时候都是对照着服务器返回的json来创建。一个property,一个property去写实在枯燥乏味,尤其是当字段量很大的时候,敲的都要怀疑人生了...。ModelMaker是用Swift Package Manager开发的一个命令行工具,只要指定好Json的文件路径,以及生成Model后要放置的目录,即可自动创建Model了,目前支持创建ObjC和Swift的Model。本文将介绍一下该脚本的实现思路,记录一下用SPM制作命令行工具的步骤。如果你感兴趣,可以在此基础上继续修改生成的Model的样子。

    实现思路

    Json这样的结构实际上是一棵多叉树,我们可以用递归把这棵树构造起来。每个节点是Model的一个Property,如果是叶子节点,该Property就是基本类型,如果节点下面还有节点,则该Property又是一个Model类型。通过遍历这棵树,拿到其下所有子节点大于0的节点,我们就知道了这个Json要生成多少个Model。画了一张对应图:

    <img src="/images/modelMaker.jpg" width="320" height="246">

    在构造这棵树的过程中,就可以得到每个Property的具体类型了,我这里定义的Node如下:

    class Node: NSObject {
        var name: String = ""    //属性的名称
        var type: String = ""    //属性的类型
        var childs: [Node] = []
        var level: Int = 0
        
        func createChildNodes(withDict data: [String: Any]) {}
    }
    

    node.type我这里可能是NSArray<ProductsModel *> *或者CustomerModel *,所以从node.type里拿到要创建的Model名称会绕一点。

    接下就是生成model文件到指定的磁盘位置了,我这里定义了一个全局的字典来保存一些文件模板,这样我们在拼接要生成的文件中的内容时,替换其中的变量就行了。

    源码地址:https://github.com/shinancao/ModelMaker

    使用

    > git clone https://github.com/shinancao/ModelMaker.git
    > cd ModelMaker
    > ./install.sh
    

    执行后,该脚本将被放在/usr/local/bin中,以后使用时:

    > modelmaker --json /Users/Shinancao/Desktop/test.json -d /Users/Shinancao/Desktop/modelFiles -t o
    

    把上面的参数换成你自己的哦~

    脚本中的参数说明:

    > modelmaker -h
      -h, --help:
          Print this help message.
      --json:
          Path of json file.
      -d, --dir:
          Directory to the output model files.
      -t, --model-type:
          model type operation - o for Objective-C, s for Swift. Default is Swift.
      -p, --prefix:
          Set prefix for generated models. Default is nothing.
      -s, --suffix:
          Set suffix for generated models. Default is "Model".
    

    <img src="/images/modelMaker2.PNG" width="320" height="126">

    SPM制作CommandLine Script

    • 创建项目文件夹(我这里创建的是TestSPM,所以下面出现该名称的地方,都将会是你自己的文件夹名),在该目录下执行:swift package init --type executable,执行完会生成以下文件:
    > swift package init --type executable
    Creating executable package: TestSPM
    Creating Package.swift
    Creating README.md
    Creating .gitignore
    Creating Sources/
    Creating Sources/TestSPM/main.swift
    Creating Tests/
    

    Package.swiftmain.swift是需要我们重点关注的两个文件,Package.swift中的代码如下:

    import PackageDescription
    
    let package = Package(
        name: "TestSPM",
        dependencies: [
            // Dependencies declare other packages that this package depends on.
            // .package(url: /* package url */, from: "1.0.0"),
        ],
        targets: [
            // Targets are the basic building blocks of a package. A target can define a module or a test suite.
            // Targets can depend on other targets in this package, and on products in packages which this package depends on.
            .target(
                name: "TestSPM",
                dependencies: []),
        ]
    )
    

    在这里可以配置项目依赖的第三方库,还有项目中的target。

    main.swift是可执行文件的入口,若在这里执行print("Hello, world!"),在运行脚本后就会在终端中打印出来。

    • 指定依赖的第三方库,比如这里我指定一个对命令行输入参数进行解析的库CommandLine,则在Package.swift中修改如下:
    dependencies: [
            // Dependencies declare other packages that this package depends on.
            .package(url: "https://github.com/jatoben/CommandLine", from: "3.0.0-pre1"),
        ],
    

    (swift的版本不同,这里的写法也会稍有不同,开发时注意一下就好)

    • 指定项目中的target,在Sources下的文件夹经编译后,如果其中有main.swift就会被当做可行文件,没有则会作为Framework。我们再Sources再添加一个文件夹TestSPMKit,同时在Package.swift中修改如下:
    targets: [
            // Targets are the basic building blocks of a package. A target can define a module or a test suite.
            // Targets can depend on other targets in this package, and on products in packages which this package depends on.
            .target(
                name: "TestSPMKit",
                dependencies: []),
            .target(
                name: "TestSPM",
                dependencies: ["TestSPMKit"])
        ]
    
    • 编译、运行脚本:
    > swift build
    > ./.build/debug/TestSPM
    Hello, world!
    
    • 生成xcodeproj:swift package generate-xcodeproj
    > swift package generate-xcodeproj
    generated: ./TestSPM.xcodeproj
    
    • 一个终端命令,通常需要一些参数,我们可以使用CommandLineKit这个第三库来处理,具体的使用可见CommandLineKit。如果要等待用户进行输入,可以使用readLine()函数。

    • 调用终端命令,可以通过Swift提供的Process来处理:

    public static func openFile(_ filePath: String) {
        let process = Process()
         process.launchPath = "/usr/bin/env"
         process.arguments = ["open", filePath]
         process.launch()
    }
    

    这里注意一下,arguments的第一个对象是命名名称,后面是需要的参数。

    --End--

    转载请注明出处:

    作者:意林

    原文链接:https://shinancao.cn/2018/04/29/Script-ModelMaker/

    相关文章

      网友评论

        本文标题:SPM开发的一个命令行工具——ModelMaker

        本文链接:https://www.haomeiwen.com/subject/qcjerftx.html