Skip to content

Commit 7e21926

Browse files
authored
Support AnimatedImage on watchOS - Using WatchKit bridge (#22)
* Temp for watchOS AnimatedImage support, using massive private API, still contains small issues * Update the hack for wacthKit experienment, fix the retain cycle issue that cause WKInterfaceImage not dealloc * Solve the merge conflict and try again * Add support for contentMode * Fix the SDAnimatedImageInterface first appear shows empty issues * Fix the scale factor support for SDAniamtedImageInterface * Fix the compile issue on other platforms * Stop animtiong when dismantle for watchOS AnimatedImage * Fix the issue that stopAnimating does not stop :) * Fix the warning because of Apple's bug * Use macro to integrate the watchOS Animation solution * Refactory code to fix that calling sd_setImage(with:) multiple times issues * Support to custom loop count on watchOS AnimatedImage * Fix the CocoaPods issues which does not have umbrella headers * Update some of the documentations * Try to solve the SwiftPM issue because it does not support mixed Objective-C and Swift code, really suck, Apple :) * Fix travis CI script to only build Carthage. Swift cli build can not works on Objective-C code import syntax, but works on Xcode
1 parent f056456 commit 7e21926

File tree

13 files changed

+474
-59
lines changed

13 files changed

+474
-59
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ script:
3333
- pod install --project-directory=Example
3434
- xcodebuild build -workspace Example/SDWebImageSwiftUI.xcworkspace -scheme SDWebImageSwiftUIDemo -sdk iphonesimulator -destination 'name=iPhone 8' ONLY_ACTIVE_ARCH=NO | xcpretty -c
3535

36-
- swift build
36+
- carthage update --platform iOS
37+
- xcodebuild build -project SDWebImageSwiftUI.xcodeproj -scheme 'SDWebImageSwiftUI' -sdk iphonesimulator -configuration Debug | xcpretty -c

Cartfile.resolved

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
github "SDWebImage/SDWebImage" "5.1.0"
1+
github "SDWebImage/SDWebImage" "5.2.3"

Example/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ PODS:
1111
- SDWebImage (5.2.3):
1212
- SDWebImage/Core (= 5.2.3)
1313
- SDWebImage/Core (5.2.3)
14-
- SDWebImageSwiftUI (0.3.2):
14+
- SDWebImageSwiftUI (0.3.3):
1515
- SDWebImage (~> 5.1)
1616
- SDWebImageWebPCoder (0.2.5):
1717
- libwebp (~> 1.0)
@@ -34,7 +34,7 @@ EXTERNAL SOURCES:
3434
SPEC CHECKSUMS:
3535
libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e
3636
SDWebImage: 46a7f73228f84ce80990c786e4372cf4db5875ce
37-
SDWebImageSwiftUI: a8a03ef596dde2e9668a76794f6c59d194289bb0
37+
SDWebImageSwiftUI: 2284857313ca5085ab7b5310d372420d23c0817f
3838
SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987
3939

4040
PODFILE CHECKSUM: 3fb06a5173225e197f3a4bf2be7e5586a693257a
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

