{"id":18334770,"url":"https://github.com/importryan/gif-addict","last_synced_at":"2025-10-26T02:02:45.627Z","repository":{"id":77156608,"uuid":"455446958","full_name":"importRyan/GIF-Addict","owner":"importRyan","description":"Quick demo macOS app","archived":false,"fork":false,"pushed_at":"2022-02-11T18:45:07.000Z","size":5245,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T19:47:03.221Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/importRyan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2022-02-04T06:38:23.000Z","updated_at":"2022-04-20T23:32:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"7674728e-042a-4ef1-99c3-966163db7e81","html_url":"https://github.com/importRyan/GIF-Addict","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/importRyan/GIF-Addict","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/importRyan%2FGIF-Addict","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/importRyan%2FGIF-Addict/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/importRyan%2FGIF-Addict/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/importRyan%2FGIF-Addict/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/importRyan","download_url":"https://codeload.github.com/importRyan/GIF-Addict/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/importRyan%2FGIF-Addict/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271712233,"owners_count":24807755,"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-22T02:00:08.480Z","response_time":65,"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-11-05T19:52:21.758Z","updated_at":"2025-10-26T02:02:45.579Z","avatar_url":"https://github.com/importRyan.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"| [About](#about)  | [Project Contents](#repo-contents) | [Faults \u0026 Next Steps](#faults-and-next-steps) | [Assignment](#assignment-recap) | [Test Flight / Build Instructions](#installation) |\n| ------------- | ------------- |  ------------- | ------------- | ------------- | \n\n#  GIF Addict (Interview Project)\n\nhttps://user-images.githubusercontent.com/78187398/153201092-4d865592-49c8-4e96-b55a-04d7149ea8d1.mp4\n\n## About\n\n#### Premise\nSharing funny GIFs has long been one of the killer features of the internet, MMS, and all the MySpace children like Facebook. Yet, the actual process of searching for a GIF is often a lonesome scrolling task for one.\n\n#### Weekend Product\nPer assignment, GIF Addict hits the GIPHY API. It also explores SharePlay as a way to socially scroll the hoards of GIFs with friends. Try to guess the search term your friend used for their favorite pick.\n\n---\n\n## Repo Contents\n\nThis simple \"display images\" app spans a few small packages. The logic, persistence, and remote service packages do not reference each other. The `Addictive Services` package resolves dependencies for the macOS app.\n\n| Package  | Utility | Dependencies |\n|:-------------|:-------------|:-------------|\n| **Addiction**  | Logic  | `Combine`, `SharePlay` |\n| **AddictiveCoreData**  | Cloud and in-memory stores (local content service)  | `CoreData` |\n| **Giphy**  | Remote mirthful content service  | `Combine`, signature of `URLSession.DataTaskPublisher` |\n| **Addictive** Services | Composes dependencies  | Addiction, AddictiveCoreData, Giphy, `Combine` |\n| **SharedUI**  | Fonts, colors, conveniences  | SwiftUI |\n| **GIF Addict App** | Mac only  | Addiction, AddictiveServices, SharedUI, `Nuke`, `AppKit`, `Combine`, `SwiftUI` |\n\n\n### Directories\n\n```\n/Addiction\n```\n *  `/Protocols`. Abstracted `ContentService`s, of both remote and local derivatives, deliver search queries to the app. \n * `/UseCases` Creating a search, listing results, rating a GIF, and coordinating SharePlay are each separate `UseCase` protocols.\n * `/App` Simple objects that privately wire up services and vend use cases.\n * Testing strategy: unit tests and use case integration tests\n\n```\n/AddictiveServices\n```\n * Maps package and logic models\n * Testing strategy: Integration tests\n\n```\n/AddictiveCoreData\n```\n * Simplistic schema and API similar to Giphy\n * NSManagedObjects are not exposed publicly\n * Testing strategy: Unit and in-memory behavioral tests\n\n```\n/Giphy\n```\n * Testing strategy: unit tests, mock URLSession, and live API tests\n\n```\n/SharedUI\n```\n * Contains SwiftUI conveniences, .colorsets and thematic/dyslexic fonts, such as the colorful Gilbert SBIX font\n\n```\n/Shared (macOS / iPad app)\n```\n * SwiftUI views depend upon generic use case protocols\n * Single-scene app, with three `/Screens` (splash, main, and focus popover)\n * A screen arranges `/Views`, such as search bar or content grid\n * `/Components` are reusable base views, like a rating button, without any protocol dependencies\n * Localization for English and Chinese\n * Testing strategy: View model unit tests, basic UI tests\n \n```\nDeployment\n```\n  * Automatic to TestFlight via Xcode Cloud workflow\n  \n---\n\n## Faults and Next Steps\n\nTo paraphrase Graham McCarthy, Rome wasn't build by some guy in a weekend. Some unfinished business and next steps include:\n\n1. Performance improvements\n- Image prefetching ahead of scroll direction to remove \"blank spaces\" loading delays on fast scroll\n- Memory footprint builds past expectations for in memory caches (URLSession, Nuke). Resetting the view hierarchy helps, suggesting some interplay with LazyVGrid's recycling strategy and Nuke's video layers. Investigation needed.\n- Likely related to #2, leaks appear on Apple Silicon, but not Intel, with same OS and Xcode environment. (12.3 beta 21E5196i)\n\n2. SharePlay\n- Refactor it into a testable service package\n- Prepare for users on multiple versions: wrap model in versioning containers\n- Explore gamification modes\n- Track history of all GIFs shared\n- Display friend's ratings too\n- Mini map of position in results scroll / \"follow\" specific users as they scroll\n\n3. Testing\n- Round out gaps in testing battery, particularly logic layer and performance testing of collection view scrolls\n\n4. Accessibility\n- Dyslexia-friendly font replacements\n- VoiceOver testing and adaptations\n \n---\n\n## Assignment Recap\n\nCreate a macOS or iOS app that can search, save, rank, and sort animated GIFs. Deliver at least one day prior to interview as a GitHub repo.\n\n#### Scope \u0026 Requirements\n- [x] Use Giphy's API to search for tags and display a paged list of GIFs\n- [x] Tap on a GIF to focus, display more info\n- [x] Rate the GIF and sort a list by rating\n- [x] UI: no specific requirements, but use SwiftUI\n- [x] Provide installation instructions (to run on Monterey, see below)\n- [x] Write tests\n\nNice to haves:\n- [x] Persist beyond local device\n- [x] Use architectural patterns\n- [x] Use a package manager\n- [ ] Use Storyboards (if not SwiftUI)\n- [ ] Optimize scrolling performance of the GIF list\n\n---\n\n## Installation\n\n#### Test Flight (macOS only)\n\n\u003e [Public link](https://testflight.apple.com/join/YVu54c8W)\n\n#### Compile Yourself (macOS only)\n1. Clone the repo\n2. Open `/GIF Addict/GIF Addict.xcproj`\n3. Use Xcode 13 on Monterey 12.1+\n4. Use `Scheme: GIF Addict macOS`\n\nWarning: This scheme runs all tests, including UI tests.\n\nReminder: iOS is not tested.\n\nXcode sometimes hiccups on composed local SPM packages. If so, build each separately. *sigh*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimportryan%2Fgif-addict","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimportryan%2Fgif-addict","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimportryan%2Fgif-addict/lists"}