{"id":22125096,"url":"https://github.com/songwentong/wtkit","last_synced_at":"2025-07-04T03:37:10.728Z","repository":{"id":56926939,"uuid":"60939735","full_name":"songwentong/WTKit","owner":"songwentong","description":"HTTP Codable Request/Swift extensions ","archived":false,"fork":false,"pushed_at":"2024-11-15T03:35:56.000Z","size":10136,"stargazers_count":50,"open_issues_count":0,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-26T00:03:22.714Z","etag":null,"topics":["chart","json","model","network","swift","uikit","webimage"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/songwentong.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-06-12T03:18:44.000Z","updated_at":"2024-11-15T03:36:00.000Z","dependencies_parsed_at":"2022-08-21T04:20:55.523Z","dependency_job_id":"a54e9417-2e98-4a56-90b9-9ecbdc278fad","html_url":"https://github.com/songwentong/WTKit","commit_stats":null,"previous_names":["swtlovewtt/wtkit"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/songwentong/WTKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songwentong%2FWTKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songwentong%2FWTKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songwentong%2FWTKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songwentong%2FWTKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/songwentong","download_url":"https://codeload.github.com/songwentong/WTKit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/songwentong%2FWTKit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261973725,"owners_count":23238586,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chart","json","model","network","swift","uikit","webimage"],"created_at":"2024-12-01T16:17:02.577Z","updated_at":"2025-06-26T00:04:10.423Z","avatar_url":"https://github.com/songwentong.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://github.com/songwentong/WTKit/actions?query=workflow%3Abuild\"\u003e\u003cimg src = \"https://github.com/songwentong/WTKit/workflows/build/badge.svg?branch=master\"\u003e\n\u003c/a\u003e\n[![Swift](https://img.shields.io/badge/Swift-5.3_5.4_5.5_5.6-orange?style=flat-square)](https://img.shields.io/badge/Swift-5.3_5.4_5.5_5.6-Orange?style=flat-square)\n![Platform](https://img.shields.io/badge/platform-iOS%20macOS%20tvOS%20watchOS-brightgreen)\n[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-Only-brightgreen?style=flat-square)](https://img.shields.io/badge/Swift_Package_Manager-only-brightgreen?style=flat-square)\n\n# WTKit\n\u003ca href=\"https://github.com/songwentong/WTKit/blob/master/Documentation/README_zhCN.md\"\u003e中文请看这里\u003c/a\u003e\nWTKit is my swift accumulated experience,I think WTKit could help you to improve development efficiency.\n## Features\n- [x] Codable extensions(JSON Decode with type-Adaption)\n- [x] cURL Command Output\n- [x] Making Codable Requests\n- [x] Simulation response data for test\n- [x] Load Web Image\n- [x] String to UIColor\n- [x] Table Model\n- [x] WTGradientView\n- [x] Base Hud View(text/indicator)\n- [x] Version track\n\n\n## Codable extensions(JSON Decode/enode, model creater)\n#### WTKit can create a swift model file from json\n#### type-Adaption decode json,WTKit resove JSONDecoder type mismatch error,and convert is to the type you need,like Int can decode from String/Double/Int, or String can decode from String/Double/Int \n#### Endocable/Decodable extensions,Decodable can decode from JSON,Encodable can map to json string\n```swift\n    func json1() -\u003e String {\n        let json1 = \"\"\"\n    {\n      \"intValue\": 3,\n      \"strValue\": \"3.8\",\n      \"double\": \"3.5\",\n      \"intList\": [\n        1,\n        2\n      ],\n      \"flag\": true,\n      \"doubleList\": [\n        1.1,\n        2.2\n      ],\n      \"object\": {\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Encoding\": \"gzip, deflate, br\",\n        \"Accept-Language\": \"zh-cn\",\n        \"Host\": \"httpbin.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15\",\n        \"X-Amzn-Trace-Id\": \"Root=1-5e716637-2f2252cc4747e55326ef4a08\"\n      },\n      \"objectList\": [\n        {\n          \"id\": 145,\n          \"title\": \"喜欢你\",\n          \"num\": \"4\",\n          \"pic\": \"https://img3.tuwandata.com/uploads/play/9766281560847422.png\"\n        },\n        {\n          \"id\": 148,\n          \"title\": \"么么哒\",\n          \"num\": \"3\",\n          \"pic\": \"https://img3.tuwandata.com/uploads/play/6851431563789324.png\"\n        }\n      ]\n    }\n    \"\"\"\n        return json1\n    }\n    \n    \n    ///Codable模型创建\n    ///给出一个class/struct名和json字符串，创建一个对应名字的class/struct\n    ///并写入Document目录\n    ///model处理了类型异常并转化，\n    ///Int类型如果收到了String会自动转化类型，反之亦然\n    ///对象类型和其他复杂类型也做了异常处理，不再抛出异常\n    func testModelCreate() {\n        let maker = WTModelMaker.default\n//        maker.needOptionalMark = false\n//        maker.useStruct = true\n        let className = \"TestModel\"\n        let classCode = maker.createModelWith(className: className, jsonString: json1())\n        print(NSHomeDirectory())\n//        print(classCode)\n        let path = NSHomeDirectory() + \"/Documents/\" + className + \".swift\"\n        print(path)\n        do {\n            try classCode.write(toFile: path, atomically: true, encoding: .utf8)\n#if os(macOS)\n            let url = path.urlValue\n            NSWorkspace.shared.activateFileViewerSelecting([url])\n            NSWorkspace.shared.selectFile(path, inFileViewerRootedAtPath: \"/\")\n#else\n#endif\n        } catch {\n            \n        }\n    }\n    \n     /**\n     test model Decode 测试数据解码\n     contains type error/key not found  包含了类型异常，字段异常\n     Int/Double/String     type error handle and transfer to type 异常处理\n     others decode no error throws\n     */\n    func testDecode() {\n        guard let obj2 = TestModel.decodeIfPresent(with: json1().utf8Data) else{\n            return\n        }\n        print(obj2.jsonString)\n    }\n```\n\n## Making Codable Requests\nWTKit provides a variety of convenience methods for making HTTP requests.\n\n```swift\npublic extension URLSession{\n    ///this method can make a urlrequest and convert result to Codable instance\n    func dataTaskWith\u003cT:Codable\u003e( request:URLRequest, testData:Data? = nil, codable object:@escaping (T)-\u003eVoid,completionHandler: @escaping (Data?, URLResponse?, Error?) -\u003e Void) -\u003e URLSessionDataTask{}\n}\npublic class HttpBin:NSObject, Codable {\n    var url:String = \"\"\n    var origin:String = \"\"\n    enum CodingKeys: String, CodingKey {\n        case url = \"url\"\n        case origin = \"origin\"\n    }\n}\nlet request = \"https://httpbin.org/get\".urlRequest\nlet task = WT.dataTaskWith(request:request,\n codable: { (model:HttpBin) in\n//model is parsed  Codable instance\n    print(\"\\(model)\")\n        }) { (data, res, err) in\n\n        }\ntask.resume()\n```\n\n## Simulation response data\n\nthis feature is only effect on DEBUG\n```swift\n//Simulation data\nlet simData =\n\"\"\"\n{\n  \"args\": {},\n  \"headers\": {\n    \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n    \"Accept-Encoding\": \"gzip, deflate, br\",\n    \"Accept-Language\": \"zh-cn\",\n    \"Host\": \"httpbin.org\",\n    \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15\",\n    \"X-Amzn-Trace-Id\": \"Root=1-5e716637-2f2252cc4747e55326ef4a08\"\n  },\n  \"origin\": \"123.112.227.96\",\n  \"url\": \"https://httpbin.org/get\"\n}\n\"\"\"\n\nlet req = \"https://httpbin.org\".urlRequest\n//if in DEBUG Mode,and testData != nil\n//the simulatedData will take effect\n\nWT.dataTaskWith(request: req, testData: simData,\n  codable: { (obj:HttpBin) in\n//in debug mode ,obj will parse from testData if not nil\n  }) { (data, res, err) in\n\n}\n\n```\n\n## cURL Command Output\n\nDebug tool\n```swift\nlet request = \"https://httpbin.org/get\".urlRequest\nprint(request.printer)\n```\nor you can print it in lldb:\n\n```swift\n(lldb) po request.printer\n```\n\n\nThis should produce:\n\n```swift\n$ curl -v \\\n-X GET \\\n-H \"Accept-Language: en;q=1.0\" \\\n-H \"Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8\" \\\n-H \"User-Agent: Demo/1.0 (com.demo.Demo; build:1; iOS 13.0.0) WTKit/1.0\" \\\n\"https://httpbin.org/get\"\n```\n![](https://github.com/songwentong/WTKit/blob/master/images/printer.png)\n\n## WTModelMaker\n\nWTModelMaker can create Codable model class/struct File from JSON Data\nhttps://github.com/songwentong/ModelMaker\nadditional Xcode App on Mac,using it to create Codable file Convenience,just copy your json ,edit class name,and press 'Write file',your file will create easily.\nand it will over write description and debugDescription automatic. this feature is very useful,swift default won't print properties for you(just like Model:\u003c0x00000f1231\u003e),if you print obj it will show you,if you want to see property values,just print it at lldb or print it.\nmodel using CodkingKeys by default,you can rename map easily.\n![](https://github.com/songwentong/WTKit/blob/master/images/modelMaker.png)\n\n\n### without description/debugDescription\n![](https://github.com/songwentong/WTKit/blob/master/images/noDesc.png)\n### with description/debugDescription\n![](https://github.com/songwentong/WTKit/blob/master/images/desc.png)\n```swift\nprint(obj)\n//or\n(lldb) po obj\n/**\n//output will be\nargs:debugDescription of args_class:\nurl:https://httpbin.org/get\nheaders:debugDescription of headers_class:\nAccept:text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\nHost:httpbin.org\nUser-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15\nAccept-Language:zh-cn\nAccept-Encoding:gzip, deflate, br\nX-Amzn-Trace-Id:Root=1-5e6b977f-43ebdc40121912f0bb6dc3d0\norigin:123.120.230.73\n*/\n```\n\n## Encodable extension\n\ncreate json data from encodable objec\n\n```swift\nlet obj:Encodable\nprint(obj.jsonString)\n//or\n(lldb) po obj.lldbPrint()\n//output will be json like this\n{\n  \"args\": {},\n  \"origin\": \"123.120.230.73\",\n  \"url\": \"https://httpbin.org/get\"\n}\n\n```\n\n## String hex color\n\n```swift\n\"f\".hexColor //white UIColor,it same as \"ffffff\"\n\"#3\".hexColor //same as 333333\n\"ff0000\".hexColor//red UIColor\n\"ff0000\".hexCGColor//red CGColor\n```\nmore:\n\n\n![](https://github.com/songwentong/WTKit/blob/master/images/color369.png)\n\n\n## WTGradientView\n\nAn UIView hold CAGradientView edit it's property will take effect on it's layer.\n\n```swift\nlet gview = WTGradientView()\ngview.colors = [\"f\".hexCGColor, \"990000\".hexCGColor]\ngview.locations = [0, 1]\ngview.startPoint = CGPoint(x: 0, y: 0.5)\ngview.endPoint = CGPoint(x: 1, y: 0.5)\n//it will effect on it's CAGradientView automatic\n```\n\n## UIView extension\n\n\n```swift\n//Cell reuse id,like it's class name\nlet reuseID:String = Cell.reuseIdentifier\nprint(\"\\(reuseID)\")\n//Cell\n\n//auto load it's nib file(if class name equal to xib file)\nlet nib:UINib = Cell.nib()\n\n//you can use this nib and reuseId to regist/dequeue use the cell\n```\n\n## HUD View\n```swift\n///normal tip\nview.showTextTip(text:\"tip\")\n///debug tip,show only in debug mode\nview.debugTip(text:\"tip\")\n```\neffect:\n![](https://github.com/songwentong/WTKit/blob/master/images/tipText.png)\n\n## Version Track\nfeature to log build history\n\n```swift\nfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -\u003e Bool {\n  application.track()//track twice no effect\n  application.versionHistory()//version history\n  application.buildHistory()//build history\n  application.isFirstLaunchForBuild//check is first build\n}\n\n```\n\n## WT Table Model\nThe abstract strategy for object-oriented development is used here, which is also the embodiment of the Model part in the MVC pattern.using Protocol oriented programming to describe UITableView as a Model,this will be more flexible,no class tree's constraint.\n```swift\n//cell model\npublic protocol UITableViewCellModel{\n    var reuseIdentifier: String{get set}\n    var object: Any?{get set}\n    var userInfo: [AnyHashable : Any]?{get set}\n}\n//section model\npublic protocol UITableViewSectionModel {\n    var cells:[UITableViewCellModel]{get set}\n}\n//table model\npublic protocol UITableViewModel {\n    var sections:[UITableViewSectionModel]{get set}\n}\n```\nmore\n```swift\n//you can use this protocol to describe some Cells more info\npublic protocol UITableViewCellDetailModel:UITableViewCellModel {\n    var height:CGFloat{get set}\n    var didSelectAction:DispatchWorkItem?{get set}\n    var willDisplayAction:DispatchWorkItem?{get set}\n    var prefetchAction:DispatchWorkItem?{get set}\n    var cancelPrefetchingAction:DispatchWorkItem?{get set}\n}\n```\n#### send data.\n#### these methods is suitable for all case using WTTableModel.\n```swift\npublic protocol UITableViewCellModelHolder {\n    var model:UITableViewCellModel?{get set}\n}\npublic extension UITableView{\n    func dequeueReusableCellModel(withModel model:UITableViewCellModel, for indexPath: IndexPath) -\u003e UITableViewCell {\n        let cell = dequeueReusableCell(withIdentifier: model.reuseIdentifier, for: indexPath)\n        if var c = cell as? UITableViewCellModelHolder{\n            c.model = model\n        }\n        return cell\n    }\n}\n```\n## UIView + Xib\ncreate UIView(or subclass) from nib,when you may want to reuse UIView in xib file, you can use it, I suggest you use UITableViewCell instead of UIVIew,because it has a contentVie w, no file's owner issue.\n```swift\nlet myView:MyView = MyView.instanceFromXib()\n//create MyView instance from xib file\n//usually use it as UITableViewCell sub class to avoid file owner issue\n```\n\n## UIViewController + IB\ncreate UIViewController instance from storyboard/nib\n```swift\nlet vc:CustromVC = CustromVC.instanceFromStoryBoard()\n//this func is create instance from you Storyboard's root VC\n\nlet vc2:CustromVC = CustromVC.instanceFromNib()\n//create instance from nib file\n```\n## Local Manager\n\nedit customBundle of Bundle can change local language easily\n```swift\n//using english\nBundle.customBundle = enUS\nprint(\"language\".customLocalizedString)\n//output will be\n//language\nprint(\"english\".customLocalizedString)\n//english\nBundle.customBundle = zhCN\nprint(\"language\".customLocalizedString)\n//output will be\n//语言\nprint(\"english\".customLocalizedString)\n//英语\n```\n\n\n## Installation\n### swift package manager\nFrom Xcode 11, you can use Swift Package Manager to add WTKit to your project.\n - Select File \u003e Swift Packages \u003e Add Package Dependency. Enter https://github.com/songwentong/WTKit.git in the \"Choose Package Repository\" dialog.\n - In the next page, specify the  rule as master branch\n - After Xcode checking out the source and resolving the version, you can choose the \"WTKit\" library and add it to your app target.\n```swift\nhttps://github.com/songwentong/WTKit.git\n```\nor\n```\n.package(url: \"https://github.com/songwentong/WTKit.git\", branch: \"master\"),\n```\n![](https://github.com/songwentong/WTKit/blob/master/images/swiftPackage.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsongwentong%2Fwtkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsongwentong%2Fwtkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsongwentong%2Fwtkit/lists"}