Example/SDWebImageSwiftUIDemo/ContentView.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ struct ContentView: View {
6767
Button(action: { self.reloadCache() }) {
6868
Text("Reload")
6969
}
70+
Button(action: { self.switchView() }) {
71+
Text("Switch")
72+
}
7073
}
7174
#endif
7275
}
@@ -76,7 +79,6 @@ struct ContentView: View {
7679
ForEach(imageURLs) { url in
7780
NavigationLink(destination: DetailView(url: url, animated: self.animated)) {
7881
HStack {
79-
#if os(iOS) || os(tvOS) || os(macOS)
8082
if self.animated {
8183
AnimatedImage(url: URL(string:url))
8284
.resizable()
@@ -88,12 +90,6 @@ struct ContentView: View {
8890
.scaledToFit()
8991
.frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
9092
}
91-
#else
92-
WebImage(url: URL(string:url))
93-
.resizable()
94-
.scaledToFit()
95-
.frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
96-
#endif
9793
Text((url as NSString).lastPathComponent)
9894
}
9995
}

Example/SDWebImageSwiftUIDemo/DetailView.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct DetailView: View {
3333
contentView()
3434
}
3535
#endif
36-
#if os(macOS)
36+
#if os(macOS) || os(watchOS)
3737
if animated {
3838
contentView()
3939
.contextMenu {
@@ -45,16 +45,12 @@ struct DetailView: View {
4545
contentView()
4646
}
4747
#endif
48-
#if os(watchOS)
49-
contentView()
50-
#endif
5148
Spacer()
5249
}
5350
}
5451

5552
func contentView() -> some View {
5653
HStack {
57-
#if os(iOS) || os(tvOS) || os(macOS)
5854
if animated {
5955
AnimatedImage(url: URL(string:url), options: [.progressiveLoad], isAnimating: $isAnimating)
6056
.onProgress(perform: { (receivedSize, expectedSize) in
@@ -79,18 +75,6 @@ struct DetailView: View {
7975
.resizable()
8076
.scaledToFit()
8177
}
82-
#else
83-
WebImage(url: URL(string:url), options: [.progressiveLoad])
84-
.onProgress(perform: { (receivedSize, expectedSize) in
85-
if (expectedSize >= 0) {
86-
self.progress = CGFloat(receivedSize) / CGFloat(expectedSize)
87-
} else {
88-
self.progress = 1
89-
}
90-
})
91-
.resizable()
92-
.scaledToFit()
93-
#endif
9478
}
9579
}
9680
}

Package.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,16 @@ let package = Package(
2424
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
2525
.target(
2626
name: "SDWebImageSwiftUI",
27+
dependencies: ["SDWebImage", "SDWebImageSwiftUIObjC"],
28+
path: "SDWebImageSwiftUI/Classes",
29+
exclude: ["ObjC"]
30+
),
31+
// This is implementation detail because SwiftPM does not support mixed Objective-C/Swift code, don't dependent this target
32+
.target(
33+
name: "SDWebImageSwiftUIObjC",
2734
dependencies: ["SDWebImage"],
28-
path: "SDWebImageSwiftUI/Classes"),
35+
path: "SDWebImageSwiftUI/Classes/ObjC",
36+
publicHeadersPath: "."
37+
)
2938
]
3039
)

SDWebImageSwiftUI.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Which aims to provide a better support for SwiftUI users.
2626
s.tvos.deployment_target = '13.0'
2727
s.watchos.deployment_target = '6.0'
2828

29-
s.source_files = 'SDWebImageSwiftUI/Classes/**/*'
29+
s.source_files = 'SDWebImageSwiftUI/Classes/**/*', 'SDWebImageSwiftUI/Module/*.h'
3030

3131
s.frameworks = 'SwiftUI'
3232
s.dependency 'SDWebImage', '~> 5.1'

SDWebImageSwiftUI.xcodeproj/project.pbxproj

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
324F61C7235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 324F61C5235E07EC003973B8 /* SDAnimatedImageInterface.h */; settings = {ATTRIBUTES = (Public, ); }; };
11+
324F61C8235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 324F61C5235E07EC003973B8 /* SDAnimatedImageInterface.h */; settings = {ATTRIBUTES = (Public, ); }; };
12+
324F61C9235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 324F61C5235E07EC003973B8 /* SDAnimatedImageInterface.h */; settings = {ATTRIBUTES = (Public, ); }; };
13+
324F61CA235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 324F61C5235E07EC003973B8 /* SDAnimatedImageInterface.h */; settings = {ATTRIBUTES = (Public, ); }; };
14+
324F61CB235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 324F61C6235E07EC003973B8 /* SDAnimatedImageInterface.m */; };
15+
324F61CC235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 324F61C6235E07EC003973B8 /* SDAnimatedImageInterface.m */; };
16+
324F61CD235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 324F61C6235E07EC003973B8 /* SDAnimatedImageInterface.m */; };
17+
324F61CE235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 324F61C6235E07EC003973B8 /* SDAnimatedImageInterface.m */; };
1018
326E480A23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 326E480923431C0F00C633E9 /* ImageViewWrapper.swift */; };
1119
326E480B23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 326E480923431C0F00C633E9 /* ImageViewWrapper.swift */; };
1220
326E480C23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 326E480923431C0F00C633E9 /* ImageViewWrapper.swift */; };
@@ -89,6 +97,8 @@
8997
/* End PBXCopyFilesBuildPhase section */
9098

9199
/* Begin PBXFileReference section */
100+
324F61C5235E07EC003973B8 /* SDAnimatedImageInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDAnimatedImageInterface.h; sourceTree = "<group>"; };
101+
324F61C6235E07EC003973B8 /* SDAnimatedImageInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDAnimatedImageInterface.m; sourceTree = "<group>"; };
92102
326E480923431C0F00C633E9 /* ImageViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewWrapper.swift; sourceTree = "<group>"; };
93103
32C43DCC22FD540D00BE87F5 /* SDWebImageSwiftUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageSwiftUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
94104
32C43DDC22FD54C600BE87F5 /* ImageManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageManager.swift; sourceTree = "<group>"; };
@@ -142,6 +152,15 @@
142152
/* End PBXFrameworksBuildPhase section */
143153

