Skip to content

Commit

Permalink
Merge pull request #98 from SDWebImage/project/copy_private_macro_and…
Browse files Browse the repository at this point in the history
…_fix_build

Copy the macros from SDWebImage Core repo to fix build issue
  • Loading branch information
dreampiggy authored Feb 5, 2024
2 parents 3f8105d + 15d5bcb commit 1e39e3d
Show file tree
Hide file tree
Showing 10 changed files with 891 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github "SDWebImage/SDWebImage" "5.18.4"
github "SDWebImage/SDWebImage" "5.18.10"
github "SDWebImage/libwebp-Xcode" "1.3.2"
2 changes: 0 additions & 2 deletions Example/SDWebImageWebPCoderExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,6 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CODE_SIGN_ENTITLEMENTS = "SDWebImageWebPCoderExample-macOS/SDWebImageWebPCoderExample_macOS.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
Expand Down Expand Up @@ -414,7 +413,6 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CODE_SIGN_ENTITLEMENTS = "SDWebImageWebPCoderExample-macOS/SDWebImageWebPCoderExample_macOS.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"repositoryURL": "https://github.com/SDWebImage/SDWebImage.git",
"state": {
"branch": null,
"revision": "c51ba84499268ea3020e6aee9e229c0f56b9d924",
"version": "5.16.0"
"revision": "59730af512c06fb569c119d737df4c1c499e001d",
"version": "5.18.10"
}
}
]
Expand Down
5 changes: 4 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ let package = Package(
dependencies: ["SDWebImage", "libwebp"],
path: ".",
sources: ["SDWebImageWebPCoder/Classes"],
publicHeadersPath: "SDWebImageWebPCoder/Classes"
publicHeadersPath: "SDWebImageWebPCoder/Classes",
cSettings: [
.headerSearchPath("SDWebImageWebPCoder/Private")
]
)
]
)
3 changes: 2 additions & 1 deletion SDWebImageWebPCoder.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ This is a SDWebImage coder plugin to support WebP image.
s.watchos.deployment_target = '2.0'
s.module_map = 'SDWebImageWebPCoder/Module/SDWebImageWebPCoder.modulemap'

