{"id":15036266,"url":"https://github.com/squirrel/squirrel.mac","last_synced_at":"2025-05-15T20:00:59.448Z","repository":{"id":9638347,"uuid":"11570420","full_name":"Squirrel/Squirrel.Mac","owner":"Squirrel","description":":shipit: Cocoa framework for updating OS X apps :shipit:","archived":false,"fork":false,"pushed_at":"2023-06-22T10:29:37.000Z","size":16313,"stargazers_count":1614,"open_issues_count":65,"forks_count":129,"subscribers_count":45,"default_branch":"master","last_synced_at":"2025-05-09T21:33:48.636Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","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/Squirrel.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}},"created_at":"2013-07-22T01:12:31.000Z","updated_at":"2025-04-13T06:13:28.000Z","dependencies_parsed_at":"2024-01-13T17:12:37.522Z","dependency_job_id":"b9831367-b67d-4fe6-a64a-ad565d5048ed","html_url":"https://github.com/Squirrel/Squirrel.Mac","commit_stats":{"total_commits":919,"total_committers":20,"mean_commits":45.95,"dds":0.5081610446137106,"last_synced_commit":"0e5d146ba13101a1302d59ea6e6e0b3cace4ae38"},"previous_names":["github/squirrel"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Squirrel%2FSquirrel.Mac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Squirrel%2FSquirrel.Mac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Squirrel%2FSquirrel.Mac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Squirrel%2FSquirrel.Mac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Squirrel","download_url":"https://codeload.github.com/Squirrel/Squirrel.Mac/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414457,"owners_count":22067263,"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":[],"created_at":"2024-09-24T20:30:39.806Z","updated_at":"2025-05-15T20:00:59.168Z","avatar_url":"https://github.com/Squirrel.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Squirrel\n\nSquirrel is an OS X framework focused on making application updates **as safe\nand transparent as updates to a website**.\n\nInstead of publishing a feed of versions from which your app must select,\nSquirrel updates to the version your server tells it to. This allows you to\nintelligently update your clients based on the request you give to Squirrel.\nThe server can remotely drive behaviors like rolling back or phased rollouts.\n\nYour request can include authentication details, custom headers or a request\nbody so that your server has the context it needs in order to supply the most\nsuitable update.\n\nThe update JSON Squirrel requests should be dynamically generated based on\ncriteria in the request, and whether an update is required. Squirrel relies\non server side support for determining whether an update is required, see\n[Server Support](#server-support).\n\nSquirrel's installer is also designed to be fault tolerant, and ensure that any\nupdates installed are valid.\n\n![:shipit:](http://shipitsquirrel.github.io/images/ship%20it%20squirrel.png)\n\n# Adopting Squirrel\n\n1. Install xctool with `brew install xctool`\n1. Add the Squirrel repository as a git submodule\n1. Run `script/bootstrap` from within the submodule\n1. Add references to Squirrel.xcodeproj and its [dependencies](#dependencies) to\n   your project\n1. Add Squirrel.framework as a target dependency\n1. Link Squirrel.framework and add it to a Copy Files build phase which copies\nit into your Frameworks directory\n1. Ensure your application includes the [dependencies](#dependencies). Squirrel\ndoes not embed them itself.\n\nIf you’re developing Squirrel on its own, then use `Squirrel.xcworkspace`.\n\n# Dependencies\n\nSquirrel depends on [ReactiveCocoa](http://github.com/ReactiveCocoa/ReactiveCocoa)\nand [Mantle](https://github.com/Mantle/Mantle).\n\nIf your application is already using ReactiveCocoa, ensure it is using the same\nversion as Squirrel.\n\nOtherwise, add a target dependency and Copy Files build phase entry for the\nReactiveCocoa.framework target included in Squirrel's repository, in\n`Carthage/Checkouts/ReactiveCocoa`.\n\nSimilarly, ensure your application includes Mantle, or copies in the Squirrel\nversion.\n\nFinally, ensure your application's Runpath Search Paths (`LD_RUNPATH_SEARCH_PATHS`)\nincludes the directory that Squirrel.framework, ReactiveCocoa.framework\nand Mantle.framework are copied into.\n\n# Configuration\n\nOnce Squirrel is added to your project, you need to configure and start it.\n\n```objc\n#import \u003cSquirrel/Squirrel.h\u003e\n\n- (void)applicationDidFinishLaunching:(NSNotification *)notification {\n\tNSURLComponents *components = [[NSURLComponents alloc] init];\n\n\tcomponents.scheme = @\"https\";\n\tcomponents.host = @\"mycompany.com\";\n\tcomponents.path = @\"/myapp/latest\";\n\n\tNSString *bundleVersion = NSBundle.mainBundle.sqrl_bundleVersion;\n\tcomponents.query = [[NSString stringWithFormat:@\"version=%@\", bundleVersion] stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet]\n\n\tself.updater = [[SQRLUpdater alloc] initWithUpdateRequest:[NSURLRequest requestWithURL:components.URL]];\n\n\t// Check for updates every 4 hours.\n\t[self.updater startAutomaticChecksWithInterval:60 * 60 * 4];\n}\n```\n\nSquirrel will periodically request and automatically download any updates. When\nyour application terminates, any downloaded update will be automatically\ninstalled.\n\n## Update Requests\n\nSquirrel is indifferent to the request the client application provides for\nupdate checking. `Accept: application/json` is added to the request headers\nbecause Squirrel is responsible for parsing the response.\n\nFor the requirements imposed on the responses and the body format of an update\nresponse see [Server Support](#server-support).\n\nYour update request must *at least* include a version identifier so that the\nserver can determine whether an update for this specific version is required. It\nmay also include other identifying criteria such as operating system version or\nusername, to allow the server to deliver as fine grained an update as you\nwould like.\n\nHow you include the version identifier or other criteria is specific to the\nserver that you are requesting updates from. A common approach is to use query\nparameters, [Configuration](#configuration) shows an example of this.\n\n## Update Available Notifications\n\nTo know when an update is ready to be installed, you can subscribe to the\n`updates` signal on `SQRLUpdater`:\n\n```objc\n[self.updater.updates subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) {\n    NSLog(@\"An update is ready to install: %@\", downloadedUpdate);\n}];\n```\n\n## Installing Updates\n\nWhile downloaded updates are automatically installed when your application\nterminates, if don't want to wait you can manually terminate the app to begin\nthe installation process immediately.\n\nOnce an [update available notification](#update-available-notifications) has\nbeen received, you may want to present an interface informing the user about\nthe update and offering the ability to install and relaunch.\n\nTo explicitly install a downloaded update and automatically relaunch afterward,\nsubscribe to the `relaunchToInstallUpdate` signal on `SQRLUpdater`:\n\n```objc\n[[self.updater relaunchToInstallUpdate] subscribeError:^(NSError *error) {\n    NSLog(@\"Error preparing update: %@\", error);\n}];\n```\n\n# Server Support\n\nYour server should determine whether an update is required based on the\n[Update Request](#update-requests) your client issues.\n\nIf an update is required your server should respond with a status code of\n[200 OK](http://tools.ietf.org/html/rfc2616#section-10.2.1) and include the\n[update JSON](#update-server-json-format) in the body. Squirrel **will** download and\ninstall this update, even if the version of the update is the same as the\ncurrently running version. To save redundantly downloading the same version\nmultiple times your server must not inform the client to update.\n\nIf no update is required your server must respond with a status code of\n[204 No Content](http://tools.ietf.org/html/rfc2616#section-10.2.5). Squirrel\nwill check for an update again at the interval you specify.\n\n## Update Server JSON Format\n\nWhen an update is available, Squirrel expects the following schema in response\nto the update request provided:\n\n```json\n{\n\t\"url\": \"https://mycompany.example.com/myapp/releases/myrelease\",\n\t\"name\": \"My Release Name\",\n\t\"notes\": \"Theses are some release notes innit\",\n\t\"pub_date\": \"2013-09-18T12:29:53+01:00\"\n}\n```\n\nThe only required key is \"url\", the others are optional.\n\nSquirrel will request \"url\" with `Accept: application/zip` and only supports\ninstalling ZIP updates. If future update formats are supported their MIME type\nwill be added to the `Accept` header so that your server can return the\nappropriate format.\n\n\"pub_date\" if present must be formatted according to ISO 8601.\n\n## Update File JSON Format\n\nThe alternate update technique uses a plain JSON file meaning you can store your\nupdate metadata on S3 or another static file store. The format of this file is\ndetailed below:\n\n```json\n{\n\t\"currentRelease\": \"1.2.3\",\n\t\"releases\": [\n\t\t{\n\t\t\t\"version\": \"1.2.1\",\n\t\t\t\"updateTo\": {\n\t\t\t\t\"version\": \"1.2.1\",\n\t\t\t\t\"pub_date\": \"2013-09-18T12:29:53+01:00\",\n\t\t\t\t\"notes\": \"Theses are some release notes innit\",\n\t\t\t\t\"name\": \"1.2.1\",\n\t\t\t\t\"url\": \"https://mycompany.example.com/myapp/releases/myrelease\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"version\": \"1.2.3\",\n\t\t\t\"updateTo\": {\n\t\t\t\t\"version\": \"1.2.3\",\n\t\t\t\t\"pub_date\": \"2014-09-18T12:29:53+01:00\",\n\t\t\t\t\"notes\": \"Theses are some more release notes innit\",\n\t\t\t\t\"name\": \"1.2.3\",\n\t\t\t\t\"url\": \"https://mycompany.example.com/myapp/releases/myrelease3\"\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\n# User Interface\n\nSquirrel does not provide any GUI components for presenting updates. If you want\nto indicate updates to the user, make sure to [listen for downloaded\nupdates](#update-available-notifications).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquirrel%2Fsquirrel.mac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquirrel%2Fsquirrel.mac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquirrel%2Fsquirrel.mac/lists"}