{"id":28437083,"url":"https://github.com/flinedev/csvimporter","last_synced_at":"2025-06-29T15:04:28.991Z","repository":{"id":56586508,"uuid":"49782649","full_name":"FlineDev/CSVImporter","owner":"FlineDev","description":"Import CSV files line by line with ease","archived":false,"fork":false,"pushed_at":"2023-09-26T06:28:43.000Z","size":8527,"stargazers_count":152,"open_issues_count":10,"forks_count":29,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-06-05T23:08:38.806Z","etag":null,"topics":["csv","csv-files","data-mapping","header","importer","line-by-line"],"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/FlineDev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2016-01-16T17:09:37.000Z","updated_at":"2025-04-12T02:35:15.000Z","dependencies_parsed_at":"2024-06-19T01:53:02.272Z","dependency_job_id":"4db78c22-001a-461e-a429-9ba16cba9cd6","html_url":"https://github.com/FlineDev/CSVImporter","commit_stats":{"total_commits":145,"total_committers":7,"mean_commits":"20.714285714285715","dds":"0.33793103448275863","last_synced_commit":"4ddebf9ae6a929181418a4b230f03dafc8adef00"},"previous_names":["flinesoft/csvimporter"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/FlineDev/CSVImporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FCSVImporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FCSVImporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FCSVImporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FCSVImporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FlineDev","download_url":"https://codeload.github.com/FlineDev/CSVImporter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlineDev%2FCSVImporter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262327296,"owners_count":23294246,"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":["csv","csv-files","data-mapping","header","importer","line-by-line"],"created_at":"2025-06-05T23:08:38.481Z","updated_at":"2025-06-27T20:32:04.818Z","avatar_url":"https://github.com/FlineDev.png","language":"Swift","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"Logo.png\" width=600\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://app.bitrise.io/app/257039737afe71d1\"\u003e\n        \u003cimg src=\"https://app.bitrise.io/app/257039737afe71d1/status.svg?token=5IksJHfDRgFFmIFyTWMdxQ\u0026branch=stable\"\n             alt=\"Build Status\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codebeat.co/projects/github-com-flinesoft-csvimporter\"\u003e\n        \u003cimg src=\"https://codebeat.co/badges/c665ed7c-1f1b-45db-9602-9ac216327edf\"\n             alt=\"Codebeat Status\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Flinesoft/CSVImporter/releases\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Version-1.9.1-blue.svg\"\n             alt=\"Version: 1.9.1\"\u003e\n    \u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift-5.0-FFAC45.svg\"\n         alt=\"Swift: 5.0\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Platforms-iOS%20%7C%20tvOS%20%7C%20macOS%20%7C%20Linux-FF69B4.svg\"\n        alt=\"Platforms: iOS | tvOS | macOS | Linux\"\u003e\n    \u003ca href=\"https://github.com/Flinesoft/CSVImporter/blob/stable/LICENSE.md\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-MIT-lightgrey.svg\"\n              alt=\"License: MIT\"\u003e\n    \u003c/a\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://paypal.me/Dschee/5EUR\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/PayPal-Donate-orange.svg\"\n             alt=\"PayPal: Donate\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/sponsors/Jeehut\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/GitHub-Become a sponsor-orange.svg\"\n             alt=\"GitHub: Become a sponsor\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://patreon.com/Jeehut\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Patreon-Become a patron-orange.svg\"\n             alt=\"Patreon: Become a patron\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\n  • \u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\n  • \u003ca href=\"#donation\"\u003eDonation\u003c/a\u003e\n  • \u003ca href=\"https://github.com/Flinesoft/CSVImporter/issues\"\u003eIssues\u003c/a\u003e\n  • \u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\n  • \u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\n\u003c/p\u003e\n\n\n# CSVImporter\n\nImport CSV files line by line with ease.\n\n## Rationale\n\n\"Why yet another CSVImporter\" you may ask. \"There is already [SwiftCSV](https://github.com/naoty/SwiftCSV) and [CSwiftV](https://github.com/Daniel1of1/CSwiftV)\" you may say. The truth is that these frameworks work well for **smaller** CSV files. But once you have a really **large CSV file** (or *could* have one, because you let the user import whatever CSV file he desires to) then those solutions will probably cause **delays and memory issues** for some of your users.\n\n**CSVImporter** on the other hand works both **asynchronously** (prevents delays) and reads your CSV file **line by line** instead of loading the entire String into memory (prevents memory issues). On top of that it is **easy to use** and provides **beautiful callbacks** for indicating failure, progress, completion and even **data mapping** if you desire to.\n\n## Installation\n\nCurrently the recommended way of installing this library is via [Carthage](https://github.com/Carthage/Carthage) on macOS or [Swift Package Manager](https://github.com/apple/swift-package-manager) on Linux. [Cocoapods](https://github.com/CocoaPods/CocoaPods) might work, too, but is not tested.\n\nYou can of course also just include this framework manually into your project by downloading it or by using git submodules.\n\n## Usage\n\nPlease have a look at the UsageExamples.playground and the Tests/CSVImporterTests/CSVImporterSpec.swift files for a complete list of features provided.\nOpen the Playground from within the `.xcworkspace` in order for it to work.\n\n\n### Basic CSV Import\n\nFirst create an instance of CSVImporter and specify the type the data within a line from the CSV should have. The default data type is an array of `String` objects which would look like this:\n\n``` Swift\nlet path = \"path/to/your/CSV/file\"\nlet importer = CSVImporter\u003c[String]\u003e(path: path)\nimporter.startImportingRecords { $0 }.onFinish { importedRecords in\n    for record in importedRecords {\n        // record is of type [String] and contains all data in a line\n    }\n}\n```\n\nNote that you can specify an **alternative delimiter** when creating a `CSVImporter` object alongside the path. The delimiter defaults to `,` if you don't specify any.\n\n### Asynchronous with Callbacks\n\nCSVImporter works asynchronously by default and therefore doesn't block the main thread. As you can see the `onFinish` method is called once it finishes for using the results. There is also `onFail` for failure cases (for example when the given path doesn't contain a CSV file), `onProgress` which is regularly called and provides the number of lines already processed (e.g. for progress indicators). You can chain them as follows:\n\n``` Swift\nimporter.startImportingRecords { $0 }.onFail {\n\n    print(\"The CSV file couldn't be read.\")\n\n}.onProgress { importedDataLinesCount in\n\n    print(\"\\(importedDataLinesCount) lines were already imported.\")\n\n}.onFinish { importedRecords in\n\n    print(\"Did finish import with \\(importedRecords.count) records.\")\n\n}\n```\n\nBy default the real importing work is done in the `.utility` global background queue and callbacks are called on the `main` queue. This way the hard work is done asynchronously but the callbacks allow you to update your UI. If you need a different behavior, you can customize the queues when creating a CSVImporter object like so:\n\n``` Swift\nlet path = \"path/to/your/CSV/file\"\nlet importer = CSVImporter\u003c[String]\u003e(path: path, workQosClass: .background, callbacksQosClass: .utility)\n```\n\n### Import Synchronously\n\nIf you know your file is small enough or blocking the UI is not a problem, you can also use the synchronous import methods to import your data. Simply call `importRecords` instead of `startImportingRecords` and you will receive the end result (the same content as in the `onFinish` closure when using `startImportingRecords`) directly:\n\n``` Swift\nlet importedRecords = importer.importRecords { $0 }\n```\n\nNote that this method doesn't have any option to get notified about progress or failure – you just get the result. Check if the resulting array is empty to recognize potential failures.\n\n### Easy data mapping\n\nAs stated above the default type is a `[String]` but you can provide whatever type you like. For example, let's say you have a class like this\n\n``` Swift\nclass Student {\n  let firstName: String, lastName: String\n  init(firstName: String, lastName: String) {\n    self.firstName = firstName\n    self.lastName = lastName\n  }\n}\n```\n\nand your CSV file looks something like the following\n\n``` CSV\nHarry,Potter\nHermione,Granger\nRon,Weasley\n```\n\nthen you can specify a mapper as the closure instead of the `{ $0 }` from the examples above like this:\n\n``` Swift\nlet path = \"path/to/Hogwarts/students\"\nlet importer = CSVImporter\u003cStudent\u003e(path: path)\nimporter.startImportingRecords { recordValues -\u003e Student in\n\n    return Student(firstName: recordValues[0], lastName: recordValues[1])\n\n}.onFinish { importedRecords in\n\n    for student in importedRecords {\n        // Now importedRecords is an array of Students\n    }\n\n}\n```\n\n### Header Structure Support\n\nLast but not least some CSV files have the structure of the data specified within the first line like this:\n\n``` CSV\nfirstName,lastName\nHarry,Potter\nHermione,Granger\nRon,Weasley\n```\n\nIn that case CSVImporter can automatically provide each record as a dictionary like this:\n\n``` Swift\nlet path = \"path/to/Hogwarts/students\"\nlet importer = CSVImporter\u003c[String: String]\u003e(path: path)\nimporter.startImportingRecords(structure: { (headerValues) -\u003e Void in\n\n    print(headerValues) // =\u003e [\"firstName\", \"lastName\"]\n\n}) { $0 }.onFinish { importedRecords in\n\n    for record in importedRecords {\n        print(record) // =\u003e e.g. [\"firstName\": \"Harry\", \"lastName\": \"Potter\"]\n        print(record[\"firstName\"]) // prints \"Harry\" on first, \"Hermione\" on second run\n        print(record[\"lastName\"]) // prints \"Potter\" on first, \"Granger\" on second run\n    }\n\n}\n```\n\nNote: If a records values count doesn't match that of the first lines values count then the record will be ignored.\n\n\n## Donation\n\nBartyCrouch was brought to you by [Cihat Gündüz](https://github.com/Jeehut) in his free time. If you want to thank me and support the development of this project, please **make a small donation on [PayPal](https://paypal.me/Dschee/5EUR)**. In case you also like my other [open source contributions](https://github.com/Flinesoft) and [articles](https://medium.com/@Jeehut), please consider motivating me by **becoming a sponsor on [GitHub](https://github.com/sponsors/Jeehut)** or a **patron on [Patreon](https://www.patreon.com/Jeehut)**.\n\nThank you very much for any donation, it really helps out a lot! 💯\n\n\n## Contributing\n\nSee the file [CONTRIBUTING.md](https://github.com/Flinesoft/CSVImporter/blob/stable/CONTRIBUTING.md).\n\n\n## License\n\nThis library is released under the [MIT License](http://opensource.org/licenses/MIT). See LICENSE for details.\n","funding_links":["https://paypal.me/Dschee/5EUR","https://github.com/sponsors/Jeehut","https://patreon.com/Jeehut","https://paypal.me/Dschee/5EUR)*","https://www.patreon.com/Jeehut)*"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflinedev%2Fcsvimporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflinedev%2Fcsvimporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflinedev%2Fcsvimporter/lists"}