| | |
| | | # Uncomment the next line to define a global platform for your project |
| | | # platform :ios, '9.0' |
| | | # platform :ios, '10.0' |
| | | |
| | | target 'XQMuse' do |
| | | # Comment the next line if you don't want to use dynamic frameworks |
| | |
| | | pod 'Alamofire' # 网络请求框架 |
| | | pod 'Lantern' # 图片浏览器 |
| | | pod 'SVProgressHUD' # 提示框组件 |
| | | pod 'AliyunOSSiOS' # 阿里云OSS |
| | | pod 'AliyunOSSiOS','2.10.22' # 阿里云OSS |
| | | pod 'WechatOpenSDK-XCFramework' # 微信开放平台组件 |
| | | pod 'CryptoSwift' # 常用加密算法 |
| | | pod 'Snapkit' |
| | | pod 'CryptoSwift','1.8.3' # 常用加密算法 |
| | | # pod 'SwiftAudioPlayer','7.6.0'# 音频播放 |
| | | end |
| | |
| | | PODS: |
| | | - Alamofire (5.9.1) |
| | | - AliyunOSSiOS (2.10.21) |
| | | - CryptoSwift (1.8.2) |
| | | - AliyunOSSiOS (2.10.22) |
| | | - CryptoSwift (1.8.3) |
| | | - Differentiator (5.0.0) |
| | | - EmptyDataSet-Swift (5.0.0) |
| | | - FFPage (3.0.0) |
| | | - HandyJSON (5.0.2) |
| | | - IQKeyboardManager (6.5.19) |
| | | - IQKeyboardManagerSwift (7.0.3) |
| | | - IQKeyboardManagerSwift (7.1.1) |
| | | - JQTools (0.1.5): |
| | | - EmptyDataSet-Swift |
| | | - HandyJSON |
| | |
| | | - IQKeyboardManagerSwift |
| | | - MJRefresh |
| | | - ObjectMapper |
| | | - QMUIKit |
| | | - QMUIKit (~> 4.7.0) |
| | | - RxCocoa |
| | | - RxDataSources |
| | | - RxSwift |
| | |
| | | - RxRelay (6.7.1): |
| | | - RxSwift (= 6.7.1) |
| | | - RxSwift (6.7.1) |
| | | - SDWebImage (5.19.2): |
| | | - SDWebImage/Core (= 5.19.2) |
| | | - SDWebImage/Core (5.19.2) |
| | | - SDWebImage (5.19.6): |
| | | - SDWebImage/Core (= 5.19.6) |
| | | - SDWebImage/Core (5.19.6) |
| | | - SnapKit (5.7.1) |
| | | - SPPageMenu (3.5.0) |
| | | - SVProgressHUD (2.3.1): |
| | | - SVProgressHUD/Core (= 2.3.1) |
| | | - SVProgressHUD/Core (2.3.1) |
| | | - SwiftAudioPlayer (7.6.0) |
| | | - SwifterSwift (6.2.0): |
| | | - SwifterSwift/AppKit (= 6.2.0) |
| | | - SwifterSwift/Combine (= 6.2.0) |
| | |
| | | - SwifterSwift/SwiftStdlib (6.2.0) |
| | | - SwifterSwift/UIKit (6.2.0) |
| | | - SwifterSwift/WebKit (6.2.0) |
| | | - TZImagePickerController (3.8.5): |
| | | - TZImagePickerController/Basic (= 3.8.5) |
| | | - TZImagePickerController/Location (= 3.8.5) |
| | | - TZImagePickerController/Basic (3.8.5) |
| | | - TZImagePickerController/Location (3.8.5) |
| | | - TZImagePickerController (3.8.7): |
| | | - TZImagePickerController/Basic (= 3.8.7) |
| | | - TZImagePickerController/Location (= 3.8.7) |
| | | - TZImagePickerController/Basic (3.8.7) |
| | | - TZImagePickerController/Location (3.8.7) |
| | | - UserDefaultsStore (1.5.0) |
| | | - VTMagic (1.2.4): |
| | | - VTMagic/Core (= 1.2.4) |
| | |
| | | - FFPage |
| | | - JQTools (from `/Users/yvkd/MyProject/JQTools`) |
| | | - Lantern |
| | | - QMUIKit |
| | | - SPPageMenu |
| | | - SVProgressHUD |
| | | - SwiftAudioPlayer |
| | | - SwifterSwift |
| | | - WechatOpenSDK-XCFramework |
| | | |
| | |
| | | - SnapKit |
| | | - SPPageMenu |
| | | - SVProgressHUD |
| | | - SwiftAudioPlayer |
| | | - SwifterSwift |
| | | - TZImagePickerController |
| | | - UserDefaultsStore |
| | |
| | | |
| | | SPEC CHECKSUMS: |
| | | Alamofire: f36a35757af4587d8e4f4bfa223ad10be2422b8c |
| | | AliyunOSSiOS: 1f091b3aeec9f7a5fd722cb511704116f2ca468d |
| | | CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea |
| | | AliyunOSSiOS: b46648fd78909a567e3743fe94183748a407b175 |
| | | CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483 |
| | | Differentiator: e8497ceab83c1b10ca233716d547b9af21b9344d |
| | | EmptyDataSet-Swift: eb382c0c87a2d9c678077385a595cec52da38171 |
| | | FFPage: 481cc0f2dde0f6be84a2359b6c86272e0024dc8d |
| | | HandyJSON: 9e4e236f5d2dbefad5155a77417bbea438201c03 |
| | | IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485 |
| | | IQKeyboardManagerSwift: f9c5dc36cba16ddd2e51fa7d51c34a2e083029b5 |
| | | JQTools: d2b720c901e39d9959c9342ba42f9eba58886a02 |
| | | IQKeyboardManagerSwift: d7f3d3a562c237a0e7335e657cd598c452f57f1b |
| | | JQTools: af562f97302a433989c23bfb31e24458eb6469ad |
| | | Lantern: b192e7146c6d04e15e627f37281254a6a8593703 |
| | | MJRefresh: ff9e531227924c84ce459338414550a05d2aea78 |
| | | ObjcExceptionBridging: d3d37d62981bb7f252ecb31b62d7e23a96bbfb8a |
| | |
| | | RxDataSources: aa47cc1ed6c500fa0dfecac5c979b723542d79cf |
| | | RxRelay: 4151ba01152436b08271e08410135e099880eae5 |
| | | RxSwift: b9a93a26031785159e11abd40d1a55bcb8057e52 |
| | | SDWebImage: dfe95b2466a9823cf9f0c6d01217c06550d7b29a |
| | | SDWebImage: a79252b60f4678812d94316c91da69ec83089c9f |
| | | SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a |
| | | SPPageMenu: da182aafcec55719d5c326103cc7716c1e48f311 |
| | | SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22 |
| | | SwiftAudioPlayer: a546709faf47f3ab0cb59e41ba4432e6bb61db0a |
| | | SwifterSwift: dd00873fb09cde19da88bdb2878f9fe70fe27b0f |
| | | TZImagePickerController: c0f8e83c27cb08f7d812b1d066a5934d30ff78ad |
| | | TZImagePickerController: 5f35bb7266552e36ca834bafa955b869fe086124 |
| | | UserDefaultsStore: 905e30372ff432197d199ce1f6fe51be7bf69628 |
| | | VTMagic: b49e5f456dbcbfd9a3588ba92417233a105bc193 |
| | | WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f |
| | | XCGLogger: 399c5885210b4e2ad79d9f7a29b105d672ef724f |
| | | |
| | | PODFILE CHECKSUM: b6fd53f7f3a4f07f827c1dd265be4ea09db142cb |
| | | PODFILE CHECKSUM: 09bcd0f1f48732e13cf706127b08a5fe4df60434 |
| | | |
| | | COCOAPODS: 1.15.2 |
| | |
| | | #elif TARGET_OS_OSX |
| | | #define OSSUAPrefix @"aliyun-sdk-mac" |
| | | #endif |
| | | #define OSSSDKVersion @"2.10.21" |
| | | #define OSSSDKVersion @"2.10.22" |
| | | |
| | | #define OSSListBucketResultXMLTOKEN @"ListBucketResult" |
| | | #define OSSNameXMLTOKEN @"Name" |
| | |
| | | /** |
| | | OSS Download Range: For example, bytes=0-9 means uploading the first to the tenth's character. |
| | | */ |
| | | @property (nonatomic, strong) OSSRange * range; |
| | | @property (nonatomic, strong, nullable) OSSRange * range; |
| | | |
| | | /** |
| | | The local file path to download to. |
| | | */ |
| | | @property (nonatomic, strong) NSURL * downloadToFileURL; |
| | | @property (nonatomic, strong, nullable) NSURL * downloadToFileURL; |
| | | |
| | | /** |
| | | Image processing configuration. |
| | | */ |
| | | @property (nonatomic, copy) NSString * xOssProcess; |
| | | @property (nonatomic, copy, nullable) NSString * xOssProcess; |
| | | |
| | | /** |
| | | Download progress callback. |
| | | It runs at background thread. |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingDownloadProgressBlock downloadProgress; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingDownloadProgressBlock downloadProgress; |
| | | |
| | | /** |
| | | During the object download, the callback is called upon response is received. |
| | | It runs under background thread (not UI thread) |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingOnRecieveDataBlock onRecieveData; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingOnRecieveDataBlock onRecieveData; |
| | | |
| | | /** |
| | | * set request headers |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary *headerFields; |
| | | @property (nonatomic, copy, nullable) NSDictionary *headerFields; |
| | | |
| | | @end |
| | | |
| | |
| | | /** |
| | | The in-memory content of the downloaded object, if the local file path is not specified. |
| | | */ |
| | | @property (nonatomic, strong) NSData * downloadedData; |
| | | @property (nonatomic, strong, nullable) NSData * downloadedData; |
| | | |
| | | /** |
| | | The object metadata dictionary |
| | |
| | | /** |
| | | The in-memory data to upload. |
| | | */ |
| | | @property (nonatomic, strong) NSData * uploadingData; |
| | | @property (nonatomic, strong, nullable) NSData * uploadingData; |
| | | |
| | | /** |
| | | The local file path to upload. |
| | | */ |
| | | @property (nonatomic, strong) NSURL * uploadingFileURL; |
| | | @property (nonatomic, strong, nullable) NSURL * uploadingFileURL; |
| | | |
| | | /** |
| | | The callback parameters. |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * callbackParam; |
| | | @property (nonatomic, copy, nullable) NSDictionary * callbackParam; |
| | | |
| | | /** |
| | | The callback variables. |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * callbackVar; |
| | | @property (nonatomic, copy, nullable) NSDictionary * callbackVar; |
| | | |
| | | /** |
| | | The content type. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentType; |
| | | @property (nonatomic, copy, nullable) NSString * contentType; |
| | | |
| | | /** |
| | | The content's MD5 digest. |
| | |
| | | Then use base64 encoding on the 128bit result to get this MD5 value. |
| | | This header is for integrity check on the data. And it's recommended to turn on for every body. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentMd5; |
| | | @property (nonatomic, copy, nullable) NSString * contentMd5; |
| | | |
| | | /** |
| | | Specifies the download name of the object. Checks out RFC2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentDisposition; |
| | | @property (nonatomic, copy, nullable) NSString * contentDisposition; |
| | | |
| | | /** |
| | | Specifies the content encoding during the download. Checks out RFC2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentEncoding; |
| | | @property (nonatomic, copy, nullable) NSString * contentEncoding; |
| | | |
| | | /** |
| | | Specifies the cache behavior during the download. Checks out RFC2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * cacheControl; |
| | | @property (nonatomic, copy, nullable) NSString * cacheControl; |
| | | |
| | | /** |
| | | Expiration time in milliseconds. Checks out RFC2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * expires; |
| | | @property (nonatomic, copy, nullable) NSString * expires; |
| | | |
| | | /** |
| | | The object's metadata. |
| | |
| | | The total size of all user metadata cannot be more than 8K. |
| | | It also could include standard HTTP headers in this object. |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * objectMeta; |
| | | @property (nonatomic, copy, nullable) NSDictionary * objectMeta; |
| | | |
| | | /** |
| | | The upload progress callback. |
| | | It runs in background thread (not UI thread). |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingUploadProgressBlock uploadProgress; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingUploadProgressBlock uploadProgress; |
| | | |
| | | /** |
| | | The upload retry callback. |
| | | It runs in background thread (not UI thread). |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingRetryBlock uploadRetryCallback; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingRetryBlock uploadRetryCallback; |
| | | |
| | | /** |
| | | * the sha1 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentSHA1; |
| | | @property (nonatomic, copy, nullable) NSString *contentSHA1; |
| | | |
| | | @end |
| | | |
| | |
| | | It's the MD5 value for put object request. If the object is created by other APIs, the ETag is the UUID of the content. |
| | | ETag could be used to check if the object has been updated. |
| | | */ |
| | | @property (nonatomic, copy) NSString * eTag; |
| | | @property (nonatomic, copy, nullable) NSString * eTag; |
| | | |
| | | /** |
| | | If the callback is specified, this is the callback response result. |
| | | */ |
| | | @property (nonatomic, copy) NSString * serverReturnJsonString; |
| | | @property (nonatomic, copy, nullable) NSString * serverReturnJsonString; |
| | | @end |
| | | |
| | | /** |
| | |
| | | /** |
| | | The in-memory data to upload from. |
| | | */ |
| | | @property (nonatomic, strong) NSData * uploadingData; |
| | | @property (nonatomic, strong, nullable) NSData * uploadingData; |
| | | |
| | | /** |
| | | The local file path to upload from. |
| | | */ |
| | | @property (nonatomic, strong) NSURL * uploadingFileURL; |
| | | @property (nonatomic, strong, nullable) NSURL * uploadingFileURL; |
| | | |
| | | /** |
| | | Sets the content type |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentType; |
| | | @property (nonatomic, copy, nullable) NSString * contentType; |
| | | |
| | | /** |
| | | The content's MD5 digest value. |
| | | It's calculated from the MD5 value of the request body according to RFC 1864 and then encoded by base64. |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentMd5; |
| | | @property (nonatomic, copy, nullable) NSString *contentMd5; |
| | | |
| | | /** |
| | | The object's name during the download according to RFC 2616. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentDisposition; |
| | | @property (nonatomic, copy, nullable) NSString * contentDisposition; |
| | | |
| | | /** |
| | | The content encoding during the object upload. Checks out RFC2616 for more detail. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentEncoding; |
| | | @property (nonatomic, copy, nullable) NSString * contentEncoding; |
| | | |
| | | /** |
| | | Specifies the cache control behavior when it's being downloaded.Checks out RFC 2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * cacheControl; |
| | | @property (nonatomic, copy, nullable) NSString * cacheControl; |
| | | |
| | | /** |
| | | Expiration time. Checks out RFC2616 for more information. |
| | | */ |
| | | @property (nonatomic, copy) NSString * expires; |
| | | @property (nonatomic, copy, nullable) NSString * expires; |
| | | |
| | | /** |
| | | The object's metadata, which start with x-oss-meta-, such as x-oss-meta-location. |
| | | Each request can have multiple metadata as long as the total size of all metadata is no bigger than 8KB. |
| | | It could include standard headers as well. |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * objectMeta; |
| | | @property (nonatomic, copy, nullable) NSDictionary * objectMeta; |
| | | |
| | | /** |
| | | Upload progress callback. |
| | | It's called on the background thread. |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingUploadProgressBlock uploadProgress; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingUploadProgressBlock uploadProgress; |
| | | |
| | | /** |
| | | * the sha1 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentSHA1; |
| | | @property (nonatomic, copy, nullable) NSString *contentSHA1; |
| | | |
| | | |
| | | @end |
| | |
| | | For Objects created by PUT, ETag is the MD5 value of the content data. For others, ETag is the UUID of the content. |
| | | ETag is used for checking data integrity. |
| | | */ |
| | | @property (nonatomic, copy) NSString * eTag; |
| | | @property (nonatomic, copy, nullable) NSString * eTag; |
| | | |
| | | /** |
| | | Specifies the next starting position. It's essentially the current object size. |
| | |
| | | /** |
| | | The content type |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentType; |
| | | @property (nonatomic, copy, nullable) NSString * contentType; |
| | | |
| | | /** |
| | | The content's MD5 digest. |
| | | It's calculated according to RFC 1864 and encoded in base64. |
| | | Though it's optional, it's recommended to turn it on for integrity check. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentMd5; |
| | | @property (nonatomic, copy, nullable) NSString * contentMd5; |
| | | |
| | | /** |
| | | The user metadata dictionary, which starts with x-oss-meta-. |
| | | The total size of user metadata can be no more than 8KB. |
| | | It could include standard http headers as well. |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * objectMeta; |
| | | @property (nonatomic, copy, nullable) NSDictionary * objectMeta; |
| | | |
| | | /** |
| | | * the sha1 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentSHA1; |
| | | @property (nonatomic, copy, nullable) NSString *contentSHA1; |
| | | |
| | | |
| | | @end |
| | |
| | | /** |
| | | The last modified time |
| | | */ |
| | | @property (nonatomic, copy) NSString * lastModifed; |
| | | @property (nonatomic, copy, nullable) NSString * lastModifed; |
| | | |
| | | /** |
| | | The ETag of the new object. |
| | | */ |
| | | @property (nonatomic, copy) NSString * eTag; |
| | | @property (nonatomic, copy, nullable) NSString * eTag; |
| | | @end |
| | | |
| | | /** |
| | |
| | | /** |
| | | Content type |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentType; |
| | | @property (nonatomic, copy, nullable) NSString * contentType; |
| | | |
| | | /** |
| | | The object's download name. Checks out RFC 2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentDisposition; |
| | | @property (nonatomic, copy, nullable) NSString * contentDisposition; |
| | | |
| | | /** |
| | | The content encoding. Checks out RFC 2616. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentEncoding; |
| | | @property (nonatomic, copy, nullable) NSString * contentEncoding; |
| | | |
| | | /** |
| | | Specifies the cache control behavior when it's downloaded. Checks out RFC 2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * cacheControl; |
| | | @property (nonatomic, copy, nullable) NSString * cacheControl; |
| | | |
| | | /** |
| | | Expiration time in milliseconds. Checks out RFC 2616 for more details. |
| | | */ |
| | | @property (nonatomic, copy) NSString * expires; |
| | | @property (nonatomic, copy, nullable) NSString * expires; |
| | | |
| | | /** |
| | | The dictionary of object's custom metadata, which starts with x-oss-meta-. |
| | | The total size of user metadata is no more than 8KB. |
| | | It could include other standard http headers. |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * objectMeta; |
| | | @property (nonatomic, copy, nullable) NSDictionary * objectMeta; |
| | | |
| | | /** |
| | | * When Setting this value to YES , parts will be uploaded in order. Default value is NO. |
| | |
| | | /** |
| | | The upload Id of the multipart upload |
| | | */ |
| | | @property (nonatomic, copy) NSString * uploadId; |
| | | @property (nonatomic, copy, nullable) NSString * uploadId; |
| | | @end |
| | | |
| | | /** |
| | |
| | | It's calculated according to RFC 1864 and encoded in base64. |
| | | Though it's optional, it's recommended to turn it on for integrity check. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentMd5; |
| | | @property (nonatomic, copy, nullable) NSString * contentMd5; |
| | | |
| | | /** |
| | | The in-memory data to upload from. |
| | | */ |
| | | @property (nonatomic, strong) NSData * uploadPartData; |
| | | @property (nonatomic, strong, nullable) NSData * uploadPartData; |
| | | |
| | | /** |
| | | The local file path to upload from |
| | | */ |
| | | @property (nonatomic, strong) NSURL * uploadPartFileURL; |
| | | @property (nonatomic, strong, nullable) NSURL * uploadPartFileURL; |
| | | |
| | | /** |
| | | The upload progress callback. |
| | | It runs in background thread (not UI thread); |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingUploadProgressBlock uploadPartProgress; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingUploadProgressBlock uploadPartProgress; |
| | | |
| | | /** |
| | | * the sha1 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentSHA1; |
| | | @property (nonatomic, copy, nullable) NSString *contentSHA1; |
| | | |
| | | @end |
| | | |
| | |
| | | The result class of uploading one part. |
| | | */ |
| | | @interface OSSUploadPartResult : OSSResult |
| | | @property (nonatomic, copy) NSString * eTag; |
| | | @property (nonatomic, copy, nullable) NSString * eTag; |
| | | @end |
| | | |
| | | /** |
| | |
| | | It's calculated according to RFC 1864 and encoded in base64. |
| | | Though it's optional, it's recommended to turn it on for integrity check. |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentMd5; |
| | | @property (nonatomic, copy, nullable) NSString * contentMd5; |
| | | |
| | | /** |
| | | All parts' information. |
| | |
| | | /** |
| | | Server side callback parameter |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * callbackParam; |
| | | @property (nonatomic, copy, nullable) NSDictionary * callbackParam; |
| | | |
| | | /** |
| | | Callback variables |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * callbackVar; |
| | | @property (nonatomic, copy, nullable) NSDictionary * callbackVar; |
| | | |
| | | /** |
| | | The metadata header |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * completeMetaHeader; |
| | | @property (nonatomic, copy, nullable) NSDictionary * completeMetaHeader; |
| | | |
| | | /** |
| | | * the sha1 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentSHA1; |
| | | @property (nonatomic, copy, nullable) NSString *contentSHA1; |
| | | |
| | | @end |
| | | |
| | |
| | | /** |
| | | The object's URL |
| | | */ |
| | | @property (nonatomic, copy) NSString * location; |
| | | @property (nonatomic, copy, nullable) NSString * location; |
| | | |
| | | /** |
| | | ETag (entity tag). |
| | | It's generated when the object is created. |
| | | */ |
| | | @property (nonatomic, copy) NSString * eTag; |
| | | @property (nonatomic, copy, nullable) NSString * eTag; |
| | | |
| | | /** |
| | | The callback response if the callback is specified. |
| | | The resutl class of initiating a multipart upload. |
| | | */ |
| | | @property (nonatomic, copy) NSString * serverReturnJsonString; |
| | | @property (nonatomic, copy, nullable) NSString * serverReturnJsonString; |
| | | @end |
| | | |
| | | /** |
| | |
| | | /** |
| | | The delimiter. |
| | | */ |
| | | @property (nonatomic, copy) NSString * delimiter; |
| | | @property (nonatomic, copy, nullable) NSString * delimiter; |
| | | |
| | | /** |
| | | The prefix. |
| | | */ |
| | | @property (nonatomic, copy) NSString * prefix; |
| | | @property (nonatomic, copy, nullable) NSString * prefix; |
| | | |
| | | /** |
| | | The max number of uploads. |
| | |
| | | /** |
| | | The key marker filter. |
| | | */ |
| | | @property (nonatomic, copy) NSString * keyMarker; |
| | | @property (nonatomic, copy, nullable) NSString * keyMarker; |
| | | |
| | | /** |
| | | The upload Id marker. |
| | | */ |
| | | @property (nonatomic, copy) NSString * uploadIdMarker; |
| | | @property (nonatomic, copy, nullable) NSString * uploadIdMarker; |
| | | |
| | | /** |
| | | The encoding type of the object in the response body. |
| | | */ |
| | | @property (nonatomic, copy) NSString * encodingType; |
| | | @property (nonatomic, copy, nullable) NSString * encodingType; |
| | | |
| | | @end |
| | | |
| | |
| | | /** |
| | | The marker filter of the objects returned---all objects returned are greater than this marker in lexicographic order. |
| | | */ |
| | | @property (nonatomic, copy) NSString * keyMarker; |
| | | @property (nonatomic, copy, nullable) NSString * keyMarker; |
| | | |
| | | /** |
| | | The delimiter to differentiate the folder object and file object. |
| | | For object whose name ends with the delimiter, then it's treated as folder or common prefixes. |
| | | */ |
| | | @property (nonatomic, copy) NSString * delimiter; |
| | | @property (nonatomic, copy, nullable) NSString * delimiter; |
| | | |
| | | /** |
| | | The prefix of the objects returned----the returned objects must have this prefix. |
| | | */ |
| | | @property (nonatomic, copy) NSString * prefix; |
| | | @property (nonatomic, copy, nullable) NSString * prefix; |
| | | |
| | | /** |
| | | The upload Id marker. |
| | | */ |
| | | @property (nonatomic, copy) NSString * uploadIdMarker; |
| | | @property (nonatomic, copy, nullable) NSString * uploadIdMarker; |
| | | |
| | | /** |
| | | The max entries to return. By default it's 100 and it could be up to 1000. |
| | |
| | | /** |
| | | If not all results are returned this time, the response request includes the NextKeyMarker element to indicate the value of KeyMarker in the next request. |
| | | */ |
| | | @property (nonatomic, copy) NSString * nextKeyMarker; |
| | | @property (nonatomic, copy, nullable) NSString * nextKeyMarker; |
| | | |
| | | /** |
| | | If not all results are returned this time, the response request includes the NextUploadMarker element to indicate the value of UploadMarker in the next request. |
| | | */ |
| | | @property (nonatomic, copy) NSString * nextUploadIdMarker; |
| | | @property (nonatomic, copy, nullable) NSString * nextUploadIdMarker; |
| | | |
| | | /** |
| | | Flag of truncated result. If it's truncated, it means there's more entries to return. |
| | |
| | | /** |
| | | The arrary of common prefixes. Each element is one common prefix. |
| | | */ |
| | | @property (nonatomic, strong) NSArray * commonPrefixes; |
| | | @property (nonatomic, strong, nullable) NSArray * commonPrefixes; |
| | | @end |
| | | |
| | | /** |
| | |
| | | /** |
| | | The upload Id |
| | | */ |
| | | @property (nonatomic, copy) NSString * uploadId; |
| | | @property (nonatomic, copy, nullable) NSString * uploadId; |
| | | |
| | | /** |
| | | Bucket name |
| | |
| | | Upload progress callback. |
| | | It runs at the background thread (not UI thread). |
| | | */ |
| | | @property (nonatomic, copy) OSSNetworkingUploadProgressBlock uploadProgress; |
| | | @property (nonatomic, copy, nullable) OSSNetworkingUploadProgressBlock uploadProgress; |
| | | |
| | | /** |
| | | The callback parmeters |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * callbackParam; |
| | | @property (nonatomic, copy, nullable) NSDictionary * callbackParam; |
| | | |
| | | /** |
| | | The callback variables |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * callbackVar; |
| | | @property (nonatomic, copy, nullable) NSDictionary * callbackVar; |
| | | |
| | | /** |
| | | Content type |
| | | */ |
| | | @property (nonatomic, copy) NSString * contentType; |
| | | @property (nonatomic, copy, nullable) NSString * contentType; |
| | | |
| | | /** |
| | | The metadata header |
| | | */ |
| | | @property (nonatomic, copy) NSDictionary * completeMetaHeader; |
| | | @property (nonatomic, copy, nullable) NSDictionary * completeMetaHeader; |
| | | |
| | | /** |
| | | * the sha1 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *contentSHA1; |
| | | @property (nonatomic, copy, nullable) NSString *contentSHA1; |
| | | |
| | | /** |
| | | * the md5 of content |
| | | */ |
| | | @property (nonatomic, copy) NSString *md5String; |
| | | @property (nonatomic, copy, nullable) NSString *md5String; |
| | | |
| | | /// The concurrent number of shard uploads |
| | | @property (nonatomic, assign) uint32_t threadNum; |
| | |
| | | /** |
| | | directory path about create record uploadId file |
| | | */ |
| | | @property (nonatomic, copy) NSString * recordDirectoryPath; |
| | | @property (nonatomic, copy, nullable) NSString * recordDirectoryPath; |
| | | |
| | | |
| | | /** |
| | |
| | | /** |
| | | The callback response, if the callback is specified. |
| | | */ |
| | | @property (nonatomic, copy) NSString * serverReturnJsonString; |
| | | @property (nonatomic, copy, nullable) NSString * serverReturnJsonString; |
| | | |
| | | @end |
| | | |
| | |
| | | [](#installation) |
| | | |
| | | [](#swift-versions-support) |
| | | [](https://github.com/apple/swift-package-manager) |
| | | [](https://github.com/swiftlang/swift-package-manager) |
| | | [](https://cocoapods.org/pods/CryptoSwift) |
| | | [](https://github.com/Carthage/Carthage) |
| | | |
| | |
| | | [Emerge Tools](https://www.emergetools.com/) is a suite of revolutionary products designed to supercharge mobile apps and the teams that build them. |
| | | |
| | | [<img alt="www.emergetools.com/" width="200" src="https://github-production-user-asset-6210df.s3.amazonaws.com/758033/256565082-a21f5ac1-ef39-4b56-a8d2-575adeb7fe55.png" />](https://www.emergetools.com) |
| | | |
| | | |
| | | ## Requirements |
| | | Good mood |
| | | |
| | |
| | | You can use [Swift Package Manager](https://swift.org/package-manager/) and specify dependency in `Package.swift` by adding this: |
| | | |
| | | ```swift |
| | | .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.8.2")) |
| | | .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "1.8.3") |
| | | ``` |
| | | |
| | | See: [Package.swift - manual](https://blog.krzyzanowskim.com/2016/08/09/package-swift-manual/) |
| | |
| | | You can use [CocoaPods](https://cocoapods.org/pods/CryptoSwift). |
| | | |
| | | ```ruby |
| | | pod 'CryptoSwift', '~> 1.8.2' |
| | | pod 'CryptoSwift', '~> 1.8.3' |
| | | ``` |
| | | |
| | | Bear in mind that CocoaPods will build CryptoSwift without [Whole-Module Optimization](https://swift.org/blog/whole-module-optimizations/) that may impact performance. You can change it manually after installation, or use [cocoapods-wholemodule](https://github.com/jedlewison/cocoapods-wholemodule) plugin. |
| | |
| | | case array |
| | | } |
| | | |
| | | internal fileprivate (set) var kind: Kind // Internal for testing only |
| | | internal fileprivate (set) var storage: [Word] // Internal for testing only; stored separately to prevent COW copies |
| | | internal fileprivate(set) var kind: Kind // Internal for testing only |
| | | internal fileprivate(set) var storage: [Word] // Internal for testing only; stored separately to prevent COW copies |
| | | |
| | | /// Initializes a new BigUInt with value 0. |
| | | public init() { |
| | |
| | | |
| | | private func sendEvent() { |
| | | |
| | | if let textFieldViewInfo = textFieldViewInfo, |
| | | let rootControllerConfiguration = rootControllerConfiguration, |
| | | if let rootControllerConfiguration = rootControllerConfiguration, |
| | | rootControllerConfiguration.isReady { |
| | | if keyboardInfo.keyboardShowing { |
| | | if lastEvent == .hide { |
| | |
| | | |
| | | typealias ConfigurationCompletion = (_ event: Event, |
| | | _ keyboardInfo: IQKeyboardInfo, |
| | | _ textFieldInfo: IQTextFieldViewInfo) -> Void |
| | | _ textFieldInfo: IQTextFieldViewInfo?) -> Void |
| | | |
| | | func registerChange(identifier: AnyHashable, changeHandler: @escaping ConfigurationCompletion) { |
| | | changeObservers[identifier] = changeHandler |
| | |
| | | changeObservers[identifier] = nil |
| | | } |
| | | |
| | | private func notify(event: Event, keyboardInfo: IQKeyboardInfo, textFieldViewInfo: IQTextFieldViewInfo) { |
| | | private func notify(event: Event, keyboardInfo: IQKeyboardInfo, textFieldViewInfo: IQTextFieldViewInfo?) { |
| | | lastEvent = event |
| | | |
| | | for block in changeObservers.values { |
| | |
| | | }) |
| | | |
| | | // Restoring the contentOffset of the lastScrollView |
| | | if let textFieldView: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, |
| | | let lastConfiguration: IQScrollViewConfiguration = lastScrollViewConfiguration { |
| | | if let lastConfiguration: IQScrollViewConfiguration = lastScrollViewConfiguration { |
| | | let textFieldView: UIView? = activeConfiguration.textFieldViewInfo?.textFieldView |
| | | |
| | | activeConfiguration.animate(alongsideTransition: { |
| | | |
| | |
| | | if !scrollView.contentOffset.equalTo(newContentOffset) { |
| | | |
| | | // (Bug ID: #1365, #1508, #1541) |
| | | let stackView: UIStackView? = textFieldView.iq.superviewOf(type: UIStackView.self, |
| | | belowView: scrollView) |
| | | let stackView: UIStackView? = textFieldView?.iq.superviewOf(type: UIStackView.self, |
| | | belowView: scrollView) |
| | | |
| | | // (Bug ID: #1901, #1996) |
| | | let animatedContentOffset: Bool = stackView != nil || |
| | |
| | | } |
| | | |
| | | // Setting toolbar to keyboard. |
| | | if let textFieldView: UITextInput = textField as? UITextInput { |
| | | if let textFieldView: any UITextInput = textField as? (any UITextInput) { |
| | | |
| | | // Bar style according to keyboard appearance |
| | | switch textFieldView.keyboardAppearance { |
| | |
| | | /** Remove any toolbar if it is IQToolbar. */ |
| | | internal func removeToolbarIfRequired() { // (Bug ID: #18) |
| | | |
| | | guard let siblings: [UIView] = responderViews(), !siblings.isEmpty, |
| | | let textField: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, |
| | | textField.responds(to: #selector(setter: UITextField.inputAccessoryView)), |
| | | textField.inputAccessoryView == nil || |
| | | textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag || |
| | | textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag else { |
| | | guard let siblings: [UIView] = responderViews(), !siblings.isEmpty else { |
| | | return |
| | | } |
| | | |
| | |
| | | showLog("Found \(siblings.count) responder sibling(s)") |
| | | |
| | | for view in siblings { |
| | | if let toolbar: IQToolbar = view.inputAccessoryView as? IQToolbar { |
| | | |
| | | // setInputAccessoryView: check (Bug ID: #307) |
| | | if view.responds(to: #selector(setter: UITextField.inputAccessoryView)), |
| | | toolbar.tag == IQKeyboardManager.kIQDoneButtonToolbarTag || |
| | | toolbar.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag { |
| | | |
| | | if let textField: UITextField = view as? UITextField { |
| | | textField.inputAccessoryView = nil |
| | | } else if let textView: UITextView = view as? UITextView { |
| | | textView.inputAccessoryView = nil |
| | | } |
| | | |
| | | view.reloadInputViews() |
| | | } |
| | | } |
| | | removeToolbarIfRequired(of: view) |
| | | } |
| | | |
| | | let elapsedTime: CFTimeInterval = CACurrentMediaTime() - startTime |
| | | showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) |
| | | } |
| | | |
| | | /** Remove any toolbar if it is IQToolbar. */ |
| | | internal func removeToolbarIfRequired(of view: UIView) { // (Bug ID: #18) |
| | | |
| | | guard view.responds(to: #selector(setter: UITextField.inputAccessoryView)), |
| | | let toolbar: IQToolbar = view.inputAccessoryView as? IQToolbar, |
| | | toolbar.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag || |
| | | toolbar.tag == IQKeyboardManager.kIQDoneButtonToolbarTag else { |
| | | return |
| | | } |
| | | |
| | | // setInputAccessoryView: check (Bug ID: #307) |
| | | if let textField: UITextField = view as? UITextField { |
| | | textField.inputAccessoryView = nil |
| | | } else if let textView: UITextView = view as? UITextView { |
| | | textView.inputAccessoryView = nil |
| | | } |
| | | } |
| | | |
| | | /** reloadInputViews to reload toolbar buttons enable/disable state on the fly Enhancement ID #434. */ |
| | | @objc func reloadInputViews() { |
| | | |
| | |
| | | } |
| | | |
| | | if keyboardConfiguration.overrideAppearance, |
| | | let textInput: UITextInput = textFieldView as? UITextInput, |
| | | let textInput: any UITextInput = textFieldView as? (any UITextInput), |
| | | textInput.keyboardAppearance != keyboardConfiguration.appearance { |
| | | // Setting textField keyboard appearance and reloading inputViews. |
| | | if let textFieldView: UITextField = textFieldView as? UITextField { |
| | |
| | | |
| | | // Removing gesture recognizer (Enhancement ID: #14) |
| | | textFieldView.window?.removeGestureRecognizer(resignFirstResponderGesture) |
| | | |
| | | removeToolbarIfRequired() |
| | | do { |
| | | if let startingConfiguration = startingTextViewConfiguration, |
| | | startingConfiguration.hasChanged { |
| | |
| | | /** |
| | | Returns the default singleton instance. |
| | | */ |
| | | @MainActor |
| | | @objc public static let shared: IQKeyboardManager = .init() |
| | | |
| | | // MARK: UIKeyboard handling |
| | |
| | | /// Wrapper for IQKeyboardManager compatible types. This type provides an extension point for |
| | | /// convenience methods in IQKeyboardManager. |
| | | @available(iOSApplicationExtension, unavailable) |
| | | public struct IQKeyboardManagerWrapper<Base> { |
| | | public let base: Base |
| | | public struct IQKeyboardManagerWrapper<Base: AnyObject> { |
| | | public private(set) weak var base: Base? |
| | | public init(_ base: Base) { |
| | | self.base = base |
| | | } |
| | |
| | | @available(iOSApplicationExtension, unavailable) |
| | | public protocol IQKeyboardManagerCompatible { |
| | | /// Type being extended. |
| | | associatedtype Base |
| | | associatedtype Base: AnyObject |
| | | |
| | | /// Instance IQKeyboardManager extension point. |
| | | @MainActor |
| | | var iq: IQKeyboardManagerWrapper<Base> { get set } |
| | | } |
| | | |
| | | // swiftlint:disable unused_setter_value |
| | | @available(iOSApplicationExtension, unavailable) |
| | | public extension IQKeyboardManagerCompatible { |
| | | public extension IQKeyboardManagerCompatible where Self: AnyObject { |
| | | |
| | | /// Instance IQKeyboardManager extension point. |
| | | @MainActor |
| | | var iq: IQKeyboardManagerWrapper<Self> { |
| | | get { IQKeyboardManagerWrapper(self) } |
| | | set {} |
| | |
| | | } |
| | | } |
| | | |
| | | @objc override weak open var delegate: UITextViewDelegate? { |
| | | @objc override weak open var delegate: (any UITextViewDelegate)? { |
| | | |
| | | get { |
| | | refreshPlaceholder() |
| | |
| | | |
| | | return newSize |
| | | } |
| | | |
| | | |
| | | @objc override open func caretRect(for position: UITextPosition) -> CGRect { |
| | | var originalRect = super.caretRect(for: position) |
| | | |
| | | // When placeholder is visible and text alignment is centered |
| | | if placeholderLabel.alpha == 1 && self.textAlignment == .center { |
| | | // Calculate the width of the placeholder text |
| | | let textSize = placeholderLabel.text?.size(withAttributes: [.font: placeholderLabel.font ?? UIFont.systemFont(ofSize: UIFont.systemFontSize)]) ?? .zero |
| | | let font = placeholderLabel.font ?? UIFont.systemFont(ofSize: UIFont.systemFontSize) |
| | | let textSize = placeholderLabel.text?.size(withAttributes: [.font: font]) ?? .zero |
| | | // Calculate the starting x position of the centered placeholder text |
| | | let centeredTextX = (self.bounds.size.width - textSize.width) / 2 |
| | | // Update the caret position to match the starting x position of the centered text |
| | |
| | | } |
| | | |
| | | return originalRect |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | private func updateAccessibility() { |
| | | if title == nil || title?.isEmpty == true { |
| | | isAccessibilityElement = false |
| | | accessibilityTraits = .none |
| | | // Swift 6: Reference to static property 'none' |
| | | // is not concurrency-safe because it involves shared mutable state |
| | | // accessibilityTraits = .none |
| | | accessibilityTraits = .init(rawValue: 0) |
| | | } else if titleButton?.isEnabled == true { |
| | | isAccessibilityElement = true |
| | | accessibilityTraits = .button |
| | | // Swift 6: Reference to static property 'button' |
| | | // is not concurrency-safe because it involves shared mutable state |
| | | // accessibilityTraits = .button |
| | | accessibilityTraits = .init(rawValue: 1) |
| | | } else { |
| | | isAccessibilityElement = true |
| | | accessibilityTraits = .staticText |
| | | |
| | | // Swift 6: Reference to static property 'staticText' |
| | | // is not concurrency-safe because it involves shared mutable state |
| | | // accessibilityTraits = .staticText |
| | | accessibilityTraits = .init(rawValue: 64) |
| | | } |
| | | } |
| | | } |
| | |
| | | IQToolbar references for better customization control. |
| | | */ |
| | | var toolbar: IQToolbar { |
| | | var toolbar: IQToolbar? = base.inputAccessoryView as? IQToolbar |
| | | var toolbar: IQToolbar? = base?.inputAccessoryView as? IQToolbar |
| | | |
| | | if toolbar == nil { |
| | | if toolbar == nil, let base = base { |
| | | toolbar = objc_getAssociatedObject(base, &AssociatedKeys.toolbar) as? IQToolbar |
| | | } |
| | | |
| | |
| | | return unwrappedToolbar |
| | | } else { |
| | | |
| | | let width: CGFloat = base.window?.windowScene?.screen.bounds.width ?? 0 |
| | | let width: CGFloat = base?.window?.windowScene?.screen.bounds.width ?? 0 |
| | | |
| | | let frame = CGRect(origin: .zero, size: .init(width: width, height: 44)) |
| | | let newToolbar = IQToolbar(frame: frame) |
| | | |
| | | objc_setAssociatedObject(base, &AssociatedKeys.toolbar, newToolbar, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.toolbar, newToolbar, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | |
| | | return newToolbar |
| | | } |
| | |
| | | */ |
| | | var hidePlaceholder: Bool { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.hidePlaceholder) as? Bool ?? false |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.hidePlaceholder) as? Bool ?? false |
| | | } |
| | | return false |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.hidePlaceholder, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | toolbar.titleBarButton.title = drawingPlaceholder |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.hidePlaceholder, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | toolbar.titleBarButton.title = drawingPlaceholder |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | var placeholder: String? { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.placeholder) as? String |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.placeholder) as? String |
| | | } |
| | | return nil |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.placeholder, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | toolbar.titleBarButton.title = drawingPlaceholder |
| | | if let base = base { |
| | | // swiftlint:disable line_length |
| | | objc_setAssociatedObject(base, &AssociatedKeys.placeholder, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | toolbar.titleBarButton.title = drawingPlaceholder |
| | | // swiftlint:enable line_length |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | return nil |
| | | } else if placeholder?.isEmpty == false { |
| | | return placeholder |
| | | } else if let placeholderable: IQPlaceholderable = base as? IQPlaceholderable { |
| | | } else if let placeholderable: any IQPlaceholderable = base as? (any IQPlaceholderable) { |
| | | |
| | | if let placeholder = placeholderable.attributedPlaceholder?.string, |
| | | !placeholder.isEmpty { |
| | |
| | | titleAccessibilityLabel: String? = nil) { |
| | | |
| | | // If can't set InputAccessoryView. Then return |
| | | if base.responds(to: #selector(setter: UITextField.inputAccessoryView)) { |
| | | if base?.responds(to: #selector(setter: UITextField.inputAccessoryView)) == true { |
| | | |
| | | // Creating a toolBar for phoneNumber keyboard |
| | | let toolbar: IQToolbar = toolbar |
| | |
| | | // Adding button to toolBar. |
| | | toolbar.items = items |
| | | |
| | | if let textInput: UITextInput = base as? UITextInput { |
| | | if let textInput: any UITextInput = base as? (any UITextInput) { |
| | | switch textInput.keyboardAppearance { |
| | | case .dark?: |
| | | toolbar.barStyle = .black |
| | |
| | | } |
| | | |
| | | // Setting toolbar to keyboard. |
| | | let reloadInputViews: Bool = base.inputAccessoryView != toolbar |
| | | let reloadInputViews: Bool = base?.inputAccessoryView != toolbar |
| | | if reloadInputViews { |
| | | if let textField: UITextField = base as? UITextField { |
| | | textField.inputAccessoryView = toolbar |
| | | } else if let textView: UITextView = base as? UITextView { |
| | | textView.inputAccessoryView = toolbar |
| | | } |
| | | base.reloadInputViews() |
| | | base?.reloadInputViews() |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldBeginEditing(_:))) { |
| | | if let unwrapDelegate: any UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector((any UITextFieldDelegate).textFieldShouldBeginEditing(_:))) { |
| | | return unwrapDelegate.textFieldShouldBeginEditing?(textField) ?? false |
| | | } |
| | | } |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:))) { |
| | | if let unwrapDelegate: any UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector((any UITextFieldDelegate).textFieldShouldEndEditing(_:))) { |
| | | return unwrapDelegate.textFieldShouldEndEditing?(textField) ?? false |
| | | } |
| | | } |
| | |
| | | @objc public func textFieldDidBeginEditing(_ textField: UITextField) { |
| | | updateReturnKeyTypeOnTextField(textField) |
| | | |
| | | var aDelegate: UITextFieldDelegate? = delegate |
| | | var aDelegate: (any UITextFieldDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | @objc public func textFieldDidEndEditing(_ textField: UITextField) { |
| | | |
| | | var aDelegate: UITextFieldDelegate? = delegate |
| | | var aDelegate: (any UITextFieldDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) { |
| | | |
| | | var aDelegate: UITextFieldDelegate? = delegate |
| | | var aDelegate: (any UITextFieldDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | let selector: Selector = #selector(UITextFieldDelegate.textField(_:shouldChangeCharactersIn: |
| | | if let unwrapDelegate: any UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | let selector: Selector = #selector((any UITextFieldDelegate).textField(_:shouldChangeCharactersIn: |
| | | replacementString:)) |
| | | if unwrapDelegate.responds(to: selector) { |
| | | return unwrapDelegate.textField?(textField, |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldClear(_:))) { |
| | | if let unwrapDelegate: any UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector((any UITextFieldDelegate).textFieldShouldClear(_:))) { |
| | | return unwrapDelegate.textFieldShouldClear?(textField) ?? false |
| | | } |
| | | } |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) { |
| | | if let unwrapDelegate: any UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { |
| | | if unwrapDelegate.responds(to: #selector((any UITextFieldDelegate).textFieldShouldReturn(_:))) { |
| | | isReturn = unwrapDelegate.textFieldShouldReturn?(textField) ?? false |
| | | } |
| | | } |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { |
| | | if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldBeginEditing(_:))) { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { |
| | | if unwrapDelegate.responds(to: #selector((any UITextViewDelegate).textViewShouldBeginEditing(_:))) { |
| | | return unwrapDelegate.textViewShouldBeginEditing?(textView) ?? false |
| | | } |
| | | } |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { |
| | | if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldEndEditing(_:))) { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { |
| | | if unwrapDelegate.responds(to: #selector((any UITextViewDelegate).textViewShouldEndEditing(_:))) { |
| | | return unwrapDelegate.textViewShouldEndEditing?(textView) ?? false |
| | | } |
| | | } |
| | |
| | | @objc public func textViewDidBeginEditing(_ textView: UITextView) { |
| | | updateReturnKeyTypeOnTextField(textView) |
| | | |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | @objc public func textViewDidEndEditing(_ textView: UITextView) { |
| | | |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { |
| | | let selector: Selector = #selector(UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:)) |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { |
| | | let selector = #selector((any UITextViewDelegate).textView(_:shouldChangeTextIn:replacementText:)) |
| | | if unwrapDelegate.responds(to: selector) { |
| | | isReturn = (unwrapDelegate.textView?(textView, |
| | | shouldChangeTextIn: range, |
| | |
| | | |
| | | @objc public func textViewDidChange(_ textView: UITextView) { |
| | | |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | @objc public func textViewDidChangeSelection(_ textView: UITextView) { |
| | | |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | let selector: Selector = #selector(textView as |
| | | (UITextView, URL, NSRange, UITextItemInteraction) -> Bool) |
| | | if unwrapDelegate.responds(to: selector) { |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | let selector: Selector = #selector(textView as |
| | | (UITextView, NSTextAttachment, NSRange, UITextItemInteraction) |
| | | -> Bool) |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange) -> Bool)) { |
| | | return unwrapDelegate.textView?(aTextView, |
| | | shouldInteractWith: URL, |
| | |
| | | |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange) -> Bool)) { |
| | | return unwrapDelegate.textView?(aTextView, |
| | | shouldInteractWith: textAttachment, |
| | |
| | | suggestedActions: [UIMenuElement]) -> UIMenu? { |
| | | if delegate == nil { |
| | | |
| | | if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | if let unwrapDelegate: any UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { |
| | | |
| | | let selector: Selector = #selector(textView as |
| | | (UITextView, NSRange, [UIMenuElement]) -> UIMenu?) |
| | |
| | | return nil |
| | | } |
| | | |
| | | public func textView(_ aTextView: UITextView, willPresentEditMenuWith animator: UIEditMenuInteractionAnimating) { |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | public func textView(_ aTextView: UITextView, |
| | | willPresentEditMenuWith animator: any UIEditMenuInteractionAnimating) { |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | aDelegate?.textView?(aTextView, willPresentEditMenuWith: animator) |
| | | } |
| | | |
| | | public func textView(_ aTextView: UITextView, willDismissEditMenuWith animator: UIEditMenuInteractionAnimating) { |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | public func textView(_ aTextView: UITextView, |
| | | willDismissEditMenuWith animator: any UIEditMenuInteractionAnimating) { |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | public func textView(_ textView: UITextView, |
| | | textItemMenuWillDisplayFor textItem: UITextItem, |
| | | animator: UIContextMenuInteractionAnimating) { |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | animator: any UIContextMenuInteractionAnimating) { |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | |
| | | public func textView(_ textView: UITextView, |
| | | textItemMenuWillEndFor textItem: UITextItem, |
| | | animator: UIContextMenuInteractionAnimating) { |
| | | var aDelegate: UITextViewDelegate? = delegate |
| | | animator: any UIContextMenuInteractionAnimating) { |
| | | var aDelegate: (any UITextViewDelegate)? = delegate |
| | | |
| | | if aDelegate == nil { |
| | | |
| | |
| | | /** |
| | | Delegate of textField/textView. |
| | | */ |
| | | @objc public weak var delegate: (UITextFieldDelegate & UITextViewDelegate)? |
| | | @objc public weak var delegate: (any UITextFieldDelegate & UITextViewDelegate)? |
| | | |
| | | /** |
| | | Set the last textfield return key type. Default is UIReturnKeyDefault. |
| | |
| | | @MainActor |
| | | internal final class IQTextFieldViewInfoModel: NSObject { |
| | | |
| | | weak var textFieldDelegate: UITextFieldDelegate? |
| | | weak var textViewDelegate: UITextViewDelegate? |
| | | weak var textFieldDelegate: (any UITextFieldDelegate)? |
| | | weak var textViewDelegate: (any UITextViewDelegate)? |
| | | weak var textFieldView: UIView? |
| | | let originalReturnKeyType: UIReturnKeyType |
| | | |
| | |
| | | */ |
| | | var ignoreScrollingAdjustment: Bool { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.ignoreScrollingAdjustment) as? Bool ?? false |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.ignoreScrollingAdjustment) as? Bool ?? false |
| | | } |
| | | return false |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.ignoreScrollingAdjustment, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.ignoreScrollingAdjustment, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | var ignoreContentInsetAdjustment: Bool { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.ignoreContentInsetAdjustment) as? Bool ?? false |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.ignoreContentInsetAdjustment) as? Bool ?? false |
| | | } |
| | | return false |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.ignoreContentInsetAdjustment, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.ignoreContentInsetAdjustment, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | var restoreContentOffset: Bool { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.restoreContentOffset) as? Bool ?? false |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.restoreContentOffset) as? Bool ?? false |
| | | } |
| | | return false |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.restoreContentOffset, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.restoreContentOffset, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | */ |
| | | var distanceFromKeyboard: CGFloat { |
| | | get { |
| | | if let value = objc_getAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard) as? CGFloat { |
| | | return value |
| | | } else { |
| | | return UIView.defaultKeyboardDistance |
| | | if let base = base { |
| | | if let value = objc_getAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard) as? CGFloat { |
| | | return value |
| | | } |
| | | } |
| | | return UIView.defaultKeyboardDistance |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | var ignoreSwitchingByNextPrevious: Bool { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.ignoreSwitchingByNextPrevious) as? Bool ?? false |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.ignoreSwitchingByNextPrevious) as? Bool ?? false |
| | | } |
| | | return false |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.ignoreSwitchingByNextPrevious, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.ignoreSwitchingByNextPrevious, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | var enableMode: IQEnableMode { |
| | | get { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.enableMode) as? IQEnableMode ?? .default |
| | | if let base = base { |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.enableMode) as? IQEnableMode ?? .default |
| | | } |
| | | return .default |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.enableMode, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.enableMode, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | var resignOnTouchOutsideMode: IQEnableMode { |
| | | get { |
| | | guard let base = base else { |
| | | return .default |
| | | } |
| | | return objc_getAssociatedObject(base, &AssociatedKeys.resignOnTouchOutsideMode) as? IQEnableMode ?? .default |
| | | } |
| | | set(newValue) { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.resignOnTouchOutsideMode, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | if let base = base { |
| | | objc_setAssociatedObject(base, &AssociatedKeys.resignOnTouchOutsideMode, |
| | | newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | var controllersHierarchy: [UIViewController] = [] |
| | | |
| | | if var topController: UIViewController = base.window?.rootViewController { |
| | | if var topController: UIViewController = base?.window?.rootViewController { |
| | | controllersHierarchy.append(topController) |
| | | |
| | | while let presented: UIViewController = topController.presentedViewController { |
| | |
| | | */ |
| | | func superviewOf<T: UIView>(type classType: T.Type, belowView: UIView? = nil) -> T? { |
| | | |
| | | var superView: UIView? = base.superview |
| | | var superView: UIView? = base?.superview |
| | | |
| | | while let unwrappedSuperView: UIView = superView { |
| | | |
| | |
| | | var tempTextFields: [UIView] = [] |
| | | |
| | | // Getting all siblings |
| | | if let siblings: [UIView] = base.superview?.subviews { |
| | | if let siblings: [UIView] = base?.superview?.subviews { |
| | | for textField in siblings { |
| | | if textField == base || !textField.iq.ignoreSwitchingByNextPrevious, |
| | | textField.iq.canBecomeFirstResponder() { |
| | |
| | | // Array of (UITextField/UITextView's). |
| | | var textfields: [UIView] = [] |
| | | |
| | | for textField in base.subviews { |
| | | for textField in base?.subviews ?? [] { |
| | | |
| | | if textField == base || !textField.iq.ignoreSwitchingByNextPrevious, |
| | | textField.iq.canBecomeFirstResponder() { |
| | |
| | | // Sometimes there are hidden or disabled views and textField inside them still recorded, |
| | | // so we added some more validations here (Bug ID: #458) |
| | | // Uncommented else (Bug ID: #625) |
| | | else if textField.subviews.count != 0, base.isUserInteractionEnabled, !base.isHidden, base.alpha != 0.0 { |
| | | else if textField.subviews.count != 0, |
| | | base?.isUserInteractionEnabled == true, |
| | | base?.isHidden == false, base?.alpha != 0.0 { |
| | | for deepView in textField.iq.deepResponderViews() { |
| | | textfields.append(deepView) |
| | | } |
| | |
| | | |
| | | var canBecomeFirstResponder: Bool = false |
| | | |
| | | if base.conforms(to: UITextInput.self) { |
| | | if base?.conforms(to: (any UITextInput).self) == true { |
| | | // Setting toolbar to keyboard. |
| | | if let textView: UITextView = base as? UITextView { |
| | | canBecomeFirstResponder = textView.isEditable |
| | |
| | | } |
| | | |
| | | if canBecomeFirstResponder { |
| | | canBecomeFirstResponder = base.isUserInteractionEnabled && |
| | | !base.isHidden && |
| | | base.alpha != 0.0 && |
| | | canBecomeFirstResponder = base?.isUserInteractionEnabled == true && |
| | | base?.isHidden == false && |
| | | base?.alpha != 0.0 && |
| | | !isAlertViewTextField() && |
| | | textFieldSearchBar() == nil |
| | | } |
| | |
| | | */ |
| | | func textFieldSearchBar() -> UISearchBar? { |
| | | |
| | | var responder: UIResponder? = base.next |
| | | var responder: UIResponder? = base?.next |
| | | |
| | | while let bar: UIResponder = responder { |
| | | |
| | |
| | | func depth() -> Int { |
| | | var depth: Int = 0 |
| | | |
| | | if let superView: UIView = base.superview { |
| | | if let superView: UIView = base?.superview { |
| | | depth = superView.iq.depth()+1 |
| | | } |
| | | |
| | |
| | | |
| | | #### Key Features |
| | | |
| | | 1) `**CODELESS**, Zero Lines of Code` |
| | | 1) `One Lines of Code` |
| | | |
| | | 2) `Works Automatically` |
| | | |
| | |
| | | |
| | | ], |
| | | "QMUIKit": [ |
| | | |
| | | "~>4.7.0" |
| | | ], |
| | | "IQKeyboardManagerSwift": [ |
| | | |
| | |
| | | PODS: |
| | | - Alamofire (5.9.1) |
| | | - AliyunOSSiOS (2.10.21) |
| | | - CryptoSwift (1.8.2) |
| | | - AliyunOSSiOS (2.10.22) |
| | | - CryptoSwift (1.8.3) |
| | | - Differentiator (5.0.0) |
| | | - EmptyDataSet-Swift (5.0.0) |
| | | - FFPage (3.0.0) |
| | | - HandyJSON (5.0.2) |
| | | - IQKeyboardManager (6.5.19) |
| | | - IQKeyboardManagerSwift (7.0.3) |
| | | - IQKeyboardManagerSwift (7.1.1) |
| | | - JQTools (0.1.5): |
| | | - EmptyDataSet-Swift |
| | | - HandyJSON |
| | |
| | | - IQKeyboardManagerSwift |
| | | - MJRefresh |
| | | - ObjectMapper |
| | | - QMUIKit |
| | | - QMUIKit (~> 4.7.0) |
| | | - RxCocoa |
| | | - RxDataSources |
| | | - RxSwift |
| | |
| | | - RxRelay (6.7.1): |
| | | - RxSwift (= 6.7.1) |
| | | - RxSwift (6.7.1) |
| | | - SDWebImage (5.19.2): |
| | | - SDWebImage/Core (= 5.19.2) |
| | | - SDWebImage/Core (5.19.2) |
| | | - SDWebImage (5.19.6): |
| | | - SDWebImage/Core (= 5.19.6) |
| | | - SDWebImage/Core (5.19.6) |
| | | - SnapKit (5.7.1) |
| | | - SPPageMenu (3.5.0) |
| | | - SVProgressHUD (2.3.1): |
| | | - SVProgressHUD/Core (= 2.3.1) |
| | | - SVProgressHUD/Core (2.3.1) |
| | | - SwiftAudioPlayer (7.6.0) |
| | | - SwifterSwift (6.2.0): |
| | | - SwifterSwift/AppKit (= 6.2.0) |
| | | - SwifterSwift/Combine (= 6.2.0) |
| | |
| | | - SwifterSwift/SwiftStdlib (6.2.0) |
| | | - SwifterSwift/UIKit (6.2.0) |
| | | - SwifterSwift/WebKit (6.2.0) |
| | | - TZImagePickerController (3.8.5): |
| | | - TZImagePickerController/Basic (= 3.8.5) |
| | | - TZImagePickerController/Location (= 3.8.5) |
| | | - TZImagePickerController/Basic (3.8.5) |
| | | - TZImagePickerController/Location (3.8.5) |
| | | - TZImagePickerController (3.8.7): |
| | | - TZImagePickerController/Basic (= 3.8.7) |
| | | - TZImagePickerController/Location (= 3.8.7) |
| | | - TZImagePickerController/Basic (3.8.7) |
| | | - TZImagePickerController/Location (3.8.7) |
| | | - UserDefaultsStore (1.5.0) |
| | | - VTMagic (1.2.4): |
| | | - VTMagic/Core (= 1.2.4) |
| | |
| | | - FFPage |
| | | - JQTools (from `/Users/yvkd/MyProject/JQTools`) |
| | | - Lantern |
| | | - QMUIKit |
| | | - SPPageMenu |
| | | - SVProgressHUD |
| | | - SwiftAudioPlayer |
| | | - SwifterSwift |
| | | - WechatOpenSDK-XCFramework |
| | | |
| | |
| | | - SnapKit |
| | | - SPPageMenu |
| | | - SVProgressHUD |
| | | - SwiftAudioPlayer |
| | | - SwifterSwift |
| | | - TZImagePickerController |
| | | - UserDefaultsStore |
| | |
| | | |
| | | SPEC CHECKSUMS: |
| | | Alamofire: f36a35757af4587d8e4f4bfa223ad10be2422b8c |
| | | AliyunOSSiOS: 1f091b3aeec9f7a5fd722cb511704116f2ca468d |
| | | CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea |
| | | AliyunOSSiOS: b46648fd78909a567e3743fe94183748a407b175 |
| | | CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483 |
| | | Differentiator: e8497ceab83c1b10ca233716d547b9af21b9344d |
| | | EmptyDataSet-Swift: eb382c0c87a2d9c678077385a595cec52da38171 |
| | | FFPage: 481cc0f2dde0f6be84a2359b6c86272e0024dc8d |
| | | HandyJSON: 9e4e236f5d2dbefad5155a77417bbea438201c03 |
| | | IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485 |
| | | IQKeyboardManagerSwift: f9c5dc36cba16ddd2e51fa7d51c34a2e083029b5 |
| | | JQTools: d2b720c901e39d9959c9342ba42f9eba58886a02 |
| | | IQKeyboardManagerSwift: d7f3d3a562c237a0e7335e657cd598c452f57f1b |
| | | JQTools: af562f97302a433989c23bfb31e24458eb6469ad |
| | | Lantern: b192e7146c6d04e15e627f37281254a6a8593703 |
| | | MJRefresh: ff9e531227924c84ce459338414550a05d2aea78 |
| | | ObjcExceptionBridging: d3d37d62981bb7f252ecb31b62d7e23a96bbfb8a |
| | |
| | | RxDataSources: aa47cc1ed6c500fa0dfecac5c979b723542d79cf |
| | | RxRelay: 4151ba01152436b08271e08410135e099880eae5 |
| | | RxSwift: b9a93a26031785159e11abd40d1a55bcb8057e52 |
| | | SDWebImage: dfe95b2466a9823cf9f0c6d01217c06550d7b29a |
| | | SDWebImage: a79252b60f4678812d94316c91da69ec83089c9f |
| | | SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a |
| | | SPPageMenu: da182aafcec55719d5c326103cc7716c1e48f311 |
| | | SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22 |
| | | SwiftAudioPlayer: a546709faf47f3ab0cb59e41ba4432e6bb61db0a |
| | | SwifterSwift: dd00873fb09cde19da88bdb2878f9fe70fe27b0f |
| | | TZImagePickerController: c0f8e83c27cb08f7d812b1d066a5934d30ff78ad |
| | | TZImagePickerController: 5f35bb7266552e36ca834bafa955b869fe086124 |
| | | UserDefaultsStore: 905e30372ff432197d199ce1f6fe51be7bf69628 |
| | | VTMagic: b49e5f456dbcbfd9a3588ba92417233a105bc193 |
| | | WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f |
| | | XCGLogger: 399c5885210b4e2ad79d9f7a29b105d672ef724f |
| | | |
| | | PODFILE CHECKSUM: b6fd53f7f3a4f07f827c1dd265be4ea09db142cb |
| | | PODFILE CHECKSUM: 09bcd0f1f48732e13cf706127b08a5fe4df60434 |
| | | |
| | | COCOAPODS: 1.15.2 |
| | |
| | | <key>orderHint</key> |
| | | <integer>32</integer> |
| | | </dict> |
| | | <key>SwifterSwift-SwifterSwift_Privacy.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>37</integer> |
| | | </dict> |
| | | <key>SwifterSwift.xcscheme</key> |
| | | <key>SwiftAudioPlayer.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>36</integer> |
| | | </dict> |
| | | <key>TZImagePickerController.xcscheme</key> |
| | | <key>SwifterSwift-SwifterSwift_Privacy.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>38</integer> |
| | | </dict> |
| | | <key>UserDefaultsStore.xcscheme</key> |
| | | <key>SwifterSwift.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>37</integer> |
| | | </dict> |
| | | <key>TZImagePickerController.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>39</integer> |
| | | </dict> |
| | | <key>VTMagic.xcscheme</key> |
| | | <key>UserDefaultsStore.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>40</integer> |
| | | </dict> |
| | | <key>WechatOpenSDK-XCFramework.xcscheme</key> |
| | | <key>VTMagic.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>41</integer> |
| | | </dict> |
| | | <key>WechatOpenSDK-XCFramework.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>42</integer> |
| | | </dict> |
| | | <key>XCGLogger-XCGLogger.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>43</integer> |
| | | <integer>44</integer> |
| | | </dict> |
| | | <key>XCGLogger.xcscheme</key> |
| | | <dict> |
| | | <key>isShown</key> |
| | | <false/> |
| | | <key>orderHint</key> |
| | | <integer>42</integer> |
| | | <integer>43</integer> |
| | | </dict> |
| | | </dict> |
| | | <key>SuppressBuildableAutocreation</key> |
| | |
| | | |
| | | From Xcode 15 Apple will verify the signature of binary XCFramework, to avoid supply chain attack. |
| | | |
| | | The fingerprint currently should be `FC 3B 10 13 86 34 4C 50 DB 70 2A 9A D1 01 6F B5 1A 3E CC 8B 9D A9 B7 AE 47 A0 48 D4 D0 63 39 83` |
| | | |
| | | The certificate is stored in the repo [here](https://github.com/SDWebImage/SDWebImage/blob/master/Certificate/SDWebImage%20Signing%20Certificate.cer) |
| | | |
| | | The public key is stored in the repo [here](https://github.com/SDWebImage/SDWebImage/blob/master/Certificate/SDWebImage%20Signing%20Certificate.pem) |
| | |
| | | /** |
| | | The image class which supports animating on `SDAnimatedImageView`. You can also use it on normal UIImageView/NSImageView. |
| | | */ |
| | | NS_SWIFT_NONISOLATED |
| | | @interface SDAnimatedImage : UIImage <SDAnimatedImage> |
| | | |
| | | // This class override these methods from UIImage(NSImage), and it supports NSSecureCoding. |
| | | // You should use these methods to create a new animated image. Use other methods just call super instead. |
| | | // @note Before 5.19, these initializer will return nil for static image (when all candidate SDAnimatedImageCoder returns nil instance), like JPEG data. After 5.19, these initializer will retry for static image as well, so JPEG data will return non-nil instance. |
| | | // @note Before 5.19, these initializer will return nil for static image (when all candidate SDAnimatedImageCoder returns nil instance), like JPEG data. After 5.19, these initializer will retry for static image as well, so JPEG data will return non-nil instance. For vector image(PDF/SVG), always return nil. |
| | | // @note When the animated image frame count <= 1, all the `SDAnimatedImageProvider` protocol methods will return nil or 0 value, you'd better check the frame count before usage and keep fallback. |
| | | + (nullable instancetype)imageNamed:(nonnull NSString *)name; // Cache in memory, no Asset Catalog support |
| | | #if __has_include(<UIKit/UITraitCollection.h>) |
| | |
| | | if (!data || data.length == 0) { |
| | | return nil; |
| | | } |
| | | // Vector image does not supported, guard firstly |
| | | SDImageFormat format = [NSData sd_imageFormatForImageData:data]; |
| | | if (format == SDImageFormatSVG || format == SDImageFormatPDF) { |
| | | return nil; |
| | | } |
| | | |
| | | id<SDAnimatedImageCoder> animatedCoder = nil; |
| | | SDImageCoderMutableOptions *mutableCoderOptions; |
| | | if (options != nil) { |
| | |
| | | if (!image) { |
| | | return nil; |
| | | } |
| | | // Vector image does not supported, guard secondly |
| | | if (image.sd_isVector) { |
| | | return nil; |
| | | } |
| | | #if SD_MAC |
| | | self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:kCGImagePropertyOrientationUp]; |
| | | #else |
| | |
| | | For UIKit: use `-startAnimating`, `-stopAnimating` to control animating. `isAnimating` to check animation state. |
| | | For AppKit: use `-setAnimates:` to control animating, `animates` to check animation state. This view is layer-backed. |
| | | */ |
| | | NS_SWIFT_UI_ACTOR |
| | | @interface SDAnimatedImageView : UIImageView |
| | | /** |
| | | The internal animation player. |
| | |
| | | #endif |
| | | self.scale = screenScale; |
| | | self.opaque = NO; |
| | | self.preferredRange = SDGraphicsImageRendererFormatRangeStandard; |
| | | #if SD_UIKIT |
| | | } |
| | | #endif |
| | |
| | | #endif |
| | | self.scale = screenScale; |
| | | self.opaque = NO; |
| | | self.preferredRange = SDGraphicsImageRendererFormatRangeStandard; |
| | | #if SD_UIKIT |
| | | } |
| | | #endif |
| | |
| | | } |
| | | if (image) { |
| | | SDImageForceDecodePolicy policy = SDImageForceDecodePolicyAutomatic; |
| | | NSNumber *polivyValue = context[SDWebImageContextImageForceDecodePolicy]; |
| | | if (polivyValue != nil) { |
| | | policy = polivyValue.unsignedIntegerValue; |
| | | NSNumber *policyValue = context[SDWebImageContextImageForceDecodePolicy]; |
| | | if (policyValue != nil) { |
| | | policy = policyValue.unsignedIntegerValue; |
| | | } |
| | | // TODO: Deprecated, remove in SD 6.0... |
| | | #pragma clang diagnostic push |
| | |
| | | + (BOOL)CGImageContainsAlpha:(_Nonnull CGImageRef)cgImage; |
| | | |
| | | /** |
| | | Detect whether the CGImage is lazy and not-yet decoded. (lazy means, only when the caller access the underlying bitmap buffer via provider like `CGDataProviderCopyData` or `CGDataProviderRetainBytePtr`, the decoder will allocate memory, it's a lazy allocation) |
| | | The implementation use the Core Graphics internal to check whether the CGImage is `CGImageProvider` based, or `CGDataProvider` based. The `CGDataProvider` based is treated as non-lazy. |
| | | */ |
| | | + (BOOL)CGImageIsLazy:(_Nonnull CGImageRef)cgImage; |
| | | |
| | | /** |
| | | Create a decoded CGImage by the provided CGImage. This follows The Create Rule and you are response to call release after usage. |
| | | It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView. |
| | | @note This actually call `CGImageCreateDecoded:orientation:` with the Up orientation. |
| | |
| | | return hasAlpha; |
| | | } |
| | | |
| | | + (BOOL)CGImageIsLazy:(CGImageRef)cgImage { |
| | | if (!cgImage) { |
| | | return NO; |
| | | } |
| | | // CoreGraphics use CGImage's C struct filed (offset 0xd8 on iOS 17.0) |
| | | // But since the description of `CGImageRef` always contains the `[DP]` (DataProvider) and `[IP]` (ImageProvider), we can use this as a hint |
| | | NSString *description = (__bridge_transfer NSString *)CFCopyDescription(cgImage); |
| | | if (description) { |
| | | // Solution 1: Parse the description to get provider |
| | | // <CGImage 0x10740ffe0> (IP) -> YES |
| | | // <CGImage 0x10740ffe0> (DP) -> NO |
| | | NSArray<NSString *> *lines = [description componentsSeparatedByString:@"\n"]; |
| | | if (lines.count > 0) { |
| | | NSString *firstLine = lines[0]; |
| | | NSRange startRange = [firstLine rangeOfString:@"("]; |
| | | NSRange endRange = [firstLine rangeOfString:@")"]; |
| | | if (startRange.location != NSNotFound && endRange.location != NSNotFound) { |
| | | NSRange resultRange = NSMakeRange(startRange.location + 1, endRange.location - startRange.location - 1); |
| | | NSString *providerString = [firstLine substringWithRange:resultRange]; |
| | | if ([providerString isEqualToString:@"IP"]) { |
| | | return YES; |
| | | } else if ([providerString isEqualToString:@"DP"]) { |
| | | return NO; |
| | | } else { |
| | | // New cases ? fallback |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // Solution 2: Use UTI metadata |
| | | CFStringRef uttype = CGImageGetUTType(cgImage); |
| | | if (uttype) { |
| | | // Only ImageIO can set `com.apple.ImageIO.imageSourceTypeIdentifier` metadata for lazy decoded CGImage |
| | | return YES; |
| | | } else { |
| | | return NO; |
| | | } |
| | | } |
| | | |
| | | + (CGImageRef)CGImageCreateDecoded:(CGImageRef)cgImage { |
| | | return [self CGImageCreateDecoded:cgImage orientation:kCGImagePropertyOrientationUp]; |
| | | } |
| | |
| | | // Check policy (automatic) |
| | | CGImageRef cgImage = image.CGImage; |
| | | if (cgImage) { |
| | | CFStringRef uttype = CGImageGetUTType(cgImage); |
| | | if (uttype) { |
| | | // Only ImageIO can set `com.apple.ImageIO.imageSourceTypeIdentifier` |
| | | // Check if it's lazy CGImage wrapper or not |
| | | BOOL isLazy = [SDImageCoderHelper CGImageIsLazy:cgImage]; |
| | | if (isLazy) { |
| | | // Lazy CGImage should trigger force decode before rendering |
| | | return YES; |
| | | } else { |
| | | // Now, let's check if the CGImage is hardware supported (not byte-aligned will cause extra copy) |
| | | // Now, let's check if this non-lazy CGImage is hardware supported (not byte-aligned will cause extra copy) |
| | | BOOL isSupported = [SDImageCoderHelper CGImageIsHardwareSupported:cgImage]; |
| | | return !isSupported; |
| | | } |
| | |
| | | } |
| | | |
| | | + (NSString *)imageUTType { |
| | | return (__bridge NSString *)kSDUTTypeHEIC; |
| | | // See: https://nokiatech.github.io/heif/technical.html |
| | | // Actually HEIC has another concept called `non-timed Image Sequence`, which can be encoded using `public.heic` |
| | | // But current SDWebImage does not has this design, I don't know whether there are use case for this |
| | | // So we just replace and always use `timed Image Sequence`, means, animated image for encoding |
| | | return (__bridge NSString *)kSDUTTypeHEICS; |
| | | } |
| | | |
| | | + (NSString *)dictionaryProperty { |
| | |
| | | if (!imageRef) { |
| | | return nil; |
| | | } |
| | | BOOL isDecoded = NO; |
| | | // Thumbnail image post-process |
| | | if (!createFullImage) { |
| | | if (preserveAspectRatio) { |
| | |
| | | if (scaledImageRef) { |
| | | CGImageRelease(imageRef); |
| | | imageRef = scaledImageRef; |
| | | isDecoded = YES; |
| | | } |
| | | } |
| | | } |
| | | // Check whether output CGImage is decoded |
| | | BOOL isLazy = [SDImageCoderHelper CGImageIsLazy:imageRef]; |
| | | if (!lazyDecode) { |
| | | if (!isDecoded) { |
| | | // Use CoreGraphics to trigger immediately decode |
| | | if (isLazy) { |
| | | // Use CoreGraphics to trigger immediately decode to drop lazy CGImage |
| | | CGImageRef decodedImageRef = [SDImageCoderHelper CGImageCreateDecoded:imageRef]; |
| | | if (decodedImageRef) { |
| | | CGImageRelease(imageRef); |
| | | imageRef = decodedImageRef; |
| | | isDecoded = YES; |
| | | isLazy = NO; |
| | | } |
| | | } |
| | | } else if (animatedImage) { |
| | |
| | | UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:exifOrientation]; |
| | | #endif |
| | | CGImageRelease(imageRef); |
| | | image.sd_isDecoded = isDecoded; |
| | | image.sd_isDecoded = !isLazy; |
| | | |
| | | return image; |
| | | } |
| | |
| | | } |
| | | |
| | | NSMutableData *imageData = [NSMutableData data]; |
| | | CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format]; |
| | | NSString *imageUTType = self.class.imageUTType; |
| | | |
| | | // Create an image destination. Animated Image does not support EXIF image orientation TODO |
| | | // The `CGImageDestinationCreateWithData` will log a warning when count is 0, use 1 instead. |
| | | CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frames.count ?: 1, NULL); |
| | | CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, (__bridge CFStringRef)imageUTType, frames.count ?: 1, NULL); |
| | | if (!imageDestination) { |
| | | // Handle failure. |
| | | return nil; |
| | |
| | | #else |
| | | CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationUp; |
| | | #endif |
| | | properties[(__bridge NSString *)kCGImagePropertyOrientation] = @(exifOrientation); |
| | | if (exifOrientation != kCGImagePropertyOrientationUp) { |
| | | properties[(__bridge NSString *)kCGImagePropertyOrientation] = @(exifOrientation); |
| | | } |
| | | // Encoding Options |
| | | double compressionQuality = 1; |
| | | if (options[SDImageCoderEncodeCompressionQuality]) { |
| | |
| | | |
| | | CFRelease(imageDestination); |
| | | |
| | | // In some beta version, ImageIO `CGImageDestinationFinalize` returns success, but the data buffer is 0 bytes length. |
| | | if (imageData.length == 0) { |
| | | return nil; |
| | | } |
| | | |
| | | return [imageData copy]; |
| | | } |
| | | |
| | |
| | | } |
| | | if (image) { |
| | | SDImageForceDecodePolicy policy = SDImageForceDecodePolicyAutomatic; |
| | | NSNumber *polivyValue = context[SDWebImageContextImageForceDecodePolicy]; |
| | | if (polivyValue != nil) { |
| | | policy = polivyValue.unsignedIntegerValue; |
| | | NSNumber *policyValue = context[SDWebImageContextImageForceDecodePolicy]; |
| | | if (policyValue != nil) { |
| | | policy = policyValue.unsignedIntegerValue; |
| | | } |
| | | // TODO: Deprecated, remove in SD 6.0... |
| | | #pragma clang diagnostic push |
| | |
| | | } |
| | | if (image) { |
| | | SDImageForceDecodePolicy policy = SDImageForceDecodePolicyAutomatic; |
| | | NSNumber *polivyValue = context[SDWebImageContextImageForceDecodePolicy]; |
| | | if (polivyValue != nil) { |
| | | policy = polivyValue.unsignedIntegerValue; |
| | | NSNumber *policyValue = context[SDWebImageContextImageForceDecodePolicy]; |
| | | if (policyValue != nil) { |
| | | policy = policyValue.unsignedIntegerValue; |
| | | } |
| | | // TODO: Deprecated, remove in SD 6.0... |
| | | #pragma clang diagnostic push |
| | |
| | | /** |
| | | The download's metrics. This will be nil if download operation does not support metrics. |
| | | */ |
| | | @property (nonatomic, strong, nullable, readonly) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | @property (nonatomic, strong, nullable, readonly) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | |
| | | @end |
| | | |
| | |
| | | @property (nonatomic, strong, nullable, readwrite) NSURL *url; |
| | | @property (nonatomic, strong, nullable, readwrite) NSURLRequest *request; |
| | | @property (nonatomic, strong, nullable, readwrite) NSURLResponse *response; |
| | | @property (nonatomic, strong, nullable, readwrite) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | @property (nonatomic, strong, nullable, readwrite) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | @property (nonatomic, weak, nullable, readwrite) id downloadOperationCancelToken; |
| | | @property (nonatomic, weak, nullable) NSOperation<SDWebImageDownloaderOperation> *downloadOperation; |
| | | @property (nonatomic, assign, getter=isCancelled) BOOL cancelled; |
| | |
| | | } |
| | | } |
| | | |
| | | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) { |
| | | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)) { |
| | | |
| | | // Identify the operation that runs this task and pass it the delegate method |
| | | NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:task]; |
| | |
| | | |
| | | @optional |
| | | @property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask; |
| | | @property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | @property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | |
| | | // These operation-level config was inherited from downloader. See `SDWebImageDownloaderConfig` for documentation. |
| | | @property (strong, nonatomic, nullable) NSURLCredential *credential; |
| | |
| | | * The collected metrics from `-URLSession:task:didFinishCollectingMetrics:`. |
| | | * This can be used to collect the network metrics like download duration, DNS lookup duration, SSL handshake duration, etc. See Apple's documentation: https://developer.apple.com/documentation/foundation/urlsessiontaskmetrics |
| | | */ |
| | | @property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | @property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | |
| | | /** |
| | | * The credential used for authentication challenges in `-URLSession:task:didReceiveChallenge:completionHandler:`. |
| | |
| | | |
| | | @property (strong, nonatomic, readwrite, nullable) NSURLSessionTask *dataTask; |
| | | |
| | | @property (strong, nonatomic, readwrite, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | @property (strong, nonatomic, readwrite, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)); |
| | | |
| | | @property (strong, nonatomic, nonnull) NSOperationQueue *coderQueue; // the serial operation queue to do image decoding |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) { |
| | | - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)) { |
| | | self.metrics = metrics; |
| | | } |
| | | |
| | |
| | | |
| | | - (BOOL)sd_isVector { |
| | | NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); |
| | | // This may returns a NSProxy, so don't use `class` to check |
| | | NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; |
| | | if ([imageRep isKindOfClass:[NSPDFImageRep class]]) { |
| | | return YES; |
| | |
| | | if ([imageRep isKindOfClass:[NSEPSImageRep class]]) { |
| | | return YES; |
| | | } |
| | | if ([NSStringFromClass(imageRep.class) hasSuffix:@"NSSVGImageRep"]) { |
| | | Class NSSVGImageRepClass = NSClassFromString([NSString stringWithFormat:@"_%@", SD_NSSTRING(NSSVGImageRep)]); |
| | | if ([imageRep isKindOfClass:NSSVGImageRepClass]) { |
| | | return YES; |
| | | } |
| | | return NO; |
| | |
| | | [](https://github.com/Carthage/Carthage) |
| | | |
| | | |
| | | A clone of UIImagePickerController, support picking multiple photos、original photo、video, also allow preview photo and video, support iOS6+. |
| | | 一个支持多选、选原图和视频的图片选择器,同时有预览功能,支持iOS6+。 |
| | | A clone of UIImagePickerController, support picking multiple photos、original photo、video, also allow preview photo and video, support iOS10+. |
| | | 一个支持多选、选原图和视频的图片选择器,同时有预览功能,支持iOS10+。 |
| | | |
| | | ## 重要提示1:提issue前,请先对照Demo、常见问题自查!Demo正常说明你可以升级下新版试试。 |
| | | |
| | | ## 重要提示2:3.7.5版本修复了iOS15.2下初次授权相册权限时的长时间卡顿&白屏问题,强烈建议尽快更新 |
| | | ## 重要提示2:3.8.7版本修复了iOS18下无照片的问题 |
| | | 关于iOS14模拟器的问题 |
| | | PHAuthorizationStatusLimited授权模式下,iOS14模拟器有bug,未授权照片无法显示,真机正常,暂可忽略:https://github.com/banchichen/TZImagePickerController/issues/1347 |
| | | |
| | |
| | | [self presentViewController:imagePickerVc animated:YES completion:nil]; |
| | | |
| | | ## 三. Requirements 要求 |
| | | iOS 6 or later. Requires ARC |
| | | iOS6及以上系统可使用. ARC环境. |
| | | |
| | | When system version is iOS6 or iOS7, Using AssetsLibrary. |
| | | When system version is iOS8 or later, Using PhotoKit. |
| | | 如果运行在iOS6或7系统上,用的是AssetsLibrary库获取照片资源。 |
| | | 如果运行在iOS8及以上系统上,用的是PhotoKit库获取照片资源。 |
| | | |
| | | iOS 10 or later. |
| | | 支持iOS10及以上系统。 |
| | | |
| | | TZImagePickerController uses Camera、Location、Microphone、Photo Library,you need add these properties to info.plist like Demo: |
| | | TZImagePickerController使用了相机、定位、麦克风、相册,请参考Demo添加下列属性到info.plist文件: |
| | | `Privacy - Camera Usage Description` |
| | |
| | | |
| | | ## 六. Release Notes 最近更新 |
| | | |
| | | **3.8.7 支持iOS18** [#1686](https://github.com/banchichen/TZImagePickerController/issues/1686) |
| | | **3.8.5 新增隐私清单文件** [#1675](https://github.com/banchichen/TZImagePickerController/pull/1675) |
| | | **3.8.4 支持使用不带定位代码的版本** [#1606](https://github.com/banchichen/TZImagePickerController/pull/1606) |
| | | **3.8.1 iOS14下可添加访问更多照片,详见PR内的评论** [#1526](https://github.com/banchichen/TZImagePickerController/pull/1526) |
| | | **3.7.6 修复iOS15.2下初次授权相册权限时的长时间卡顿&白屏问题** [#1547](https://github.com/banchichen/TZImagePickerController/issues/1547) |
| | | 3.8.1 iOS14下可添加访问更多照片,详见PR内的评论 [#1526](https://github.com/banchichen/TZImagePickerController/pull/1526) |
| | | 3.7.6 修复iOS15.2下初次授权相册权限时的长时间卡顿&白屏问题 [#1547](https://github.com/banchichen/TZImagePickerController/issues/1547) |
| | | **3.6.7 修复Xcode13&iOS15下导航栏颜色异常问题** |
| | | 3.6.2 新增allowEditVideo,单选视频时支持裁剪 |
| | | 3.6.0 修复iOS14下iCloud视频导出失败问题 |
| | |
| | | ... |
| | | 1.4.5 性能大幅提升(性能测试截图请去博客查看);可在照片列表页拍照;Demo大幅优化; |
| | | ... |
| | | |
| | | ## 七. Common links 常用链接 |
| | | 1. Json diff online: https://www.jsondiffonline.com/ |
| | | |
| | |
| | | if (!self.sortAscendingByModificationDate) { |
| | | option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:self.sortAscendingByModificationDate]]; |
| | | } |
| | | PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; |
| | | PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; |
| | | for (PHAssetCollection *collection in smartAlbums) { |
| | | // 有可能是PHCollectionList类的的对象,过滤掉 |
| | | if (![collection isKindOfClass:[PHAssetCollection class]]) continue; |
| | |
| | | } |
| | | // 我的照片流 1.6.10重新加入.. |
| | | PHFetchResult *myPhotoStreamAlbum = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:nil]; |
| | | PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; |
| | | PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; |
| | | PHFetchResult *topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil]; |
| | | PHFetchResult *syncedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumSyncedAlbum options:nil]; |
| | | PHFetchResult *sharedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumCloudShared options:nil]; |
| | |
| | | // |
| | | // Created by 谭真 on 15/12/24. |
| | | // Copyright © 2015年 谭真. All rights reserved. |
| | | // version 3.8.5 - 2024.04.14 |
| | | // version 3.8.7 - 2024.08.14 |
| | | // 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController |
| | | |
| | | /* |
| | |
| | | // |
| | | // Created by 谭真 on 15/12/24. |
| | | // Copyright © 2015年 谭真. All rights reserved. |
| | | // version 3.8.5 - 2024.04.14 |
| | | // version 3.8.7 - 2024.08.14 |
| | | // 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController |
| | | |
| | | #import "TZImagePickerController.h" |
| | |
| | | self.allowTakeVideo = YES; |
| | | self.videoMaximumDuration = 10 * 60; |
| | | self.sortAscendingByModificationDate = YES; |
| | | self.autoDismiss = YES; |
| | | self.columnNumber = columnNumber; |
| | | [self configDefaultSetting]; |
| | | |
| | |
| | | } |
| | | |
| | | - (void)configDefaultSetting { |
| | | self.autoDismiss = YES; |
| | | self.autoSelectCurrentWhenDone = YES; |
| | | self.timeout = 30; |
| | | self.photoWidth = 828.0; |
| | |
| | | - (void)removeSelectedModel:(TZAssetModel *)model { |
| | | [_selectedModels removeObject:model]; |
| | | [_selectedAssetIds removeObject:model.asset.localIdentifier]; |
| | | } |
| | | |
| | | - (void)setSelectedModels:(NSMutableArray<TZAssetModel *> *)selectedModels { |
| | | _selectedModels = selectedModels; |
| | | NSMutableArray *selectedAssetIds = [NSMutableArray array]; |
| | | for (TZAssetModel *model in selectedModels) { |
| | | [selectedAssetIds addObject:model.asset.localIdentifier]; |
| | | } |
| | | _selectedAssetIds = selectedAssetIds; |
| | | } |
| | | |
| | | - (UIImage *)createImageWithColor:(UIColor *)color size:(CGSize)size radius:(CGFloat)radius { |
| | |
| | | [self configCollectionView]; |
| | | self->_collectionView.hidden = YES; |
| | | [self configBottomToolBar]; |
| | | [self refreshBottomToolBarStatus]; |
| | | [self prepareScrollCollectionViewToBottom]; |
| | | }); |
| | | } |
| | |
| | | [selectedAssets addObject:model.asset]; |
| | | } |
| | | // 拿到了最新的models,在此刷新照片选中状态 |
| | | // 由于可能有照片权限变化,也需要刷新selectedModels https://github.com/banchichen/TZImagePickerController/pull/1658 |
| | | NSMutableArray *newSelectedModels = [NSMutableArray array]; |
| | | for (TZAssetModel *model in _models) { |
| | | model.isSelected = NO; |
| | | if ([selectedAssets containsObject:model.asset]) { |
| | | model.isSelected = YES; |
| | | [newSelectedModels addObject:model]; |
| | | } |
| | | } |
| | | tzImagePickerVc.selectedModels = newSelectedModels; |
| | | } |
| | | |
| | | /// 选中/取消选中某张照片 |
| | |
| | | PHFetchResultChangeDetails *changeDetail = [changeInstance changeDetailsForFetchResult:self.model.result]; |
| | | if (changeDetail == nil) return; |
| | | if ([[TZImageManager manager] isPHAuthorizationStatusLimited]) { |
| | | self.model.result = changeDetail.fetchResultAfterChanges; |
| | | self.model.count = changeDetail.fetchResultAfterChanges.count; |
| | | [self fetchAssetModels]; |
| | | } else if (changeDetail.hasIncrementalChanges == NO) { |
| | | NSArray *changedObjects = [changeDetail changedObjects]; |
| | | changeDetail = [PHFetchResultChangeDetails changeDetailsFromFetchResult:self.model.result toFetchResult:changeDetail.fetchResultAfterChanges changedObjects:changedObjects]; |
| | | if (changeDetail && changeDetail.removedObjects.count) { |
| | | [self handleRemovedAssets:changeDetail.removedObjects]; |
| | | } |
| | | } |
| | | |
| | | if (changeDetail.hasIncrementalChanges == NO) { |
| | | [self.model refreshFetchResult]; |
| | | [self fetchAssetModels]; |
| | | } else { |
| | |
| | | }); |
| | | } |
| | | |
| | | - (void)handleRemovedAssets:(NSArray<PHAsset *> *)removedObjects { |
| | | TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController; |
| | | for (PHAsset *asset in removedObjects) { |
| | | Boolean isSelected = [tzImagePickerVc.selectedAssetIds containsObject:asset.localIdentifier]; |
| | | if (!isSelected) continue; |
| | | NSArray *selectedModels = [NSArray arrayWithArray:tzImagePickerVc.selectedModels]; |
| | | for (TZAssetModel *model_item in selectedModels) { |
| | | if ([asset.localIdentifier isEqualToString:model_item.asset.localIdentifier]) { |
| | | [tzImagePickerVc removeSelectedModel:model_item]; |
| | | } |
| | | } |
| | | [self refreshBottomToolBarStatus]; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - Asset Caching |
| | | |
| | | - (void)resetCachedAssets { |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>FMWK</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>2.10.21</string> |
| | | <string>2.10.22</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>BNDL</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>2.10.21</string> |
| | | <string>2.10.22</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>FMWK</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>1.8.2</string> |
| | | <string>1.8.3</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>BNDL</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>1.8.2</string> |
| | | <string>1.8.3</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>FMWK</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>7.0.3</string> |
| | | <string>7.1.1</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>BNDL</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>7.0.3</string> |
| | | <string>7.1.1</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | THE SOFTWARE. |
| | | |
| | | |
| | | ## SwiftAudioPlayer |
| | | |
| | | Copyright (c) 2019 Tanha Kabir <tanhakabir.ca@gmail.com>, Jon Mercer <mercer.jon@gmail.com> |
| | | |
| | | Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | of this software and associated documentation files (the "Software"), to deal |
| | | in the Software without restriction, including without limitation the rights |
| | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | copies of the Software, and to permit persons to whom the Software is |
| | | furnished to do so, subject to the following conditions: |
| | | |
| | | The above copyright notice and this permission notice shall be included in |
| | | all copies or substantial portions of the Software. |
| | | |
| | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | THE SOFTWARE. |
| | | |
| | | |
| | | ## SwifterSwift |
| | | |
| | | MIT License |
| | |
| | | </dict> |
| | | <dict> |
| | | <key>FooterText</key> |
| | | <string>Copyright (c) 2019 Tanha Kabir <tanhakabir.ca@gmail.com>, Jon Mercer <mercer.jon@gmail.com> |
| | | |
| | | Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | of this software and associated documentation files (the "Software"), to deal |
| | | in the Software without restriction, including without limitation the rights |
| | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | copies of the Software, and to permit persons to whom the Software is |
| | | furnished to do so, subject to the following conditions: |
| | | |
| | | The above copyright notice and this permission notice shall be included in |
| | | all copies or substantial portions of the Software. |
| | | |
| | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| | | THE SOFTWARE. |
| | | </string> |
| | | <key>License</key> |
| | | <string>MIT</string> |
| | | <key>Title</key> |
| | | <string>SwiftAudioPlayer</string> |
| | | <key>Type</key> |
| | | <string>PSGroupSpecifier</string> |
| | | </dict> |
| | | <dict> |
| | | <key>FooterText</key> |
| | | <string>MIT License |
| | | |
| | | Copyright (c) 2015-2018 SwifterSwift (https://github.com/swifterswift) |
| | |
| | | ${BUILT_PRODUCTS_DIR}/SPPageMenu/SPPageMenu.framework |
| | | ${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework |
| | | ${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework |
| | | ${BUILT_PRODUCTS_DIR}/SwiftAudioPlayer/SwiftAudioPlayer.framework |
| | | ${BUILT_PRODUCTS_DIR}/SwifterSwift/SwifterSwift.framework |
| | | ${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework |
| | | ${BUILT_PRODUCTS_DIR}/UserDefaultsStore/UserDefaultsStore.framework |
| | |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SPPageMenu.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftAudioPlayer.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwifterSwift.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UserDefaultsStore.framework |
| | |
| | | ${BUILT_PRODUCTS_DIR}/SPPageMenu/SPPageMenu.framework |
| | | ${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework |
| | | ${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework |
| | | ${BUILT_PRODUCTS_DIR}/SwiftAudioPlayer/SwiftAudioPlayer.framework |
| | | ${BUILT_PRODUCTS_DIR}/SwifterSwift/SwifterSwift.framework |
| | | ${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework |
| | | ${BUILT_PRODUCTS_DIR}/UserDefaultsStore/UserDefaultsStore.framework |
| | |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SPPageMenu.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftAudioPlayer.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwifterSwift.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework |
| | | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UserDefaultsStore.framework |
| | |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SPPageMenu/SPPageMenu.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SwiftAudioPlayer/SwiftAudioPlayer.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SwifterSwift/SwifterSwift.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/UserDefaultsStore/UserDefaultsStore.framework" |
| | |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SPPageMenu/SPPageMenu.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SwiftAudioPlayer/SwiftAudioPlayer.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/SwifterSwift/SwifterSwift.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework" |
| | | install_framework "${BUILT_PRODUCTS_DIR}/UserDefaultsStore/UserDefaultsStore.framework" |
| | |
| | | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES |
| | | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO |
| | | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger" "${PODS_ROOT}/WechatOpenSDK-XCFramework" |
| | | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftAudioPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger" "${PODS_ROOT}/WechatOpenSDK-XCFramework" |
| | | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| | | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator/Differentiator.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift/EmptyDataSet_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage/FFPage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON/HandyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools/JQTools.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern/Lantern.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging/ObjcExceptionBridging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit/QMUIKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa/RxCocoa.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources/RxDataSources.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay/RxRelay.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift/RxSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu/SPPageMenu.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift/SwifterSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore/UserDefaultsStore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic/VTMagic.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger/XCGLogger.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" |
| | | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator/Differentiator.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift/EmptyDataSet_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage/FFPage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON/HandyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools/JQTools.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern/Lantern.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging/ObjcExceptionBridging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit/QMUIKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa/RxCocoa.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources/RxDataSources.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay/RxRelay.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift/RxSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu/SPPageMenu.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftAudioPlayer/SwiftAudioPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift/SwifterSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore/UserDefaultsStore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic/VTMagic.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger/XCGLogger.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" |
| | | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' |
| | | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift |
| | | OTHER_LDFLAGS = $(inherited) -l"WechatOpenSDK" -l"c++" -l"resolv" -l"sqlite3.0" -l"swiftCoreGraphics" -l"z" -framework "AVFoundation" -framework "Alamofire" -framework "AliyunOSSiOS" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreServices" -framework "CoreTelephony" -framework "CryptoSwift" -framework "Differentiator" -framework "EmptyDataSet_Swift" -framework "FFPage" -framework "Foundation" -framework "HandyJSON" -framework "IQKeyboardManager" -framework "IQKeyboardManagerSwift" -framework "ImageIO" -framework "JQTools" -framework "Lantern" -framework "MJRefresh" -framework "ObjcExceptionBridging" -framework "ObjectMapper" -framework "Photos" -framework "PhotosUI" -framework "QMUIKit" -framework "QuartzCore" -framework "RxCocoa" -framework "RxDataSources" -framework "RxRelay" -framework "RxSwift" -framework "SDWebImage" -framework "SPPageMenu" -framework "SVProgressHUD" -framework "Security" -framework "SnapKit" -framework "SwifterSwift" -framework "SystemConfiguration" -framework "TZImagePickerController" -framework "UIKit" -framework "UserDefaultsStore" -framework "VTMagic" -framework "WebKit" -framework "XCGLogger" |
| | | OTHER_LDFLAGS = $(inherited) -l"WechatOpenSDK" -l"c++" -l"resolv" -l"sqlite3.0" -l"swiftCoreGraphics" -l"z" -framework "AVFoundation" -framework "Alamofire" -framework "AliyunOSSiOS" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreServices" -framework "CoreTelephony" -framework "CryptoSwift" -framework "Differentiator" -framework "EmptyDataSet_Swift" -framework "FFPage" -framework "Foundation" -framework "HandyJSON" -framework "IQKeyboardManager" -framework "IQKeyboardManagerSwift" -framework "ImageIO" -framework "JQTools" -framework "Lantern" -framework "MJRefresh" -framework "ObjcExceptionBridging" -framework "ObjectMapper" -framework "Photos" -framework "PhotosUI" -framework "QMUIKit" -framework "QuartzCore" -framework "RxCocoa" -framework "RxDataSources" -framework "RxRelay" -framework "RxSwift" -framework "SDWebImage" -framework "SPPageMenu" -framework "SVProgressHUD" -framework "Security" -framework "SnapKit" -framework "SwiftAudioPlayer" -framework "SwifterSwift" -framework "SystemConfiguration" -framework "TZImagePickerController" -framework "UIKit" -framework "UserDefaultsStore" -framework "VTMagic" -framework "WebKit" -framework "XCGLogger" |
| | | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS |
| | | PODS_BUILD_DIR = ${BUILD_DIR} |
| | | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| | |
| | | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES |
| | | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO |
| | | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger" "${PODS_ROOT}/WechatOpenSDK-XCFramework" |
| | | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftAudioPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger" "${PODS_ROOT}/WechatOpenSDK-XCFramework" |
| | | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 |
| | | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator/Differentiator.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift/EmptyDataSet_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage/FFPage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON/HandyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools/JQTools.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern/Lantern.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging/ObjcExceptionBridging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit/QMUIKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa/RxCocoa.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources/RxDataSources.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay/RxRelay.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift/RxSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu/SPPageMenu.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift/SwifterSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore/UserDefaultsStore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic/VTMagic.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger/XCGLogger.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" |
| | | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Differentiator/Differentiator.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/EmptyDataSet-Swift/EmptyDataSet_Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FFPage/FFPage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/HandyJSON/HandyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JQTools/JQTools.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Lantern/Lantern.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjcExceptionBridging/ObjcExceptionBridging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QMUIKit/QMUIKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa/RxCocoa.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxDataSources/RxDataSources.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay/RxRelay.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift/RxSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPPageMenu/SPPageMenu.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftAudioPlayer/SwiftAudioPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwifterSwift/SwifterSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/UserDefaultsStore/UserDefaultsStore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VTMagic/VTMagic.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XCGLogger/XCGLogger.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" |
| | | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' |
| | | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift |
| | | OTHER_LDFLAGS = $(inherited) -l"WechatOpenSDK" -l"c++" -l"resolv" -l"sqlite3.0" -l"swiftCoreGraphics" -l"z" -framework "AVFoundation" -framework "Alamofire" -framework "AliyunOSSiOS" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreServices" -framework "CoreTelephony" -framework "CryptoSwift" -framework "Differentiator" -framework "EmptyDataSet_Swift" -framework "FFPage" -framework "Foundation" -framework "HandyJSON" -framework "IQKeyboardManager" -framework "IQKeyboardManagerSwift" -framework "ImageIO" -framework "JQTools" -framework "Lantern" -framework "MJRefresh" -framework "ObjcExceptionBridging" -framework "ObjectMapper" -framework "Photos" -framework "PhotosUI" -framework "QMUIKit" -framework "QuartzCore" -framework "RxCocoa" -framework "RxDataSources" -framework "RxRelay" -framework "RxSwift" -framework "SDWebImage" -framework "SPPageMenu" -framework "SVProgressHUD" -framework "Security" -framework "SnapKit" -framework "SwifterSwift" -framework "SystemConfiguration" -framework "TZImagePickerController" -framework "UIKit" -framework "UserDefaultsStore" -framework "VTMagic" -framework "WebKit" -framework "XCGLogger" |
| | | OTHER_LDFLAGS = $(inherited) -l"WechatOpenSDK" -l"c++" -l"resolv" -l"sqlite3.0" -l"swiftCoreGraphics" -l"z" -framework "AVFoundation" -framework "Alamofire" -framework "AliyunOSSiOS" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreServices" -framework "CoreTelephony" -framework "CryptoSwift" -framework "Differentiator" -framework "EmptyDataSet_Swift" -framework "FFPage" -framework "Foundation" -framework "HandyJSON" -framework "IQKeyboardManager" -framework "IQKeyboardManagerSwift" -framework "ImageIO" -framework "JQTools" -framework "Lantern" -framework "MJRefresh" -framework "ObjcExceptionBridging" -framework "ObjectMapper" -framework "Photos" -framework "PhotosUI" -framework "QMUIKit" -framework "QuartzCore" -framework "RxCocoa" -framework "RxDataSources" -framework "RxRelay" -framework "RxSwift" -framework "SDWebImage" -framework "SPPageMenu" -framework "SVProgressHUD" -framework "Security" -framework "SnapKit" -framework "SwiftAudioPlayer" -framework "SwifterSwift" -framework "SystemConfiguration" -framework "TZImagePickerController" -framework "UIKit" -framework "UserDefaultsStore" -framework "VTMagic" -framework "WebKit" -framework "XCGLogger" |
| | | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS |
| | | PODS_BUILD_DIR = ${BUILD_DIR} |
| | | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>BNDL</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>5.19.2</string> |
| | | <string>5.19.6</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>FMWK</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>5.19.2</string> |
| | | <string>5.19.6</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | <key>CFBundlePackageType</key> |
| | | <string>FMWK</string> |
| | | <key>CFBundleShortVersionString</key> |
| | | <string>3.8.5</string> |
| | | <string>3.8.7</string> |
| | | <key>CFBundleSignature</key> |
| | | <string>????</string> |
| | | <key>CFBundleVersion</key> |
| | |
| | | 13649F9E2C770C9C00F4E0EE /* ContactCustomerDetailVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13649F9D2C770C9C00F4E0EE /* ContactCustomerDetailVC.xib */; }; |
| | | 13649F9F2C770C9C00F4E0EE /* ContactCustomerDetailVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13649F9C2C770C9C00F4E0EE /* ContactCustomerDetailVC.swift */; }; |
| | | 136C7C7D2C7715C9004540CD /* BitrhdayPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136C7C7C2C7715C9004540CD /* BitrhdayPickerView.swift */; }; |
| | | 136C7C812C771CF3004540CD /* PayMusicVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136C7C7F2C771CF3004540CD /* PayMusicVC.swift */; }; |
| | | 137175C62C6C3C4700B38EF1 /* SourceHanSansCN-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 137175C52C6C3C4700B38EF1 /* SourceHanSansCN-Regular.otf */; }; |
| | | 137175C82C6C3C6D00B38EF1 /* Agenda-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 137175C72C6C3C6D00B38EF1 /* Agenda-Light.otf */; }; |
| | | 137175CB2C6C412A00B38EF1 /* BackgroundVoiceVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137175C92C6C412A00B38EF1 /* BackgroundVoiceVC.swift */; }; |
| | |
| | | 137ABE382C6B6641003A91C5 /* WebVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137ABE372C6B6641003A91C5 /* WebVC.swift */; }; |
| | | 137ABE3B2C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137ABE392C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.swift */; }; |
| | | 137ABE3C2C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 137ABE3A2C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.xib */; }; |
| | | 137ECACF2C78268B00C338BE /* LoginTreatyVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137ECACD2C78268B00C338BE /* LoginTreatyVC.swift */; }; |
| | | 137ECAD02C78268B00C338BE /* LoginTreatyVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 137ECACE2C78268B00C338BE /* LoginTreatyVC.xib */; }; |
| | | 1385DFFA2C6C4EBC00AADB1F /* RefreshModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1385DFF92C6C4EBC00AADB1F /* RefreshModel.swift */; }; |
| | | 1385E0002C6C4F1200AADB1F /* NetworkRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1385DFFB2C6C4F1200AADB1F /* NetworkRequest.swift */; }; |
| | | 1385E0022C6C4F1200AADB1F /* Services.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1385DFFD2C6C4F1200AADB1F /* Services.swift */; }; |
| | |
| | | 13649F9C2C770C9C00F4E0EE /* ContactCustomerDetailVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactCustomerDetailVC.swift; sourceTree = "<group>"; }; |
| | | 13649F9D2C770C9C00F4E0EE /* ContactCustomerDetailVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ContactCustomerDetailVC.xib; sourceTree = "<group>"; }; |
| | | 136C7C7C2C7715C9004540CD /* BitrhdayPickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BitrhdayPickerView.swift; sourceTree = "<group>"; }; |
| | | 136C7C7F2C771CF3004540CD /* PayMusicVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayMusicVC.swift; sourceTree = "<group>"; }; |
| | | 137175C52C6C3C4700B38EF1 /* SourceHanSansCN-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SourceHanSansCN-Regular.otf"; sourceTree = "<group>"; }; |
| | | 137175C72C6C3C6D00B38EF1 /* Agenda-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Agenda-Light.otf"; sourceTree = "<group>"; }; |
| | | 137175C92C6C412A00B38EF1 /* BackgroundVoiceVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundVoiceVC.swift; sourceTree = "<group>"; }; |
| | |
| | | 137ABE372C6B6641003A91C5 /* WebVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebVC.swift; sourceTree = "<group>"; }; |
| | | 137ABE392C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotPasswordInputCodeVC.swift; sourceTree = "<group>"; }; |
| | | 137ABE3A2C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ForgotPasswordInputCodeVC.xib; sourceTree = "<group>"; }; |
| | | 137ECACD2C78268B00C338BE /* LoginTreatyVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginTreatyVC.swift; sourceTree = "<group>"; }; |
| | | 137ECACE2C78268B00C338BE /* LoginTreatyVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LoginTreatyVC.xib; sourceTree = "<group>"; }; |
| | | 1385DFF92C6C4EBC00AADB1F /* RefreshModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshModel.swift; sourceTree = "<group>"; }; |
| | | 1385DFFB2C6C4F1200AADB1F /* NetworkRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkRequest.swift; sourceTree = "<group>"; }; |
| | | 1385DFFD2C6C4F1200AADB1F /* Services.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Services.swift; sourceTree = "<group>"; }; |
| | |
| | | 131E75C32C6B87C400E2C85D /* ForgotPasswordChangeVC.xib */, |
| | | 139466452C6B8E0200F6FB15 /* UpdatePhoneVC.swift */, |
| | | 139466462C6B8E0200F6FB15 /* UpdatePhoneVC.xib */, |
| | | 137ECACD2C78268B00C338BE /* LoginTreatyVC.swift */, |
| | | 137ECACE2C78268B00C338BE /* LoginTreatyVC.xib */, |
| | | ); |
| | | path = VC; |
| | | sourceTree = "<group>"; |
| | |
| | | 13391E012C73334000B9513F /* PavilionDetailVC.xib */, |
| | | ); |
| | | path = VC; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 136C7C7E2C771CCB004540CD /* PayMusicView */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 136C7C7F2C771CF3004540CD /* PayMusicVC.swift */, |
| | | ); |
| | | path = PayMusicView; |
| | | sourceTree = "<group>"; |
| | | }; |
| | | 137175C42C6C3C2100B38EF1 /* Fonts */ = { |
| | |
| | | 13985DC92C69E9B60046B6DC /* Root */ = { |
| | | isa = PBXGroup; |
| | | children = ( |
| | | 136C7C7E2C771CCB004540CD /* PayMusicView */, |
| | | 1385DFFF2C6C4F1200AADB1F /* Network */, |
| | | 1385DFF82C6C4EB500AADB1F /* ViewModel */, |
| | | 137ABE362C6B6636003A91C5 /* Other */, |
| | |
| | | 130C07122C76DA0500ADB098 /* SpendingDetailContentTCell.xib in Resources */, |
| | | 13E160202C6CB8930027F781 /* CommentListVC.xib in Resources */, |
| | | 139228B12C6B8374006F3CB6 /* Popup_1_View.xib in Resources */, |
| | | 137ECAD02C78268B00C338BE /* LoginTreatyVC.xib in Resources */, |
| | | ); |
| | | runOnlyForDeploymentPostprocessing = 0; |
| | | }; |
| | |
| | | 130AA4A92C72F71700F20944 /* CourseDetialVideoVC.swift in Sources */, |
| | | 1336EFA52C6DEB550075E070 /* HoverHeaderFlowLayout.swift in Sources */, |
| | | 13985DB52C69B7DF0046B6DC /* Def.swift in Sources */, |
| | | 136C7C812C771CF3004540CD /* PayMusicVC.swift in Sources */, |
| | | 139228AF2C6B836B006F3CB6 /* Popup_1_View.swift in Sources */, |
| | | 1336EFA72C6DEC640075E070 /* PaymentOrderResultTopView.swift in Sources */, |
| | | 13CBCCE32C747C3D00C67701 /* NoticeCenterUserRepeaceDetailVC.swift in Sources */, |
| | |
| | | 13271D862C75EF8200DE1328 /* AddBankInfoVC.swift in Sources */, |
| | | 137ABE3B2C6B6BDD003A91C5 /* ForgotPasswordInputCodeVC.swift in Sources */, |
| | | 130B765D2C6C4C33006371AF /* HomeItemListVC.swift in Sources */, |
| | | 137ECACF2C78268B00C338BE /* LoginTreatyVC.swift in Sources */, |
| | | 1385E0002C6C4F1200AADB1F /* NetworkRequest.swift in Sources */, |
| | | 136C7C7D2C7715C9004540CD /* BitrhdayPickerView.swift in Sources */, |
| | | 13334FDB2C7321BE00914086 /* PavilionItemCell.swift in Sources */, |
New file |
| | |
| | | { |
| | | "images" : [ |
| | | { |
| | | "idiom" : "universal", |
| | | "scale" : "1x" |
| | | }, |
| | | { |
| | | "filename" : "icon_pay_purse@2x.png", |
| | | "idiom" : "universal", |
| | | "scale" : "2x" |
| | | }, |
| | | { |
| | | "filename" : "icon_pay_purse@3x.png", |
| | | "idiom" : "universal", |
| | | "scale" : "3x" |
| | | } |
| | | ], |
| | | "info" : { |
| | | "author" : "xcode", |
| | | "version" : 1 |
| | | } |
| | | } |
| | |
| | | |
| | | open func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { |
| | | |
| | | var musicVC:PayMusicVC? |
| | | |
| | | for vc in navigationController.tabBarController?.children ?? []{ |
| | | if vc is PayMusicVC{ |
| | | musicVC = (vc as! PayMusicVC);break |
| | | } |
| | | } |
| | | |
| | | musicVC?.view.isHidden = navigationController.viewControllers.count != 1 |
| | | |
| | | let status = lucencyVCs.contains(where: {$0 == viewController.classForCoder}) |
| | | if (navigationController.viewControllers.count == 1 || status){ |
| | | if #available(iOS 15.0, *) { |
| | |
| | | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| | | <plist version="1.0"> |
| | | <dict> |
| | | <key>NSAppTransportSecurity</key> |
| | | <dict> |
| | | <key>NSAllowsArbitraryLoads</key> |
| | | <true/> |
| | | <key>NSAllowsArbitraryLoadsInWebContent</key> |
| | | <true/> |
| | | </dict> |
| | | <key>UIAppFonts</key> |
| | | <array> |
| | | <string>SourceHanSansCN-Regular.otf</string> |
| | |
| | | </array> |
| | | </dict> |
| | | </dict> |
| | | <key>UIBackgroundModes</key> |
| | | <array> |
| | | <string>audio</string> |
| | | </array> |
| | | </dict> |
| | | </plist> |
| | |
| | | |
| | | import UIKit |
| | | import JQTools |
| | | import MediaPlayer |
| | | |
| | | struct TitleItem{ |
| | | var title = "" |
| | |
| | | titleItems.append(TitleItem(title: "放松助眠", subTitle: "与内心的宁静与喜悦入睡",hasMore:true)) |
| | | titleItems.append(TitleItem(title: "放松助眠", subTitle: "与内心的宁静与喜悦入睡",hasMore:true)) |
| | | titleItems.append(TitleItem(title: "放松助眠", subTitle: "与内心的宁静与喜悦入睡",hasMore:true)) |
| | | |
| | | let vc = LoginTreatyVC() |
| | | vc.modalPresentationStyle = .custom |
| | | present(vc, animated: true) |
| | | } |
| | | |
| | | override func setUI() { |
| | |
| | | navigationItem.rightBarButtonItem = UIBarButtonItem(customView: voices) |
| | | |
| | | tableView = UITableView(frame: .zero, style: .plain) |
| | | tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 40, right: 0) |
| | | tableView.showsVerticalScrollIndicator = false |
| | | DispatchQueue.main.async { |
| | | let height = self.topMenuView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height |
| | |
| | | |
| | | |
| | | } |
| | | |
| | | extension HomeVC:UIScrollViewDelegate{ |
| | | func scrollViewDidScroll(_ scrollView: UIScrollView) { |
| | | let v = min(scrollView.contentOffset.y / JQ_NavBarHeight, 1) |
| | | navigationController?.navigationBar.standardAppearance.backgroundColor = .white.withAlphaComponent(v) |
| | | } |
| | | } |
New file |
| | |
| | | // |
| | | // LoginTreatyVC.swift |
| | | // XQMuse |
| | | // |
| | | // Created by 无故事王国 on 2024/8/23. |
| | | // |
| | | |
| | | import UIKit |
| | | import SPPageMenu |
| | | import FFPage |
| | | |
| | | class LoginTreatyVC: BaseVC { |
| | | @IBOutlet weak var view_menu: UIView! |
| | | @IBOutlet weak var view_content: UIView! |
| | | |
| | | private(set) var pageMenu:SPPageMenu = { |
| | | let pageMenu = SPPageMenu(frame: .zero, trackerStyle: .line) |
| | | // 追踪线 |
| | | pageMenu.trackerWidth = 12 |
| | | pageMenu.setTrackerHeight(2, cornerRadius:1) |
| | | pageMenu.trackerFollowingMode = .always |
| | | pageMenu.contentInset = UIEdgeInsets(top: 0, left: 19.5, bottom: 5, right: 19.5) |
| | | pageMenu.setItems(["用户协议","隐私协议"], selectedItemIndex: 0) |
| | | pageMenu.backgroundColor = UIColor(hexString: "#F0F0F0") |
| | | pageMenu.tracker.backgroundColor = UIColor(hexString: "#8AAE65") |
| | | pageMenu.backgroundColor = .white |
| | | |
| | | // 分割线 |
| | | pageMenu.dividingLine.backgroundColor = UIColor(hexString: "#D4D4D4") |
| | | pageMenu.dividingLineHeight = 0.4 |
| | | |
| | | // item |
| | | pageMenu.spacing = 27.0 |
| | | pageMenu.permutationWay = .notScrollAdaptContent |
| | | |
| | | // 字体 |
| | | pageMenu.selectedItemTitleFont = Def_SourceHanSansCN_Regular(fontSize: 14) |
| | | pageMenu.unSelectedItemTitleFont = Def_SourceHanSansCN_Regular(fontSize: 14) |
| | | // 颜色 |
| | | pageMenu.selectedItemTitleColor = UIColor(hexStr: "#8AAE65") |
| | | pageMenu.unSelectedItemTitleColor = .black.withAlphaComponent(0.6) |
| | | return pageMenu |
| | | }() |
| | | |
| | | lazy var pageViewController:FFPageViewController = { |
| | | let pageVC = FFPageViewController() |
| | | pageVC.view.backgroundColor = .clear |
| | | pageVC.scrollview.backgroundColor = .clear |
| | | |
| | | pageVC.scrollview.bounces = false |
| | | return pageVC |
| | | }() |
| | | override func viewWillAppear(_ animated: Bool) { |
| | | super.viewWillAppear(animated) |
| | | UIView.animate(withDuration: 0.5) { |
| | | self.view.backgroundColor = UIColor.black.withAlphaComponent(0.7) |
| | | } |
| | | } |
| | | |
| | | override func viewDidAppear(_ animated: Bool) { |
| | | super.viewDidAppear(animated) |
| | | |
| | | } |
| | | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | | view.backgroundColor = UIColor.black.withAlphaComponent(0) |
| | | } |
| | | |
| | | override func setUI() { |
| | | view_menu.addSubview(pageMenu) |
| | | pageMenu.snp.makeConstraints { make in |
| | | make.edges.equalToSuperview() |
| | | } |
| | | |
| | | view_content.addSubview(pageViewController.view) |
| | | pageViewController.view.backgroundColor = .clear |
| | | pageViewController.delegate = self |
| | | pageViewController.view.snp.makeConstraints { make in |
| | | make.top.equalTo(pageMenu.snp.bottom) |
| | | make.left.right.bottom.equalToSuperview() |
| | | } |
| | | } |
| | | |
| | | @IBAction func rejectAction(_ sender: UIButton) { |
| | | dismiss(animated: true) |
| | | } |
| | | |
| | | @IBAction func completeAction(_ sender: UIButton) { |
| | | dismiss(animated: true) |
| | | } |
| | | } |
| | | |
| | | extension LoginTreatyVC:SPPageMenuDelegate{ |
| | | func pageMenu(_ pageMenu: SPPageMenu, itemSelectedAt index: Int) { |
| | | pageViewController.scroll(toPage: index, animation: true) |
| | | } |
| | | } |
| | | |
| | | |
| | | extension LoginTreatyVC:FFPageViewControllerDelegate{ |
| | | |
| | | func pageViewController(_ pageViewController: FFPageViewController, currentPageChanged currentPage: Int) { |
| | | pageMenu.selectedItemIndex = currentPage |
| | | } |
| | | |
| | | func totalPagesOfpageViewController(_ pageViewConteoller: FFPageViewController) -> UInt { |
| | | return 2 |
| | | } |
| | | |
| | | func pageViewController(_ pageViewConteoller: FFPageViewController, controllerForPage page: Int) -> UIViewController { |
| | | return WebVC(url: "https://www.baidu.com") |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> |
| | | <device id="retina6_12" orientation="portrait" appearance="light"/> |
| | | <dependencies> |
| | | <deployment identifier="iOS"/> |
| | | <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> |
| | | <capability name="Safe area layout guides" minToolsVersion="9.0"/> |
| | | <capability name="System colors in document resources" minToolsVersion="11.0"/> |
| | | <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> |
| | | </dependencies> |
| | | <objects> |
| | | <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LoginTreatyVC" customModule="XQMuse" customModuleProvider="target"> |
| | | <connections> |
| | | <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> |
| | | <outlet property="view_content" destination="nCE-Qk-DuB" id="5f4-Tr-Dcq"/> |
| | | <outlet property="view_menu" destination="E3X-XR-FeI" id="erg-RD-Rgt"/> |
| | | </connections> |
| | | </placeholder> |
| | | <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> |
| | | <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> |
| | | <rect key="frame" x="0.0" y="0.0" width="393" height="852"/> |
| | | <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> |
| | | <subviews> |
| | | <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Fel-9y-YFP"> |
| | | <rect key="frame" x="45" y="173" width="303" height="531"/> |
| | | <subviews> |
| | | <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="E3X-XR-FeI"> |
| | | <rect key="frame" x="0.0" y="0.0" width="303" height="51"/> |
| | | <color key="backgroundColor" systemColor="systemBackgroundColor"/> |
| | | <constraints> |
| | | <constraint firstAttribute="height" constant="51" id="nwM-Wk-2BU"/> |
| | | </constraints> |
| | | </view> |
| | | <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="39" translatesAutoresizingMaskIntoConstraints="NO" id="9xc-Mf-Pss"> |
| | | <rect key="frame" x="33" y="475" width="237" height="40"/> |
| | | <subviews> |
| | | <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="csH-Nv-3qW"> |
| | | <rect key="frame" x="0.0" y="0.0" width="99" height="40"/> |
| | | <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> |
| | | <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> |
| | | <state key="normal" title="拒绝"> |
| | | <color key="titleColor" red="0.6470588235294118" green="0.74901960784313726" blue="0.5607843137254902" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="sRGB"/> |
| | | </state> |
| | | <userDefinedRuntimeAttributes> |
| | | <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/> |
| | | <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB"> |
| | | <real key="value" value="20"/> |
| | | </userDefinedRuntimeAttribute> |
| | | <userDefinedRuntimeAttribute type="number" keyPath="ld_borderWidthXIB"> |
| | | <real key="value" value="1"/> |
| | | </userDefinedRuntimeAttribute> |
| | | <userDefinedRuntimeAttribute type="color" keyPath="ld_borderColorXIB"> |
| | | <color key="value" red="0.6470588235294118" green="0.74901960784313726" blue="0.5607843137254902" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="sRGB"/> |
| | | </userDefinedRuntimeAttribute> |
| | | </userDefinedRuntimeAttributes> |
| | | <connections> |
| | | <action selector="rejectAction:" destination="-1" eventType="touchUpInside" id="2fy-cb-Zy4"/> |
| | | </connections> |
| | | </button> |
| | | <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nVf-ur-W7Y"> |
| | | <rect key="frame" x="138" y="0.0" width="99" height="40"/> |
| | | <color key="backgroundColor" red="0.55686274509803924" green="0.64313725490196072" blue="0.47843137254901957" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="sRGB"/> |
| | | <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> |
| | | <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> |
| | | <state key="normal" title="确定"> |
| | | <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| | | </state> |
| | | <userDefinedRuntimeAttributes> |
| | | <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/> |
| | | <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB"> |
| | | <real key="value" value="20"/> |
| | | </userDefinedRuntimeAttribute> |
| | | </userDefinedRuntimeAttributes> |
| | | <connections> |
| | | <action selector="completeAction:" destination="-1" eventType="touchUpInside" id="tH0-VT-PQD"/> |
| | | </connections> |
| | | </button> |
| | | </subviews> |
| | | <constraints> |
| | | <constraint firstAttribute="height" constant="40" id="nUz-d1-TNk"/> |
| | | </constraints> |
| | | </stackView> |
| | | <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nCE-Qk-DuB"> |
| | | <rect key="frame" x="0.0" y="51" width="303" height="424"/> |
| | | <color key="backgroundColor" systemColor="systemBackgroundColor"/> |
| | | </view> |
| | | </subviews> |
| | | <color key="backgroundColor" systemColor="systemBackgroundColor"/> |
| | | <constraints> |
| | | <constraint firstItem="nCE-Qk-DuB" firstAttribute="top" secondItem="E3X-XR-FeI" secondAttribute="bottom" id="2ba-vr-vsi"/> |
| | | <constraint firstAttribute="trailing" secondItem="nCE-Qk-DuB" secondAttribute="trailing" id="71D-Ys-Y8r"/> |
| | | <constraint firstAttribute="trailing" secondItem="9xc-Mf-Pss" secondAttribute="trailing" constant="33" id="QpB-DR-0yX"/> |
| | | <constraint firstAttribute="trailing" secondItem="E3X-XR-FeI" secondAttribute="trailing" id="WRf-9i-In2"/> |
| | | <constraint firstAttribute="width" secondItem="Fel-9y-YFP" secondAttribute="height" multiplier="1:1.753" id="b69-Uf-lBS"/> |
| | | <constraint firstItem="9xc-Mf-Pss" firstAttribute="top" secondItem="nCE-Qk-DuB" secondAttribute="bottom" id="cia-3n-g9p"/> |
| | | <constraint firstAttribute="bottom" secondItem="9xc-Mf-Pss" secondAttribute="bottom" constant="16" id="iol-Lo-Ugj"/> |
| | | <constraint firstItem="9xc-Mf-Pss" firstAttribute="leading" secondItem="Fel-9y-YFP" secondAttribute="leading" constant="33" id="ju1-aK-UR7"/> |
| | | <constraint firstItem="nCE-Qk-DuB" firstAttribute="leading" secondItem="Fel-9y-YFP" secondAttribute="leading" id="n7F-0n-lw3"/> |
| | | <constraint firstItem="E3X-XR-FeI" firstAttribute="leading" secondItem="Fel-9y-YFP" secondAttribute="leading" id="yRs-He-4DO"/> |
| | | <constraint firstItem="E3X-XR-FeI" firstAttribute="top" secondItem="Fel-9y-YFP" secondAttribute="top" id="ztP-s7-Esv"/> |
| | | </constraints> |
| | | <userDefinedRuntimeAttributes> |
| | | <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/> |
| | | <userDefinedRuntimeAttribute type="number" keyPath="ld_cornerRadiusXIB"> |
| | | <real key="value" value="10"/> |
| | | </userDefinedRuntimeAttribute> |
| | | </userDefinedRuntimeAttributes> |
| | | </view> |
| | | </subviews> |
| | | <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> |
| | | <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="sRGB"/> |
| | | <constraints> |
| | | <constraint firstItem="Fel-9y-YFP" firstAttribute="centerY" secondItem="fnl-2z-Ty3" secondAttribute="centerY" id="5OR-YX-sI0"/> |
| | | <constraint firstItem="Fel-9y-YFP" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="45" id="Bnf-LL-BoC"/> |
| | | <constraint firstItem="Fel-9y-YFP" firstAttribute="centerX" secondItem="fnl-2z-Ty3" secondAttribute="centerX" id="a7s-eR-Ewe"/> |
| | | <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Fel-9y-YFP" secondAttribute="trailing" constant="45" id="vZI-wR-eRw"/> |
| | | </constraints> |
| | | <point key="canvasLocation" x="140" y="21"/> |
| | | </view> |
| | | </objects> |
| | | <resources> |
| | | <systemColor name="systemBackgroundColor"> |
| | | <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
| | | </systemColor> |
| | | </resources> |
| | | </document> |
New file |
| | |
| | | // |
| | | // PayMusicVC.swift |
| | | // XQMuse |
| | | // |
| | | // Created by 无故事王国 on 2024/8/22. |
| | | // |
| | | |
| | | import UIKit |
| | | import JQTools |
| | | import AVFoundation |
| | | import MediaPlayer |
| | | |
| | | class PayMusicVC: BaseVC { |
| | | |
| | | private var coverImage:UIImageView! |
| | | private var label_name:UILabel! |
| | | private var btn_handle:UIButton! |
| | | private var audioPlayer:AudioPlayer! |
| | | |
| | | private init() { |
| | | super.init(nibName: nil, bundle: nil) |
| | | } |
| | | |
| | | internal required init?(coder: NSCoder) { |
| | | fatalError("init(coder:) has not been implemented") |
| | | } |
| | | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | | audioPlayer = AudioPlayer.getSharedInstance() |
| | | } |
| | | |
| | | override func setUI() { |
| | | view.backgroundColor = UIColor(hexString: "#B1C998") |
| | | view.jq_cornerRadius = 23.25 |
| | | |
| | | coverImage = UIImageView(image: UIImage(named: "bg_home_1")) |
| | | coverImage.jq_cornerRadius = 18.25 |
| | | coverImage.jq_borderColor = .black |
| | | coverImage.jq_borderWidth = 3.5 |
| | | view.addSubview(coverImage) |
| | | coverImage.snp.makeConstraints { make in |
| | | make.left.equalTo(7.5) |
| | | make.width.height.equalTo(36.5) |
| | | make.centerY.equalToSuperview() |
| | | } |
| | | |
| | | label_name = UILabel() |
| | | label_name.text = "--" |
| | | label_name.font = .systemFont(ofSize: 14.8, weight: .bold) |
| | | label_name.textColor = .white |
| | | view.addSubview(label_name) |
| | | label_name.snp.makeConstraints { make in |
| | | make.left.equalTo(self.coverImage.snp.right).offset(17.5) |
| | | make.centerY.equalToSuperview() |
| | | } |
| | | |
| | | btn_handle = UIButton(type: .custom) |
| | | btn_handle.setImage(UIImage(named: "icon_play_purse"), for: .normal) |
| | | btn_handle.addTarget(self, action: #selector(tapHandleAction), for: .touchUpInside) |
| | | view.addSubview(btn_handle) |
| | | btn_handle.snp.makeConstraints { make in |
| | | make.right.equalToSuperview().offset(-24.5) |
| | | make.centerY.equalToSuperview() |
| | | make.width.height.equalTo(28) |
| | | } |
| | | } |
| | | |
| | | static func show(){ |
| | | let vc = PayMusicVC() |
| | | let tabBarHeight = JQ_currentViewController().navigationController?.tabBarController?.tabBar.height ?? 0 |
| | | JQ_currentViewController().navigationController?.tabBarController?.addChild(vc) |
| | | JQ_currentViewController().navigationController?.tabBarController?.view.addSubview(vc.view) |
| | | vc.view.snp.makeConstraints { make in |
| | | make.left.equalTo(18.5) |
| | | make.right.equalTo(-18.5) |
| | | make.height.equalTo(46.5) |
| | | make.bottom.equalToSuperview().offset(-(tabBarHeight)) |
| | | } |
| | | vc.startRunloopAni() |
| | | |
| | | var testURL = [URL]() |
| | | testURL.append(URL(string: "https://downsc.chinaz.net/files/download/sound1/201206/1638.mp3")!) |
| | | testURL.append(URL(string: "https://downsc.chinaz.net/Files/DownLoad/sound1/201906/11582.mp3")!) |
| | | testURL.append(URL(string: "https://www.cambridgeenglish.org/images/153149-movers-sample-listening-test-vol2.mp3")!) |
| | | vc.audioPlayer.playAt(firstPlayIndex: 2, urls: testURL) |
| | | |
| | | } |
| | | |
| | | |
| | | private func startRunloopAni(){ |
| | | // 创建旋转动画 |
| | | let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z") |
| | | rotationAnimation.fromValue = 0 |
| | | rotationAnimation.toValue = CGFloat.pi * 2 |
| | | rotationAnimation.duration = 5 // 动画持续时间 |
| | | rotationAnimation.repeatCount = .greatestFiniteMagnitude // 无限重复 |
| | | coverImage.layer.add(rotationAnimation, forKey: nil) |
| | | |
| | | } |
| | | |
| | | @objc func tapHandleAction(_ btn:UIButton){ |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | class AudioPlayer { |
| | | private var player:AVPlayer? |
| | | private var playIndex:Int = 0 //播放的角标 |
| | | private var cacheDirectory:URL! |
| | | private let session = URLSession.shared |
| | | private var urls = [URL]() |
| | | |
| | | private static var _sharedInstance: AudioPlayer? |
| | | |
| | | class func getSharedInstance() -> AudioPlayer { |
| | | guard let instance = _sharedInstance else { |
| | | _sharedInstance = AudioPlayer() |
| | | _sharedInstance!.cacheDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent("audios") |
| | | print("---:\(_sharedInstance!.cacheDirectory.absoluteString)") |
| | | |
| | | if !FileManager.default.fileExists(atPath: _sharedInstance!.cacheDirectory!.absoluteString){ |
| | | try? FileManager.default.createDirectory(at: _sharedInstance!.cacheDirectory, withIntermediateDirectories: false) |
| | | } |
| | | return _sharedInstance! |
| | | } |
| | | return instance |
| | | } |
| | | |
| | | private init() {} // 私有化init方法 |
| | | |
| | | //销毁单例对象 |
| | | class func destroy() { |
| | | _sharedInstance = nil |
| | | } |
| | | |
| | | func playAt(firstPlayIndex:Int,urls:[URL]){ |
| | | self.playIndex = firstPlayIndex |
| | | |
| | | autoreleasepool{ |
| | | for url in urls { |
| | | checkCacheAudio(from: url) { _, url in |
| | | self.urls.append(url) |
| | | } |
| | | } |
| | | player = AVPlayer(url: self.urls[firstPlayIndex]) |
| | | player?.play() |
| | | } |
| | | |
| | | self.player!.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 1), queue: DispatchQueue.main) { [unowned self](time) in |
| | | //当前正在播放的时间 |
| | | let loadTime = CMTimeGetSeconds(time) |
| | | //视频总时间 |
| | | let totalTime = CMTimeGetSeconds((self.player?.currentItem?.duration)!) |
| | | |
| | | var dic = [String:Any]() |
| | | dic[MPMediaItemPropertyTitle] = "测试" |
| | | dic[MPNowPlayingInfoPropertyElapsedPlaybackTime] = loadTime |
| | | dic[MPNowPlayingInfoPropertyPlaybackRate] = 1 |
| | | // 获取时长。item.duration.seconds 不凑效 |
| | | let asset = self.player?.currentItem?.asset |
| | | dic[MPMediaItemPropertyPlaybackDuration] = CMTimeGetSeconds(asset!.duration) |
| | | // dic[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: CGSize(width: 50, height: 50), requestHandler: { s in |
| | | // return UIImage() |
| | | // }) |
| | | MPNowPlayingInfoCenter.default().nowPlayingInfo = dic |
| | | } |
| | | |
| | | |
| | | //播放完成 |
| | | NotificationCenter.default.addObserver(self, selector: #selector(playbackEnd), name:NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil) |
| | | |
| | | setLockScreen() |
| | | |
| | | do { |
| | | try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay]) |
| | | print("Playback OK") |
| | | try AVAudioSession.sharedInstance().setActive(true) |
| | | print("Session is Active") |
| | | } catch { |
| | | print(error) |
| | | } |
| | | } |
| | | |
| | | func next(){ |
| | | playIndex += 1 |
| | | let index = min((urls.count - 1), playIndex) |
| | | player?.replaceCurrentItem(with: AVPlayerItem(url: urls[index])) |
| | | player?.play() |
| | | } |
| | | |
| | | @objc private func playbackEnd(){ |
| | | |
| | | } |
| | | |
| | | func previous(){ |
| | | playIndex -= 1 |
| | | let index = max(0, playIndex) |
| | | player?.replaceCurrentItem(with: AVPlayerItem(url: urls[index])) |
| | | player?.play() |
| | | } |
| | | |
| | | |
| | | func setLockScreen(){ |
| | | // 锁屏进度控制 |
| | | let center = MPRemoteCommandCenter.shared() |
| | | |
| | | // 修改进度 |
| | | center.changePlaybackPositionCommand.addTarget {[unowned self] event in |
| | | |
| | | guard let event = event as? MPChangePlaybackPositionCommandEvent else { |
| | | return .commandFailed |
| | | } |
| | | |
| | | self.player?.seek(to: CMTime(seconds: event.positionTime, preferredTimescale: 1), |
| | | toleranceBefore: CMTime(seconds: 0, preferredTimescale: 1), |
| | | toleranceAfter: CMTime(seconds: 0, preferredTimescale: 1)) |
| | | |
| | | // 更新锁屏信息 |
| | | return .success |
| | | } |
| | | |
| | | // 播放 |
| | | center.playCommand.addTarget { event in |
| | | return .success |
| | | } |
| | | |
| | | // 暂停 |
| | | center.pauseCommand.addTarget { event in |
| | | return .success |
| | | } |
| | | |
| | | // 下一首 |
| | | center.nextTrackCommand.addTarget { event in |
| | | return .success |
| | | } |
| | | |
| | | // 上一首 |
| | | center.previousTrackCommand.addTarget { event in |
| | | return .success |
| | | } |
| | | } |
| | | |
| | | |
| | | // 下载视频并缓存,如果没有缓存,原路返回并异步下载 |
| | | internal func checkCacheAudio(from url: URL, completion: @escaping (Bool,URL) -> Void) { |
| | | |
| | | let videoCacheUrl = cacheDirectory.appendingPathComponent(url.lastPathComponent.jq_md5String() + "." + url.pathExtension) |
| | | |
| | | // 检查缓存中是否已存在文件 |
| | | if FileManager.default.fileExists(atPath: videoCacheUrl.path) { |
| | | completion(true,videoCacheUrl) |
| | | return |
| | | }else{ |
| | | completion(false,url) |
| | | } |
| | | |
| | | // 使用URLSession下载视频 |
| | | let downloadTask = session.downloadTask(with: url) { tempLocalUrl, response, error in |
| | | if let tempLocalUrl = tempLocalUrl, error == nil { |
| | | do { |
| | | let temp = videoCacheUrl.appendingPathExtension(url.pathExtension) |
| | | try FileManager.default.moveItem(at: tempLocalUrl, to: temp) |
| | | } catch { |
| | | print("视频缓存失败:catch") |
| | | } |
| | | } else { |
| | | print("视频缓存失败:\(error?.localizedDescription ?? "")") |
| | | } |
| | | } |
| | | downloadTask.resume() |
| | | } |
| | | } |
| | | |
| | | |
| | | struct MusicProjectPlayInfoModel { |
| | | |
| | | } |