144154
/* Begin PBXGroup section */
155+
324F61C4235E07EC003973B8 /* ObjC */ = {
156+
isa = PBXGroup;
157+
children = (
158+
324F61C5235E07EC003973B8 /* SDAnimatedImageInterface.h */,
159+
324F61C6235E07EC003973B8 /* SDAnimatedImageInterface.m */,
160+
);
161+
path = ObjC;
162+
sourceTree = "<group>";
163+
};
145164
32C43DC222FD540D00BE87F5 = {
146165
isa = PBXGroup;
147166
children = (
@@ -175,6 +194,7 @@
175194
32C43DDB22FD54C600BE87F5 /* Classes */ = {
176195
isa = PBXGroup;
177196
children = (
197+
324F61C4235E07EC003973B8 /* ObjC */,
178198
32C43DDC22FD54C600BE87F5 /* ImageManager.swift */,
179199
32C43DDE22FD54C600BE87F5 /* WebImage.swift */,
180200
32C43DDF22FD54C600BE87F5 /* AnimatedImage.swift */,
@@ -202,6 +222,7 @@
202222
isa = PBXHeadersBuildPhase;
203223
buildActionMask = 2147483647;
204224
files = (
225+
324F61C7235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */,
205226
32C43DE622FD54CD00BE87F5 /* SDWebImageSwiftUI.h in Headers */,
206227
);
207228
runOnlyForDeploymentPostprocessing = 0;
@@ -210,6 +231,7 @@
210231
isa = PBXHeadersBuildPhase;
211232
buildActionMask = 2147483647;
212233
files = (
234+
324F61C8235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */,
213235
32C43E2222FD583A00BE87F5 /* SDWebImageSwiftUI.h in Headers */,
214236
);
215237
runOnlyForDeploymentPostprocessing = 0;
@@ -218,6 +240,7 @@
218240
isa = PBXHeadersBuildPhase;
219241
buildActionMask = 2147483647;
220242
files = (
243+
324F61C9235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */,
221244
32C43E2322FD583B00BE87F5 /* SDWebImageSwiftUI.h in Headers */,
222245
);
223246
runOnlyForDeploymentPostprocessing = 0;
@@ -226,6 +249,7 @@
226249
isa = PBXHeadersBuildPhase;
227250
buildActionMask = 2147483647;
228251
files = (
252+
324F61CA235E07EC003973B8 /* SDAnimatedImageInterface.h in Headers */,
229253
32C43E2422FD583C00BE87F5 /* SDWebImageSwiftUI.h in Headers */,
230254
);
231255
runOnlyForDeploymentPostprocessing = 0;
@@ -320,15 +344,19 @@
320344
TargetAttributes = {
321345
32C43DCB22FD540D00BE87F5 = {
322346
CreatedOnToolsVersion = 11.0;
347+
LastSwiftMigration = 1100;
323348
};
324349
32C43DF322FD57FD00BE87F5 = {
325350
CreatedOnToolsVersion = 11.0;
351+
LastSwiftMigration = 1100;
326352
};
327353
32C43E0022FD581400BE87F5 = {
328354
CreatedOnToolsVersion = 11.0;
355+
LastSwiftMigration = 1100;
329356
};
330357
32C43E0D22FD581C00BE87F5 = {
331358
CreatedOnToolsVersion = 11.0;
359+
LastSwiftMigration = 1100;
332360
};
333361
};
334362
};
@@ -394,6 +422,7 @@
394422
326E480A23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */,
395423
32C43E1622FD583700BE87F5 /* ImageManager.swift in Sources */,
396424
32C43E1822FD583700BE87F5 /* AnimatedImage.swift in Sources */,
425+
324F61CB235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */,
397426
);
398427
runOnlyForDeploymentPostprocessing = 0;
399428
};
@@ -406,6 +435,7 @@
406435
326E480B23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */,
407436
32C43E1922FD583700BE87F5 /* ImageManager.swift in Sources */,
408437
32C43E1B22FD583700BE87F5 /* AnimatedImage.swift in Sources */,
438+
324F61CC235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */,
409439
);
410440
runOnlyForDeploymentPostprocessing = 0;
411441
};
@@ -418,6 +448,7 @@
418448
326E480C23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */,
419449
32C43E1C22FD583800BE87F5 /* ImageManager.swift in Sources */,
420450
32C43E1E22FD583800BE87F5 /* AnimatedImage.swift in Sources */,
451+
324F61CD235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */,
421452
);
422453
runOnlyForDeploymentPostprocessing = 0;
423454
};
@@ -430,6 +461,7 @@
430461
326E480D23431C0F00C633E9 /* ImageViewWrapper.swift in Sources */,
431462
32C43E1F22FD583800BE87F5 /* ImageManager.swift in Sources */,
432463
32C43E2122FD583800BE87F5 /* AnimatedImage.swift in Sources */,
464+
324F61CE235E07EC003973B8 /* SDAnimatedImageInterface.m in Sources */,
433465
);
434466
runOnlyForDeploymentPostprocessing = 0;
435467
};
@@ -565,6 +597,7 @@
565597
32C43DD522FD540D00BE87F5 /* Debug */ = {
566598
isa = XCBuildConfiguration;
567599
buildSettings = {
600+
CLANG_ENABLE_MODULES = YES;
568601
CODE_SIGN_STYLE = Automatic;
569602
DEFINES_MODULE = YES;
570603
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -585,6 +618,7 @@
585618
PRODUCT_NAME = SDWebImageSwiftUI;
586619
SKIP_INSTALL = YES;
587620
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
621+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
588622
SWIFT_VERSION = 5.0;
589623
TARGETED_DEVICE_FAMILY = "1,2";
590624
};
@@ -593,6 +627,7 @@
593627
32C43DD622FD540D00BE87F5 /* Release */ = {
594628
isa = XCBuildConfiguration;
595629
buildSettings = {
630+
CLANG_ENABLE_MODULES = YES;
596631
CODE_SIGN_STYLE = Automatic;
597632
DEFINES_MODULE = YES;
598633
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -621,6 +656,7 @@
621656
32C43DFA22FD57FD00BE87F5 /* Debug */ = {
622657
isa = XCBuildConfiguration;
623658
buildSettings = {
659+
CLANG_ENABLE_MODULES = YES;
624660
CODE_SIGN_STYLE = Automatic;
625661
COMBINE_HIDPI_IMAGES = YES;
626662
DEFINES_MODULE = YES;
@@ -643,13 +679,15 @@
643679
PRODUCT_NAME = SDWebImageSwiftUI;
644680
SDKROOT = macosx;
645681
SKIP_INSTALL = YES;
682+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
646683
SWIFT_VERSION = 5.0;
647684
};
648685
name = Debug;
649686
};
650687
32C43DFB22FD57FD00BE87F5 /* Release */ = {
651688
isa = XCBuildConfiguration;
652689
buildSettings = {
690+
CLANG_ENABLE_MODULES = YES;
653691
CODE_SIGN_STYLE = Automatic;
654692
COMBINE_HIDPI_IMAGES = YES;
655693
DEFINES_MODULE = YES;
@@ -679,6 +717,7 @@
679717
32C43E0722FD581400BE87F5 /* Debug */ = {
680718
isa = XCBuildConfiguration;
681719
buildSettings = {
720+
CLANG_ENABLE_MODULES = YES;
682721
CODE_SIGN_STYLE = Automatic;
683722
DEFINES_MODULE = YES;
684723
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -699,6 +738,7 @@
699738
PRODUCT_NAME = SDWebImageSwiftUI;
700739
SDKROOT = appletvos;
701740
SKIP_INSTALL = YES;
741+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
702742
SWIFT_VERSION = 5.0;
703743
TARGETED_DEVICE_FAMILY = 3;
704744
};
@@ -707,6 +747,7 @@
707747
32C43E0822FD581400BE87F5 /* Release */ = {
708748
isa = XCBuildConfiguration;
709749
buildSettings = {
750+
CLANG_ENABLE_MODULES = YES;
710751
CODE_SIGN_STYLE = Automatic;
711752
DEFINES_MODULE = YES;
712753
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -736,6 +777,7 @@
736777
isa = XCBuildConfiguration;
737778
buildSettings = {
738779
APPLICATION_EXTENSION_API_ONLY = YES;
780+
CLANG_ENABLE_MODULES = YES;
739781
CODE_SIGN_STYLE = Automatic;
740782
DEFINES_MODULE = YES;
741783
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -756,6 +798,7 @@
756798
PRODUCT_NAME = SDWebImageSwiftUI;
757799
SDKROOT = watchos;
758800
SKIP_INSTALL = YES;
801+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
759802
SWIFT_VERSION = 5.0;
760803
TARGETED_DEVICE_FAMILY = 4;
761804
};
@@ -765,6 +808,7 @@
765808
isa = XCBuildConfiguration;
766809
buildSettings = {
767810
APPLICATION_EXTENSION_API_ONLY = YES;
811+
CLANG_ENABLE_MODULES = YES;
768812
CODE_SIGN_STYLE = Automatic;
769813
DEFINES_MODULE = YES;
770814
DYLIB_COMPATIBILITY_VERSION = 1;

0 commit comments

Comments
 (0)