{"id":1351,"url":"https://github.com/DrewKiino/Atlantis","last_synced_at":"2025-08-02T04:30:52.734Z","repository":{"id":56902524,"uuid":"46837183","full_name":"DrewKiino/Atlantis","owner":"DrewKiino","description":"A powerful input-agnostic swift logging framework made to speed up development with maximum readability.","archived":false,"fork":false,"pushed_at":"2018-04-10T23:49:23.000Z","size":1568,"stargazers_count":198,"open_issues_count":1,"forks_count":11,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-06-09T18:03:29.841Z","etag":null,"topics":[],"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/DrewKiino.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}},"created_at":"2015-11-25T04:22:34.000Z","updated_at":"2024-04-03T01:41:17.000Z","dependencies_parsed_at":"2022-08-20T18:50:30.747Z","dependency_job_id":null,"html_url":"https://github.com/DrewKiino/Atlantis","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/DrewKiino/Atlantis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrewKiino%2FAtlantis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrewKiino%2FAtlantis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrewKiino%2FAtlantis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrewKiino%2FAtlantis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DrewKiino","download_url":"https://codeload.github.com/DrewKiino/Atlantis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrewKiino%2FAtlantis/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334607,"owners_count":24233793,"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","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-01-05T20:15:44.441Z","updated_at":"2025-08-02T04:30:52.318Z","avatar_url":"https://github.com/DrewKiino.png","language":"Swift","funding_links":[],"categories":["Logging","Logger"],"sub_categories":["Other Hardware","Other free courses"],"readme":"![alt tag](https://github.com/DrewKiino/Atlantis/blob/master/Images/atlantis-logo.png?raw=true)\n\n\u003c!-- ![GitHub Logo](atlantis-screenshot.png) --\u003e\n\n# The Swift logging framework.\n\n`Atlantis` is an extremely powerful logging framework that I've created for everyday use, including enterprise development for aspiring start-ups or for rapid prototyping API's. It is **type agnostic**, meaning you can pass in anything from `strings` to custom`objects` that you yourself made... and it will basically **pretty print** all the values within that object or literally anything in general. It is made with exceptional readability and ease of use.\n\n### Installation\n\nAdd this to your [podfile](https://cocoapods.org/)...\n\n```\n# for Swift 4.0\npod 'Atlantis', :git =\u003e 'https://github.com/aaronjsutton/Atlantis.git', :branch =\u003e 'swift-4-patch'\n# for Swift 3.0\npod 'Atlantis'\n# for Swift 2.3\npod 'Atlantis', :git =\u003e 'https://github.com/DrewKiino/Atlantis.git', :branch =\u003e 'swift2.3'\n```\n\nThen do a pod install, and voila!\n\n## Unique Logs\nThis includes the stamp trace of the log's `date`, `source`, `function`, `line number`, as well as the **actual** `type` of the value.\n\n**Note**: *The date's format goes by month, date, year, hour, then time of day.*\n\n```swift\n// You do not need to initialize this, the variable is initialized in file.\nlet log = Atlantis.Logger()\n\n// Let's log some stuff\nlog.verbose(\"Hello, World!\")\nlog.info(\"Hello, World!\")\nlog.warning(\"Hello, World!\")\nlog.debug(\"Hello, World!\")\nlog.error(\"Hello, World!\")\n```\n\nWhich prints the following...\n\n![alt tag](https://github.com/DrewKiino/Atlantis/blob/master/Images/log-print-colors2.png?raw=true)\n\n## Powerful Printing\n\n`Atlantis` is built to `pretty print` literally everything.\n\n### - `proper text alignment`\n\n![alt tag](https://github.com/DrewKiino/Atlantis/blob/master/Images/proper-text-alignment.png?raw=true)\n\n`Atlantis` automatically aligns its logs based on it's previous alignments. However you can change this configuration by setting this variable,\n\n`Atlantis.Configuration.alignmentThreshold`\n\nwhich defaults to `5`.\n\n### - `optionals`\n\n`Atlantis` will safely unwrap any optionals.\n\n```swift\nlet doIExist: String? = nil\n\nlog.warning(doIExist)\n\n// prints 'nil'\n```\n\n### - `empty strings`\n\n`Atlantis` will visually print empty strings.\n\n```swift\nlet emptyString: String = \"\"\n\nlog.warning(emptyString)\n\n// prints \"\"\n```\n\n### - `native types`\n\n``` swift\nlet string = \"Hello, World\"\nlet int = 123\nlet double = 12.3\nlet float = 12.3\nlet bool = true\n\n// you can either log one value\nlog.debug(string)\n\n// or all of them like so,\nlog.debug(string, int, double, float, bool)\n\n// prints\n\"Hello, World\" // first one\n\n\"Hello, World\" // prints each with a new line\n123\n12.3\n12.3\ntrue\n```\n\n### - `arrays`\n```swift\n// array of ints\nlet numbers = [123, 1234, 12345]\n\nlog.debug(numbers)\n\n// prints\n[\n\t123,\n\t1234,\n\t12345\n]\n```\n```swift\n// lets try arrays of arrays\nlet numberArray = [[1, 2, 3], [4, 5]]\n\nlog.debug(numberArray)\n\n// prints\n[\n\t[\n\t\t1,\n\t\t2,\n\t\t3\n\t],\n\t[\n\t\t4,\n\t\t5\n\t]\n]\n```\n\n### - `dictionaries`\n\n```swift\n// on to dictionaries...\nlet dictionary: [String: AnyObject] = [\n\t\"quote\": \"It is better to have loved, than to have never loved at all?\"\n]\n\nlog.debug(dictionary)\n\n// prints\n[\n\t\"quote\": \"It is better to have loved, than to have never loved at all?\"\n]\n```\n\n```swift\n// how about NSDictionary types?\nvar dictionary = NSDictionary()\ndictionary.updateValue(\"will this work?\", key: \"question\")\n\nlog.debug(dictionary)\n\n// prints\n[\n\t\"question\": \"will  this work?\"\n]\n```\n\n```swift\n// say we got two response objects from the server,\n// now both objects are the same but one of them has missing data...\n\nresponses.map { log.debug($0) }\n\n// prints\n{\n\t\"response\": \"Here is some data!\",\n\t\"success\" 200\n},\n{\n\t\"response\": null,\n\t\"success\" 200\n}\n\n// Atlantis will print all of the object's keys regardless of missing\n// or empty values and will print null if need be.\n\n```\n\n### - `objects`\n```swift\n// now let's get to the fun part,\n```\n```swift\n// native Foundation (ex: UIView, UIColor, etc.)\n\nlog.debug(UIColor())\n\n// prints\n\u003cUIPlaceholderColor: 0x7ff1fb517ab0\u003e\n```\n\n```swift\n// native NSObjects\n\npublic class Dog: NSObject {\n  var name = \"Doug\"\n}\n\nlet dog = Dog()\n\nlog.debug(dog)\n\n// prints\n{\n\t\"name\": \"Doug\"\n}\n```\n``` swift\n// But what about objects you created with no native subclasses?\n\npublic class CustomObject {\n\tvar id: Int = 123\n\tvar name: String = \"Ben\"\n}\n\nlet customObject = CustomObject()\n\nlog.debug(customObject)\n\n// prints\n{\n\t\"id\": 123,\n\t\"name\": \"Doug\"\n}\n\n// Haha, no way?\n```\n\n```swift\n// Alright, well how about custom objects with custom objects in them?\n\npublic class ParentObject {\n\tvar id: Int = 456\n\tvar name: String = \"Tammy\"\n\tvar customObject: CustomObject = CustomObject()\n}\n\nlet parentObject = ParentObject()\n\nlog.debug(parentObject)\n\n// prints\n{\n\t\"id\": 456,\n\t\"name\": \"Tammy\"\n\t\"customObject\": {\n\t\t\"id\": 123,\n\t\t\"name\": \"Doug\"\n\t}\n}\n\n// That's right.\n```\n\n```swift\n// Okay, custom objects with an array of custom objects. ;)\n\npublic class ParentObject {\n\tvar id: Int = 456\n\tvar name: String = \"Tammy\"\n\tvar customObjects: [CustomObject] = [CustomObject(), CustomObject()]\n}\n\nlet parentObject = ParentObject()\n\nlog.debug(parentObject)\n\n// prints\n{\n\t\"id\": 456,\n\t\"name\": \"Tammy\"\n\t\"customObjects\": [\n\t\t{\n\t\t\t\"id\": 123,\n\t\t\t\"name\": \"Doug\"\n\t\t},\n\t\t{\n\t\t\t\"id\": 123,\n\t\t\t\"name\": \"Doug\"\n\t\t}\n\t]\n}\n```\n\n```swift\n// Not impressed?\n\nlet parentObject1 = ParentObject()\nlet parentObject2 = ParentObject() // one of its child has a dictionary\n\nlet parents: [ParentObject] = [parentObject1, parentObject2]\n\nlog.debug(parents)\n\n// prints\n[\n\t{\n\t\t\"id\": 456,\n\t\t\"name\": \"Tammy\"\n\t\t\"customObjects\": [\n\t\t\t{\n\t\t\t\t\"id\": 123,\n\t\t\t\t\"name\": \"Doug\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"id\": 123,\n\t\t\t\t\"name\": \"Doug\"\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\t\"id\": 456,\n\t\t\"name\": \"Tammy\"\n\t\t\"customObjects\": [\n\t\t\t{\n\t\t\t\t\"id\": 123,\n\t\t\t\t\"name\": \"Doug\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"id\": 123,\n\t\t\t\t\"name\": \"Doug\"\n\t\t\t\t\"dictionary\": [\n\t\t\t\t\t\"likes\": \"baseball\",\n\t\t\t\t\t\"dislikes\": \"pad thai\"\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t}\n]\n\n// Atlantis' logging is infinitely and ambiguously recursive,\n// it supports almost all data types including arrays, dictionaries,\n// and any objects within any objects. 👍🏼\n```\n\n### - `Structs`\n\n```swift\n// Great!! Now on to some more stand-alone but much needed types.\n\nstruct Struct {\n  var name: String = \"Bob the Builder\"\n  var skills: [String] = [\"structures, buildings\"]\n}\n\nlog.debug(Struct())\n\n// prints\n{\n  \"skills\" : [\n    \"structures, buildings\"\n  ],\n  \"name\" : \"Bob the Builder\"\n}\n```\n\n### - `Enum`\n\n```swift\nenum ErrorType {\n\tcase Severe\n\tcase Moderate\n\tcase Casual\n}\n\nlet type: ErrorType = .Severe\n\nlog.debug(type)\n\n// prints\nSevere\n```\n\n```swift\n// one more example.\n\nlog.debug(ErrorType.Moderate)\nlog.debug(ErrorType.Casual)\n\n// prints\nModerate\nCasual\n```\n\n## Error Handling\n\n`Atlantis` will print all errors like so,\n\n```swift\nError: [ViewController.swift/viewDidLoad()/line:98]\n{\n  \"code\" : 404,\n  \"localizedDescription\" : \"The operation couldn’t be completed. (Hello, World! error 404.)\",\n  \"domain\" : \"Hello, World!\",\n  \"userInfo\" : {\n  \t\"error\": \"found\"\n  \t\"note\": \"syntax\"\n  }\n}\n```\n\nIt will automatically parse the localized description, error code, domain, and user info from the `NSError` object.\n\n```swift\nAtlantis.Configuration.highlightsErrors // default false\n```\n\nBy default, `Atlantis` will print all logs equally in white or in color if colored logging is enabled. However, if you enable error highlighting it will always highlight errors regardless of any set parameters.\n\n```swift\nAtlantis.Configuration.filteredErrorCodes\n```\n\n`Atlantis` has the ability to filter out errors based on their error code. For example, you have a method that sends requests to the network and you made it so it can only make one request at a time so it will always cancel the last request made. However, some APIs are out of our control and will send out errors without your permission.\n\nSay you want to filter out error code `-1099 // offline error`,\n\n```swift\nAtlantis.Configuration.filteredErrorCodes.append(-1099)\n\n// let's call a method that throws errors, however one of the\n// errors is something we want to filter out.\nmethod() { error in\n\tlog.error(error) // can either be error 404 or -1099?\n}\n\n// will only print the error if the error code is 404\n```\n\nNow, if the method throws a `-1099` error, `Atlantis` will will skip over it!\n\n## .Tap\nTap is an `Atlantis` extension that allows you to print like how you would regularly do, but will return the value of the input.\n\n```swift\nfunc add(x: Int, _ y: Int) -\u003e Int { return x + y }\n\nlet addXY = log.tap.debug(add(3, 5))\n\n// prints 8 and assigns the value to addXY\n```\n\nNormal extensions such as ```.Verbose``` etc. are also under ```.Tap```\n\n#### Compatible with ```Promises```\n\nusing [PromiseKit](https://github.com/mxcl/PromiseKit) more specifically...\n\n```swift\nfunc promise() -\u003e Promise\u003cString\u003e {\n  return Promise { fulfill, reject in\n    // blah blah\n    fulfill(\"Hello from server!\")\n  }\n}\n\npromise()\n.then { log.tap($0) }\n.then { reply in\n  // blah blah\n}\n.catch { log.error($0) }\n\n// prints \"Hello from server!\" while completing the promise.\n```\nNote that `.Tap` can only take in single inputs.\n\n## Configuration\n#### Levels\n\n```swift\nAtlantis.Configuration.logLevel // default .Verbose\n```\n\nThe five log levels are: `Verbose`, `Info`, `Warning`, `Debug`, `Error`, and `None`, ordered by priority.\n\nFor example, if you set the log level to `Debug`, `Atlantis` will only print logs whose levels are `Debug` and `Error`.\n\nSetting the log level to `.None` means `Atlantis` will skip all log execution. I recommend using this when the app is shift off to production.\n\n#### Source Information\n\n```swift\nAtlantis.Configuration.showExtraInfo // default true\n```\n\nYou can also hide the source details by setting this parameter to false.\n\n#### Coloring\n\n`Atlantis` is able to provide full color customization,\n\n```swift\n// colors\nAtlantis.Configuration.hasColoredLogs // default false\nAtlantis.Configuration.hasWhiteBackground // default false\nAtlantis.Configuration.coloredLogLevels // default [.Verbose, .Info, .Warning, .Debug, .Error]\n\n// using a Tuple initializer\n\nAtlantis.Configuration.logColors.info = Atlantis.XCodeColor(fg: (Int, Int, Int)\u003e, bg: \u003c(Int, Int, Int)\u003e)\n\n// using UIColor setting only the foreground\n\nAtlantis.Configuration.logColors.info = Atlantis.XCodeColor(fg: UIColor)\n\n// or using UIColor setting both the foreground and background\n\nAtlantis.Configuration.logColors.debug = Atlantis.XCodeColor(fg: UIColor, bg: UIColor)\n```\n\nBy default, `Atlantis` doesn't print its logs in colors. if you want colors, you will need to set the configuration during launch.\n\nHowever, for you to enable log colors you will have to first download the xcode package manager [Alcatraz](http://alcatraz.io/) and enable it inside xcode. Pull up the package manager afterwards and install [XCodeColors](https://github.com/robbiehanson/XcodeColors).\n\n## Afterword\n### To Do\n1. ~~create a logging framework~~\n2. ~~add color customization~~\n3. print to a text file when used on a device\n4. ~~pretty print json types from server responses~~\n\n### License\nThe MIT License (MIT)\n\nCopyright (c) 2015 Andrew Aquino http://drewkiino.github.io/\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDrewKiino%2FAtlantis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDrewKiino%2FAtlantis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDrewKiino%2FAtlantis/lists"}