{"id":20164010,"url":"https://github.com/marcusziade/cachedasyncimage","last_synced_at":"2025-03-03T03:13:14.943Z","repository":{"id":216009793,"uuid":"740233354","full_name":"marcusziade/CachedAsyncImage","owner":"marcusziade","description":"SwiftUI's simple to use AsyncImage with cache","archived":false,"fork":false,"pushed_at":"2024-01-20T20:52:39.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-28T13:14:40.608Z","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":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcusziade.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2024-01-07T22:33:36.000Z","updated_at":"2024-01-07T22:56:16.000Z","dependencies_parsed_at":"2024-01-20T20:26:26.996Z","dependency_job_id":"87c86f50-f044-4808-9bad-6711c7f65e54","html_url":"https://github.com/marcusziade/CachedAsyncImage","commit_stats":null,"previous_names":["marcusziade/cachedasyncimage"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusziade%2FCachedAsyncImage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusziade%2FCachedAsyncImage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusziade%2FCachedAsyncImage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusziade%2FCachedAsyncImage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcusziade","download_url":"https://codeload.github.com/marcusziade/CachedAsyncImage/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241600492,"owners_count":19988715,"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-11-14T00:32:54.368Z","updated_at":"2025-03-03T03:13:14.922Z","avatar_url":"https://github.com/marcusziade.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CachedAsyncImage\n\nCachedAsyncImage is a Swift package offering an efficient and easy-to-use image caching solution for SwiftUI applications. It provides seamless image caching functionality, ensuring fast and reliable image loading.\n\n## Features\n\n- Asynchronous image loading and caching.\n- Easy integration with SwiftUI.\n- Customizable placeholder and error images.\n- Efficient memory usage by leveraging `NSCache`.\n\n## Requirements\n\n- iOS 14.0+ / macOS 10.15+\n- Swift 5.9+\n- Xcode 15.0+\n\n## Installation\n\n### Swift Package Manager\n\nYou can add CachedAsyncImage to an Xcode project by adding it as a package dependency.\n\n1. From the **File** menu, select **Swift Packages** \u003e **Add Package Dependency...**\n2. Enter `https://github.com/marcusziade/CachedAsyncImage.git` into the package repository URL text field\n\n## Usage\n\n`CachedAsyncImage` is a Swift package designed for SwiftUI applications, providing an efficient mechanism for asynchronously loading and caching images from the web. \n\n### Common use case\n\n```swift\nimport SwiftUI\nimport CachedAsyncImage\n\nstruct ContentView: View {\n    var body: some View {\n        CachedAsyncImage(url: URL(string: \"https://example.com/image.jpg\"))\n    }\n}\n```\n\n### Components\n\n#### `ImageCache` Protocol\n\n```swift\nprotocol ImageCache {\n    subscript(_ url: URL) -\u003e UIImage? { get set }\n}\n```\n\n- **Purpose**: Defines a contract for an image caching system.\n- **Subscript**: Allows getting and setting `UIImage` instances associated with a `URL`.\n\n#### `DefaultImageCache` Class\n\n```swift\nclass DefaultImageCache: ImageCache {\n    private var cache = NSCache\u003cNSURL, UIImage\u003e()\n    \n    subscript(_ url: URL) -\u003e UIImage? {\n        // Implementation\n    }\n}\n```\n\n- **Description**: A default implementation of `ImageCache`, using `NSCache` to store `UIImage` instances.\n- **Usage**: Automatically used by `CachedAsyncImage` if no custom cache is provided.\n\n#### `CachedAsyncImage` View\n\n```swift\nstruct CachedAsyncImage: View {\n    // Properties and Initializer\n}\n```\n\n- **Description**: A SwiftUI view that loads and displays images from a URL, with caching.\n- **Initialization Parameters**:\n  - `url`: The URL of the image to load.\n  - `placeholder`: A view to display while the image is loading.\n  - `errorImage`: A view to display if the image loading fails.\n  - `cache`: An optional `ImageCache` instance for custom caching behavior.\n\n#### ViewModel for `CachedAsyncImage`\n\n```swift\nextension CachedAsyncImage {\n    final class ViewModel: ObservableObject {\n        // Properties and Functions\n    }\n}\n```\n\n- **Responsibility**: Manages the state of image loading, including caching logic.\n- **LoadState**: Enum representing the loading state (`idle`, `loading`, `loaded`, `failed`, `noURL`).\n\n### Example Usage\n\n#### Basic Usage\n\n```swift\nimport SwiftUI\nimport CachedAsyncImage\n\nstruct ContentView: View {\n    var body: some View {\n        CachedAsyncImage(\n            url: URL(string: \"https://example.com/image.jpg\"),\n            placeholder: Image(systemName: \"photo\"),\n            errorImage: Image(systemName: \"multiply.circle\")\n        )\n    }\n}\n```\n\n#### Custom Cache Implementation\n\nTo use a custom cache:\n\n```swift\nclass MyCustomCache: ImageCache {\n    // Custom cache implementation\n}\n\nstruct ContentView: View {\n    var body: some View {\n        CachedAsyncImage(\n            url: URL(string: \"https://example.com/image.jpg\"),\n            cache: MyCustomCache()\n        )\n    }\n}\n```\n\n### Advanced Features\n\n#### Handling Tap Gestures on Error\n\nTo reload the image on tapping the error view:\n\n```swift\nCachedAsyncImage(\n    url: URL(string: \"https://example.com/image.jpg\"),\n    errorImage: Image(systemName: \"multiply.circle\")\n        .onTapGesture {\n            // Custom action to handle tap\n        }\n)\n```\n\n#### Customizing Placeholder and Error Images\n\nYou can provide custom SwiftUI views for placeholders and error states:\n\n```swift\nCachedAsyncImage(\n    url: URL(string: \"https://example.com/image.jpg\"),\n    placeholder: Text(\"Loading...\"),\n    errorImage: Text(\"Failed to Load Image\")\n)\n```\n\n### Testing\n\nFor unit testing, you can use the provided `MockImageCache` class to simulate different caching scenarios.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcusziade%2Fcachedasyncimage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcusziade%2Fcachedasyncimage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcusziade%2Fcachedasyncimage/lists"}