{"id":26777854,"url":"https://github.com/comiclandapp/stormcloud-master","last_synced_at":"2026-04-19T02:08:16.921Z","repository":{"id":282710104,"uuid":"949430675","full_name":"comiclandapp/Stormcloud-master","owner":"comiclandapp","description":"Backup of an old project from Simon Fairbairn","archived":false,"fork":false,"pushed_at":"2025-03-16T12:58:18.000Z","size":1196,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-02T06:07:06.892Z","etag":null,"topics":["coredata","icloud","json","swift"],"latest_commit_sha":null,"homepage":"https://github.com/SimonFairbairn","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/comiclandapp.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":"2025-03-16T12:58:16.000Z","updated_at":"2025-03-16T13:06:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"49bd36c7-2b37-41a8-94e2-db2ae69ce539","html_url":"https://github.com/comiclandapp/Stormcloud-master","commit_stats":null,"previous_names":["comiclandapp/stormcloud-master"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/comiclandapp/Stormcloud-master","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comiclandapp%2FStormcloud-master","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comiclandapp%2FStormcloud-master/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comiclandapp%2FStormcloud-master/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comiclandapp%2FStormcloud-master/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/comiclandapp","download_url":"https://codeload.github.com/comiclandapp/Stormcloud-master/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comiclandapp%2FStormcloud-master/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018785,"owners_count":26086452,"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-10-14T02:00:06.444Z","response_time":60,"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":["coredata","icloud","json","swift"],"created_at":"2025-03-29T05:18:14.492Z","updated_at":"2025-10-14T10:41:41.232Z","avatar_url":"https://github.com/comiclandapp.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"http://images.neverendingvoyage.com/github/StormcloudLogo.png\" width=\"400\" style=\"margin : 0 auto; display: block;\" /\u003e\n\nStormcloud is a way to convert and write JSON files and JPEG images to iCloud documents and back.\n\nIt also supports Core Data, converting a Core Data driven database to JSON and back—pass it an `NSManagedObjectContext` and it will read out all of the entities, attributes, and relationships, wrap them in a JSON document and upload that document to iCloud, where it can be restored on another device.\n\n## Usage\n\n```swift\nlet stormcloud = Stormcloud()\n```\n\nRegular JSON:\n\n\n```swift\nstormcloud.backupObjectsToJSON( objects : AnyObject, completion : (error : StormcloudError?, metadata : StormcloudMetadata?) -\u003e () ) {\n\n    if let hasError = error {\n        // Handle error\n    } \n\n    if let newMetadata = metadata {\n        print(\"Successfully added new document with filename: \\(metadata.filename)\")\n    }\n})\n\n```\n\nImage:\n\n```swift\n\nlet image = UIImage(named: \"YourImage\")\nstormcloud.addDocument( withData: image, for: .jpegImage ) { (error, stormcloudMetadata) in\n\n\tif let hasError = error {\n\t\t// Error creating document\n\t} else {\n\t\tprint(\"Successfully added new document with filename: \\(stormcloudMetadata!.filename)\")\n\t}\n}\n\n```\n\nRestoring \n\n```swift\nstormcloud.restoreBackup(withMetadata: metadataItem ) { (error, restoredObjects ) in\n    if let hasError = error {\n        // Handle error\n\t} else if let isImage = restoredObjects as? UIImage {\n\t\t// Do something with the image\n\t} else if let isJSON = restoredObjects as? [String : Any] {\n\t\t// Do something with the JSON\n\t}\n}\n```\n\n### Core Data\n\nManaged Object Context:\n\n\n```swift\nstormcloud.backupCoreDataEntities(inContext: self.managedObjectContext, completion: { (error, metadata) -\u003e () in\n\n    if let hasError = error {\n        // Handle error\n    } \n\n    if let newMetadata = metadata {\n        print(\"Successfully added new document with filename: \\(metadata.filename)\")\n    }\n\n})\n\n```\n\nRestoring \n\n```swift\nstormcloud.restoreCoreDataBackup(with : stormCloudMetadata, to context : NSManagedObjectContext,  completion : (error : StormcloudError?) -\u003e () ) {\n    if let hasError = error {\n        // Handle error here\n    }\n}\n```\n\n### Getting Items\n\n```swift\n\nlet jsonItems = stormcloud.items(for: .json)\t\t// Returns an array of metadata items\nlet images = stormcloud.items(for: .jpegImage) \t// Returns an array of metadata items\n\n```\n\n## Metadata\n\nStormcloud has its own metadata object that is used for both iCloud and local documents. If you're using iCloud, the metadata property `iCloudMetadata` will be set. The objects also have convenience properties detailing their current status (where they are (iCloud or local), whether they're uploading or downloading, etc).\n\n## Delegate\n\nStormcloud has a range of delegate methods.\n\n```swift\n// Called when a metadata item is updated in any way. Useful for getting downloading/uploading progress of items.\nfunc metadataDidUpdate(metadata : StormcloudMetadata,type : StormcloudDocumentType) {\n\n}\n\n// Called when the internal list changes\nfunc metadataListDidChange(manager : Stormcloud) {\n\n}\n\n// Called when items are added or deleted from the interal list. Here's an example of how this can be used with a table view with appropriate animations:\nfunc metadataListDidAddItemsAt( addedItems : IndexSet?, deletedItems: IndexSet?, type : StormcloudDocumentType) {\n\tself.tableView.beginUpdates()\n\n\tvar section : Int\n\tswitch type {\n\tcase .jpegImage:\n\t\tsection = 1\n\tdefault:\n\t\tsection = 0\n\t\t}\n\n\tif let didAddItems = addedItems {\n\t\tvar indexPaths : [IndexPath] = []\n\t\tfor additionalItems in didAddItems {\n\t\t\tindexPaths.append(IndexPath(row: additionalItems, section: section))\n\t\t}\n\t\tself.tableView.insertRows(at: indexPaths as [IndexPath], with: .automatic)\n\t}\n\n\tif let didDeleteItems = deletedItems {\n\t\tvar indexPaths : [IndexPath] = []\n\t\tfor deletedItems in didDeleteItems {\n\t\t\tindexPaths.append(IndexPath(row: deletedItems, section: section))\n\t\t}\n\t\tself.tableView.deleteRows(at: indexPaths as [IndexPath], with: .automatic)\n\t}\n\tself.tableView.endUpdates()\n\n}\n\n// Called when the file list first finishes loading. If you're using iCloud, the list will not be ready until the first\n// gathering of documents has completed. This method allows you to know when the list is ready to be used.\nfunc stormcloudFileListDidLoad( stormcloud : Stormcloud) {\n\n}\n```\n\n## Installation\n\nInstalling using CocaoPods\n\nTo begin using pods see: https://cocoapods.org.\nA minimal Podfile for Stormcloud could be:\n\n```\ntarget 'yourAppName'\nuse_frameworks!\n\npod 'Stormcloud'\n```\n\n\n## Environment Variables\n\nStormcloud supports environment variables for extra debugging and logging.\n\nEnvironment variables:\n\n`StormcloudDelayLocalFiles` - When set, the Local Files document provider will delay its initial gathering of the files. Allows you to simulate how iCloud's metadata gathering works without enabling iCloud.\n\n`StormcloudVerboseLogging` - Enables comprehensive logging for debugging.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomiclandapp%2Fstormcloud-master","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomiclandapp%2Fstormcloud-master","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomiclandapp%2Fstormcloud-master/lists"}