Skip to content

Commit 3259290

Browse files
authored
Merge pull request #2 from bullinnyc/add-macos-support
Add macOS support.
2 parents 2d835d3 + cc96b19 commit 3259290

10 files changed

Lines changed: 177 additions & 100 deletions

File tree

.github/workflows/build-and-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
macos: ['macos-13']
1818
scheme: ['CachedAsyncImage']
1919
command: ['test']
20-
platform: ['iOS']
20+
platform: ['macOS', 'iOS']
2121
steps:
2222
- name: Switch xcode to ${{ matrix.xcode }}
2323
uses: maxim-lobanov/setup-xcode@v1.6.0

.swiftpm/CachedAsyncImage.xctestplan

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"configurations" : [
33
{
4-
"id" : "E45F0232-EFE9-4D85-9212-2CDCA2411611",
4+
"id" : "FE7FCFF0-5186-4CE4-A013-A485B56842C2",
55
"name" : "Test Scheme Action",
66
"options" : {
77

Examples/ContentView.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// Copyright © 2023 Dmitry Kononchuk. All rights reserved.
77
//
88

9-
#if os(iOS)
109
import SwiftUI
1110
import CachedAsyncImage
1211

@@ -52,7 +51,7 @@ struct ContentView: View {
5251
},
5352
image: {
5453
// Customize image.
55-
Image(uiImage: $0)
54+
Image(cpImage: $0)
5655
.resizable()
5756
.scaledToFill()
5857
},
@@ -93,6 +92,9 @@ struct ContentView: View {
9392
}
9493
}
9594
}
95+
#if os(macOS)
96+
.frame(width: 300, height: 450)
97+
#endif
9698
}
9799

98100
// MARK: - Initializers
@@ -123,4 +125,3 @@ struct ContentView_Previews: PreviewProvider {
123125
ContentView()
124126
}
125127
}
126-
#endif

Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ let package = Package(
77
name: "CachedAsyncImage",
88
platforms: [
99
// Add support for all platforms starting from a specific version.
10-
.iOS(.v14)
10+
.iOS(.v14),
11+
.macOS(.v11)
1112
],
1213
products: [
1314
// Products define the executables and libraries a package produces, making them visible to other packages.

Sources/CachedAsyncImage/Resources/ResourcesManager.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,31 @@ public final class ResourcesManager {
3434
UIImage(named: name, in: Bundle.module, with: nil)
3535
}
3636
}
37+
#elseif canImport(AppKit)
38+
import AppKit
39+
40+
/// Resources manager typealias.
41+
public typealias RM = ResourcesManager
42+
43+
/// Resources manager.
44+
public final class ResourcesManager {
45+
// MARK: - Public Properties
46+
47+
/// An object that stores color data.
48+
public static let snow = NSColor(
49+
named: NSColor.Name("snow"),
50+
bundle: Bundle.module
51+
) ?? NSColor()
52+
53+
// MARK: - Public Methods
54+
55+
/// Get image by name.
56+
///
57+
/// - Parameter name: Image name.
58+
///
59+
/// - Returns: An initialized image object or `nil` if the object was not found in the resources.
60+
public static func image(_ name: String) -> NSImage? {
61+
Bundle.module.image(forResource: NSImage.Name(name))
62+
}
63+
}
3764
#endif
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// CrossPlatformImage.swift
3+
// CachedAsyncImage
4+
//
5+
// Created by Dmitry Kononchuk on 01.11.2023.
6+
// Copyright © 2023 Dmitry Kononchuk. All rights reserved.
7+
//
8+
9+
#if os(iOS)
10+
import UIKit
11+
import SwiftUI
12+
13+
/// Cross platform image typealias.
14+
public typealias CPImage = UIImage
15+
16+
extension Image {
17+
/// - Parameter cpImage: Cross platform image.
18+
public init(cpImage: CPImage) {
19+
self.init(uiImage: cpImage)
20+
}
21+
}
22+
23+
extension UIImage {
24+
var data: Data? {
25+
pngData()
26+
}
27+
}
28+
#elseif os(macOS)
29+
import AppKit
30+
import SwiftUI
31+
32+
/// Cross platform image typealias.
33+
public typealias CPImage = NSImage
34+
35+
extension Image {
36+
/// - Parameter cpImage: Cross platform image.
37+
public init(cpImage: CPImage) {
38+
self.init(nsImage: cpImage)
39+
}
40+
}
41+
42+
extension NSImage {
43+
var data: Data? {
44+
tiffRepresentation
45+
}
46+
}
47+
#endif

Sources/CachedAsyncImage/Services/ImageLoader.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
// Copyright © 2023 Dmitry Kononchuk. All rights reserved.
77
//
88

9+
import Foundation
910
import Combine
10-
import UIKit
1111

1212
final class ImageLoader: ObservableObject {
1313
// MARK: - Property Wrappers
1414

15-
@Published var image: UIImage?
15+
@Published var image: CPImage?
1616
@Published var progress: Double?
1717
@Published var errorMessage: String?
1818

@@ -63,15 +63,15 @@ final class ImageLoader: ObservableObject {
6363
.store(in: &cancellables)
6464

6565
data
66-
.map { UIImage(data: $0) }
67-
.catch { [weak self] error -> AnyPublisher<UIImage?, Never> in
66+
.map { CPImage(data: $0) }
67+
.catch { [weak self] error -> AnyPublisher<CPImage?, Never> in
6868
if let error = error as? NetworkError {
6969
DispatchQueue.main.async {
7070
self?.errorMessage = error.rawValue
7171
}
7272

7373
#if DEBUG
74-
print("**** CachedAsyncImage error: \(error.rawValue)")
74+
print("**** CachedAsyncImage error: \(error.rawValue)")
7575
#endif
7676
}
7777

@@ -109,7 +109,7 @@ final class ImageLoader: ObservableObject {
109109
isLoading = false
110110
}
111111

112-
private func cache(url: URL?, image: UIImage?) {
112+
private func cache(url: URL?, image: CPImage?) {
113113
guard let url = url else { return }
114114
image.map { imageCache[url] = $0 }
115115
}

Sources/CachedAsyncImage/Services/TemporaryImageCache.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// Copyright © 2023 Dmitry Kononchuk. All rights reserved.
77
//
88

9-
import UIKit
9+
import Foundation
1010

1111
/// Temporary image cache.
1212
public final class TemporaryImageCache {
@@ -19,19 +19,19 @@ public final class TemporaryImageCache {
1919

2020
// MARK: - Private Properties
2121

22-
private lazy var cache: NSCache<NSURL, UIImage> = {
23-
let cache = NSCache<NSURL, UIImage>()
22+
private lazy var cache: NSCache<NSURL, CPImage> = {
23+
let cache = NSCache<NSURL, CPImage>()
2424
return cache
2525
}()
2626

2727
// MARK: - Subscripts
2828

29-
subscript(_ key: URL) -> UIImage? {
29+
subscript(_ key: URL) -> CPImage? {
3030
get { cache.object(forKey: key as NSURL) }
3131
set {
3232
newValue == nil
3333
? cache.removeObject(forKey: key as NSURL)
34-
: cache.setObject(newValue ?? UIImage(), forKey: key as NSURL)
34+
: cache.setObject(newValue ?? CPImage(), forKey: key as NSURL)
3535
}
3636
}
3737

0 commit comments

Comments
 (0)