s.source_files = 'SDWebImageWebPCoder/Classes/**/*', 'SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h'
s.source_files = 'SDWebImageWebPCoder/Classes/**/*', 'SDWebImageWebPCoder/Classes/Private/*.h', 'SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h'
s.private_header_files = 'SDWebImageWebPCoder/Classes/Private/*.h'
s.xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1',
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src'
Expand Down
28 changes: 28 additions & 0 deletions SDWebImageWebPCoder.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };
220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };
228EA36125825A52005903D9 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; };
32A3C1452B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
32A3C1462B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
32A3C1472B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
32A3C1482B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
32A3C1492B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
32A3C14A2B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; };
32A3C14B2B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
32A3C14C2B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */; };
806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AD2136A2E900A316D2 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -49,6 +57,8 @@
220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageWebPCoderDefine.m; sourceTree = "<group>"; };
220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageWebPCoderDefine.h; sourceTree = "<group>"; };
3217BE7B220547EB003D0310 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = SDWebImageWebPCoder.modulemap; sourceTree = "<group>"; };
32A3C1432B7129CB00B611BD /* SDInternalMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDInternalMacros.h; sourceTree = "<group>"; };
32A3C1442B7129CB00B611BD /* SDmetamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDmetamacros.h; sourceTree = "<group>"; };
46F21AD7D1692EBAC4D0FF33 /* Pods_SDWebImageWebPCoderTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageWebPCoderTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
806E779D2136A1C000A316D2 /* SDWebImageWebPCoder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageWebPCoder.framework; sourceTree = BUILT_PRODUCTS_DIR; };
806E77AA2136A2E900A316D2 /* UIImage+WebP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+WebP.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -110,6 +120,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
32A3C1422B7129CB00B611BD /* Private */ = {
isa = PBXGroup;
children = (
32A3C1432B7129CB00B611BD /* SDInternalMacros.h */,
32A3C1442B7129CB00B611BD /* SDmetamacros.h */,
);
path = Private;
sourceTree = "<group>";
};
806E77932136A1C000A316D2 = {
isa = PBXGroup;
children = (
Expand All @@ -135,6 +154,7 @@
children = (
806E77A92136A2E900A316D2 /* Classes */,
806E77AF2136A2E900A316D2 /* Module */,
32A3C1422B7129CB00B611BD /* Private */,
806E77B12136A2E900A316D2 /* Assets */,
);
name = SDImageWebPCoder;
Expand Down Expand Up @@ -229,7 +249,9 @@
806E77C72136A7AD00A316D2 /* SDWebImageWebPCoder.h in Headers */,
806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */,
220A623D257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */,
32A3C1452B7129CB00B611BD /* SDInternalMacros.h in Headers */,
806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */,
32A3C1492B7129CB00B611BD /* SDmetamacros.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -240,7 +262,9 @@
80BFF2502136BC1500B95470 /* UIImage+WebP.h in Headers */,
80BFF24D2136BC0600B95470 /* SDWebImageWebPCoder.h in Headers */,
220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */,
32A3C1462B7129CB00B611BD /* SDInternalMacros.h in Headers */,
80BFF24E2136BC1000B95470 /* SDImageWebPCoder.h in Headers */,
32A3C14A2B7129CB00B611BD /* SDmetamacros.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -251,7 +275,9 @@
80BFF2632136BE2200B95470 /* SDWebImageWebPCoder.h in Headers */,
80BFF2612136BE1C00B95470 /* UIImage+WebP.h in Headers */,
220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */,
32A3C1472B7129CB00B611BD /* SDInternalMacros.h in Headers */,
80BFF25F2136BE1700B95470 /* SDImageWebPCoder.h in Headers */,
32A3C14B2B7129CB00B611BD /* SDmetamacros.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -262,7 +288,9 @@
80BFF27F2136BEF200B95470 /* SDWebImageWebPCoder.h in Headers */,
80BFF27D2136BEED00B95470 /* UIImage+WebP.h in Headers */,
220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */,
32A3C1482B7129CB00B611BD /* SDInternalMacros.h in Headers */,
80BFF27B2136BEE700B95470 /* SDImageWebPCoder.h in Headers */,
32A3C14C2B7129CB00B611BD /* SDmetamacros.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
42 changes: 0 additions & 42 deletions SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,6 @@
@import libwebp;
#endif

#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\
(__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\
(__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\
(__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\
(__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0)

#ifndef SD_LOCK_DECLARE
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK_DECLARE(lock) os_unfair_lock lock
#else
#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \
OSSpinLock lock##_deprecated;
#endif
#endif

#ifndef SD_LOCK_INIT
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT
#else
#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \
else lock##_deprecated = OS_SPINLOCK_INIT;
#endif
#endif

#ifndef SD_LOCK
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK(lock) os_unfair_lock_lock(&lock)
#else
#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \
else OSSpinLockLock(&lock##_deprecated);
#endif
#endif

#ifndef SD_UNLOCK
#if SD_USE_OS_UNFAIR_LOCK
#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock)
#else
#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \
else OSSpinLockUnlock(&lock##_deprecated);
#endif
#endif

/// Used for animated WebP, which need a canvas for decoding (rendering), possible apply a scale transform for thumbnail decoding (avoiding post-rescale using vImage)
/// See more in #73
static inline CGContextRef _Nullable CreateWebPCanvas(BOOL hasAlpha, CGSize canvasSize, CGSize thumbnailSize, BOOL preserveAspectRatio) {
Expand Down
187 changes: 187 additions & 0 deletions SDWebImageWebPCoder/Private/SDInternalMacros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

#import <Foundation/Foundation.h>
#import <os/lock.h>
#import <libkern/OSAtomic.h>
#import "SDmetamacros.h"

#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\
(__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\
(__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\
(__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\
(__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0)

#ifndef SD_LOCK_DECLARE
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK_DECLARE(lock) os_unfair_lock lock
#else
#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \
OSSpinLock lock##_deprecated;
#endif
#endif

#ifndef SD_LOCK_DECLARE_STATIC
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock
#else
#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \
static OSSpinLock lock##_deprecated;
#endif
#endif

#ifndef SD_LOCK_INIT
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT
#else
#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \
else lock##_deprecated = OS_SPINLOCK_INIT;
#endif
#endif

#ifndef SD_LOCK
#if SD_USE_OS_UNFAIR_LOCK
#define SD_LOCK(lock) os_unfair_lock_lock(&lock)
#else
#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \
else OSSpinLockLock(&lock##_deprecated);
#endif
#endif

#ifndef SD_UNLOCK
#if SD_USE_OS_UNFAIR_LOCK
#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock)
#else
#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \
else OSSpinLockUnlock(&lock##_deprecated);
#endif
#endif

#ifndef SD_OPTIONS_CONTAINS
#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value))
#endif

#ifndef SD_CSTRING
#define SD_CSTRING(str) #str
#endif

#ifndef SD_NSSTRING
#define SD_NSSTRING(str) @(SD_CSTRING(str))
#endif

#ifndef SD_SEL_SPI
#define SD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@"_%@", SD_NSSTRING(name)])
#endif

#ifndef weakify
#define weakify(...) \
sd_keywordify \
metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__)
#endif

#ifndef strongify
#define strongify(...) \
sd_keywordify \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
metamacro_foreach(sd_strongify_,, __VA_ARGS__) \
_Pragma("clang diagnostic pop")
#endif

#define sd_weakify_(INDEX, CONTEXT, VAR) \
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);

#define sd_strongify_(INDEX, VAR) \
__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);

#if DEBUG
#define sd_keywordify autoreleasepool {}
#else
#define sd_keywordify try {} @catch (...) {}
#endif

#ifndef onExit
#define onExit \
sd_keywordify \
__strong sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(sd_executeCleanupBlock), unused)) = ^
#endif

typedef void (^sd_cleanupBlock_t)(void);

#if defined(__cplusplus)
extern "C" {
#endif
void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block);
#if defined(__cplusplus)
}
#endif

/**
* \@keypath allows compile-time verification of key paths. Given a real object
* receiver and key path:
*
* @code
NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String);
// => @"lowercaseString.UTF8String"
NSString *versionPath = @keypath(NSObject, version);
// => @"version"
NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString);
// => @"lowercaseString"
* @endcode
*
* ... the macro returns an \c NSString containing all but the first path
* component or argument (e.g., @"lowercaseString.UTF8String", @"version").
*
* In addition to simply creating a key path, this macro ensures that the key
* path is valid at compile-time (causing a syntax error if not), and supports
* refactoring, such that changing the name of the property will also update any
* uses of \@keypath.
*/
#define keypath(...) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-repeated-use-of-weak\"") \
(NO).boolValue ? ((NSString * _Nonnull)nil) : ((NSString * _Nonnull)@(cStringKeypath(__VA_ARGS__))) \
_Pragma("clang diagnostic pop") \

#define cStringKeypath(...) \
metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__))

#define keypath1(PATH) \
(((void)(NO && ((void)PATH, NO)), \
({ char *__extobjckeypath__ = strchr(# PATH, '.'); NSCAssert(__extobjckeypath__, @"Provided key path is invalid."); __extobjckeypath__ + 1; })))

#define keypath2(OBJ, PATH) \
(((void)(NO && ((void)OBJ.PATH, NO)), # PATH))

/**
* \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object
* receiver, collection object receiver and related keypaths:
*
* @code
NSString *employeesFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName)
// => @"employees.firstName"
NSString *employeesFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName)
// => @"employees.firstName"
* @endcode
*
*/
#define collectionKeypath(...) \
metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__))

#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) \
(YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil

#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) \
(YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(OBJ, PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil
Loading

0 comments on commit 1e39e3d

Please sign in to comment.