提交
1
Podfile
@@ -81,6 +81,7 @@ def taget_pods
|
|||||||
pod 'TIMPush'
|
pod 'TIMPush'
|
||||||
#占位
|
#占位
|
||||||
pod 'DZNEmptyDataSet'
|
pod 'DZNEmptyDataSet'
|
||||||
|
pod 'XHLaunchAd' #广告页
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'QXLive' do
|
target 'QXLive' do
|
||||||
|
|||||||
20
Podfile.lock
@@ -89,6 +89,8 @@ PODS:
|
|||||||
- BRPickerView/TextPicker (2.9.1):
|
- BRPickerView/TextPicker (2.9.1):
|
||||||
- BRPickerView/Core
|
- BRPickerView/Core
|
||||||
- Bugly (2.6.1)
|
- Bugly (2.6.1)
|
||||||
|
- DZNEmptyDataSet (1.8.1)
|
||||||
|
- FLAnimatedImage (1.0.17)
|
||||||
- FMDB (2.7.12):
|
- FMDB (2.7.12):
|
||||||
- FMDB/standard (= 2.7.12)
|
- FMDB/standard (= 2.7.12)
|
||||||
- FMDB/Core (2.7.12)
|
- FMDB/Core (2.7.12)
|
||||||
@@ -189,6 +191,9 @@ PODS:
|
|||||||
- SVGAPlayer/ProtoFiles
|
- SVGAPlayer/ProtoFiles
|
||||||
- SVGAPlayer/ProtoFiles (2.5.7):
|
- SVGAPlayer/ProtoFiles (2.5.7):
|
||||||
- Protobuf (~> 3.4)
|
- Protobuf (~> 3.4)
|
||||||
|
- SVProgressHUD (2.3.1):
|
||||||
|
- SVProgressHUD/Core (= 2.3.1)
|
||||||
|
- SVProgressHUD/Core (2.3.1)
|
||||||
- TencentCloudHuiyanSDKFace_framework (8.7.0)
|
- TencentCloudHuiyanSDKFace_framework (8.7.0)
|
||||||
- TIMCommon (8.5.6864):
|
- TIMCommon (8.5.6864):
|
||||||
- Masonry
|
- Masonry
|
||||||
@@ -222,6 +227,8 @@ PODS:
|
|||||||
- TZImagePickerController/Basic (3.8.8)
|
- TZImagePickerController/Basic (3.8.8)
|
||||||
- TZImagePickerController/Location (3.8.8)
|
- TZImagePickerController/Location (3.8.8)
|
||||||
- WechatOpenSDK-XCFramework (2.0.4)
|
- WechatOpenSDK-XCFramework (2.0.4)
|
||||||
|
- XHLaunchAd (3.9.12):
|
||||||
|
- FLAnimatedImage (~> 1.0.12)
|
||||||
- YBImageBrowser (3.0.9):
|
- YBImageBrowser (3.0.9):
|
||||||
- YBImageBrowser/Core (= 3.0.9)
|
- YBImageBrowser/Core (= 3.0.9)
|
||||||
- YBImageBrowser/Core (3.0.9):
|
- YBImageBrowser/Core (3.0.9):
|
||||||
@@ -254,6 +261,7 @@ DEPENDENCIES:
|
|||||||
- AvoidCrash
|
- AvoidCrash
|
||||||
- BRPickerView
|
- BRPickerView
|
||||||
- Bugly
|
- Bugly
|
||||||
|
- DZNEmptyDataSet
|
||||||
- FMDB
|
- FMDB
|
||||||
- IQKeyboardManager
|
- IQKeyboardManager
|
||||||
- JXCategoryView
|
- JXCategoryView
|
||||||
@@ -269,6 +277,7 @@ DEPENDENCIES:
|
|||||||
- SDWebImage
|
- SDWebImage
|
||||||
- SDWebImageWebPCoder
|
- SDWebImageWebPCoder
|
||||||
- SVGAPlayer
|
- SVGAPlayer
|
||||||
|
- SVProgressHUD
|
||||||
- TencentCloudHuiyanSDKFace_framework (from `./TencentCloudHuiyanSDKFace_framework`)
|
- TencentCloudHuiyanSDKFace_framework (from `./TencentCloudHuiyanSDKFace_framework`)
|
||||||
- TIMCommon (from `./TUIKit/TIMCommon`)
|
- TIMCommon (from `./TUIKit/TIMCommon`)
|
||||||
- TIMPush
|
- TIMPush
|
||||||
@@ -277,6 +286,7 @@ DEPENDENCIES:
|
|||||||
- TUICore (from `./TUIKit/TUICore`)
|
- TUICore (from `./TUIKit/TUICore`)
|
||||||
- TZImagePickerController
|
- TZImagePickerController
|
||||||
- WechatOpenSDK-XCFramework (~> 2.0.2)
|
- WechatOpenSDK-XCFramework (~> 2.0.2)
|
||||||
|
- XHLaunchAd
|
||||||
- YBImageBrowser (~> 3.0.9)
|
- YBImageBrowser (~> 3.0.9)
|
||||||
- YBImageBrowser/Video
|
- YBImageBrowser/Video
|
||||||
- YYCache
|
- YYCache
|
||||||
@@ -298,6 +308,8 @@ SPEC REPOS:
|
|||||||
- AvoidCrash
|
- AvoidCrash
|
||||||
- BRPickerView
|
- BRPickerView
|
||||||
- Bugly
|
- Bugly
|
||||||
|
- DZNEmptyDataSet
|
||||||
|
- FLAnimatedImage
|
||||||
- FMDB
|
- FMDB
|
||||||
- IQKeyboardManager
|
- IQKeyboardManager
|
||||||
- JXCategoryView
|
- JXCategoryView
|
||||||
@@ -318,10 +330,12 @@ SPEC REPOS:
|
|||||||
- SDWebImageWebPCoder
|
- SDWebImageWebPCoder
|
||||||
- SSZipArchive
|
- SSZipArchive
|
||||||
- SVGAPlayer
|
- SVGAPlayer
|
||||||
|
- SVProgressHUD
|
||||||
- TIMPush
|
- TIMPush
|
||||||
- TXIMSDK_Plus_iOS_XCFramework
|
- TXIMSDK_Plus_iOS_XCFramework
|
||||||
- TZImagePickerController
|
- TZImagePickerController
|
||||||
- WechatOpenSDK-XCFramework
|
- WechatOpenSDK-XCFramework
|
||||||
|
- XHLaunchAd
|
||||||
- YBImageBrowser
|
- YBImageBrowser
|
||||||
- YYCache
|
- YYCache
|
||||||
- YYCategories
|
- YYCategories
|
||||||
@@ -354,6 +368,8 @@ SPEC CHECKSUMS:
|
|||||||
AvoidCrash: 28c6916fe19bd2b84126b8dec7cbe61c9a12741d
|
AvoidCrash: 28c6916fe19bd2b84126b8dec7cbe61c9a12741d
|
||||||
BRPickerView: 6dd69ea2c48e0a0abf1d197a705050e13143ee63
|
BRPickerView: 6dd69ea2c48e0a0abf1d197a705050e13143ee63
|
||||||
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
|
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
|
||||||
|
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
|
||||||
|
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
|
||||||
FMDB: 728731dd336af3936ce00f91d9d8495f5718a0e6
|
FMDB: 728731dd336af3936ce00f91d9d8495f5718a0e6
|
||||||
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
|
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
|
||||||
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
|
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
|
||||||
@@ -374,6 +390,7 @@ SPEC CHECKSUMS:
|
|||||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||||
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
|
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
|
||||||
|
SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
|
||||||
TencentCloudHuiyanSDKFace_framework: 1a9398776aac617c2ea7e580fbaf797be96256e1
|
TencentCloudHuiyanSDKFace_framework: 1a9398776aac617c2ea7e580fbaf797be96256e1
|
||||||
TIMCommon: 23ed3f287fe194ce5139ce421f96cfb81232562f
|
TIMCommon: 23ed3f287fe194ce5139ce421f96cfb81232562f
|
||||||
TIMPush: e1d85ff0ee0c22cc3f51010ddd8de5316d60102c
|
TIMPush: e1d85ff0ee0c22cc3f51010ddd8de5316d60102c
|
||||||
@@ -383,6 +400,7 @@ SPEC CHECKSUMS:
|
|||||||
TXIMSDK_Plus_iOS_XCFramework: ae200b67e618fef504947de6551b127d35b18d67
|
TXIMSDK_Plus_iOS_XCFramework: ae200b67e618fef504947de6551b127d35b18d67
|
||||||
TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf
|
TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf
|
||||||
WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f
|
WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f
|
||||||
|
XHLaunchAd: 6320f9c68732667323072fc3a5f104e40fbe9cfe
|
||||||
YBImageBrowser: 7ecc8bf33ffa5f3b94c397c29b4f3638dd37f527
|
YBImageBrowser: 7ecc8bf33ffa5f3b94c397c29b4f3638dd37f527
|
||||||
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
|
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
|
||||||
YYCategories: 6bcd4314c6661a561410dce4a793379ebd306abd
|
YYCategories: 6bcd4314c6661a561410dce4a793379ebd306abd
|
||||||
@@ -392,6 +410,6 @@ SPEC CHECKSUMS:
|
|||||||
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
|
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
|
||||||
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67
|
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67
|
||||||
|
|
||||||
PODFILE CHECKSUM: 0bc5dc8150dc827b074af9f826d3454f1feacf07
|
PODFILE CHECKSUM: 068f3e03c3d864b09a8c3ffbb0275bbd06bd6ed7
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
9
Pods/DZNEmptyDataSet/LICENSE
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl
|
||||||
|
|
||||||
|
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.
|
||||||
296
Pods/DZNEmptyDataSet/README.md
generated
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
DZNEmptyDataSet
|
||||||
|
=================
|
||||||
|
|
||||||
|
[](http://cocoadocs.org/docsets/DZNEmptyDataSet/)
|
||||||
|
[](https://github.com/Carthage/Carthage)
|
||||||
|
[](http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
### Projects using this library
|
||||||
|
|
||||||
|
[Add your project to the list here](https://github.com/dzenbot/DZNEmptyDataSet/wiki/Projects-using-DZNEmptyDataSet) and provide a (320px wide) render of the result.
|
||||||
|
|
||||||
|
|
||||||
|
### The Empty Data Set Pattern
|
||||||
|
Also known as *[Empty State](http://emptystat.es/)* or *[Blank Slate](http://patternry.com/p=blank-slate/)*.
|
||||||
|
|
||||||
|
Most applications show lists of content (data sets), which many turn out to be empty at one point, specially for new users with blank accounts. Empty screens create confusion by not being clear about what's going on, if there is an error/bug or if the user is supposed to do something within your app to be able to consume the content.
|
||||||
|
|
||||||
|
Please read this very interesting article about [*Designing For The Empty States*](http://tympanus.net/codrops/2013/01/09/designing-for-the-empty-states/).
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
(*These are real life examples, available in the 'Applications' sample project*)
|
||||||
|
|
||||||
|
**[Empty Data Sets](http://pttrns.com/?did=1&scid=30)** are helpful for:
|
||||||
|
* Avoiding white-screens and communicating to your users why the screen is empty.
|
||||||
|
* Calling to action (particularly as an onboarding process).
|
||||||
|
* Avoiding other interruptive mechanisms like showing error alerts.
|
||||||
|
* Being consistent and improving the user experience.
|
||||||
|
* Delivering a brand presence.
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
* Compatible with UITableView and UICollectionView. Also compatible with UISearchDisplayController and UIScrollView.
|
||||||
|
* Gives multiple possibilities of layout and appearance, by showing an image and/or title label and/or description label and/or button.
|
||||||
|
* Uses NSAttributedString for easier appearance customisation.
|
||||||
|
* Uses auto-layout to automagically center the content to the tableview, with auto-rotation support. Also accepts custom vertical and horizontal alignment.
|
||||||
|
* Background color customisation.
|
||||||
|
* Allows tap gesture on the whole tableview rectangle (useful for resigning first responder or similar actions).
|
||||||
|
* For more advanced customisation, it allows a custom view.
|
||||||
|
* Compatible with Storyboard.
|
||||||
|
* Compatible with iOS 6 or later.
|
||||||
|
* Compatible with iPhone and iPad.
|
||||||
|
* **App Store ready**
|
||||||
|
|
||||||
|
This library has been designed in a way where you won't need to extend UITableView or UICollectionView class. It will still work when using UITableViewController or UICollectionViewController.
|
||||||
|
By just conforming to DZNEmptyDataSetSource & DZNEmptyDataSetDelegate, you will be able to fully customize the content and appearance of the empty states for your application.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Available in [CocoaPods](http://cocoapods.org/?q=DZNEmptyDataSet)
|
||||||
|
```ruby
|
||||||
|
pod 'DZNEmptyDataSet'
|
||||||
|
```
|
||||||
|
|
||||||
|
To integrate DZNEmptyDataSet into your Xcode project using Carthage, specify it in your `Cartfile`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
github "dzenbot/DZNEmptyDataSet"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
For complete documentation, [visit CocoaPods' auto-generated doc](http://cocoadocs.org/docsets/DZNEmptyDataSet/)
|
||||||
|
|
||||||
|
### Import
|
||||||
|
```objc
|
||||||
|
#import "UIScrollView+EmptyDataSet.h"
|
||||||
|
```
|
||||||
|
Unless you are importing as a framework, then do:
|
||||||
|
```objc
|
||||||
|
#import "<DZNEmptyDataSet/UIScrollView+EmptyDataSet.h>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Protocol Conformance
|
||||||
|
Conform to datasource and/or delegate.
|
||||||
|
```objc
|
||||||
|
@interface MainViewController : UITableViewController <DZNEmptyDataSetSource, DZNEmptyDataSetDelegate>
|
||||||
|
|
||||||
|
- (void)viewDidLoad
|
||||||
|
{
|
||||||
|
[super viewDidLoad];
|
||||||
|
|
||||||
|
self.tableView.emptyDataSetSource = self;
|
||||||
|
self.tableView.emptyDataSetDelegate = self;
|
||||||
|
|
||||||
|
// A little trick for removing the cell separators
|
||||||
|
self.tableView.tableFooterView = [UIView new];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Source Implementation
|
||||||
|
Return the content you want to show on the empty state, and take advantage of NSAttributedString features to customise the text appearance.
|
||||||
|
|
||||||
|
The image for the empty state:
|
||||||
|
```objc
|
||||||
|
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return [UIImage imageNamed:@"empty_placeholder"];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The image view animation
|
||||||
|
```objc
|
||||||
|
- (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"transform"];
|
||||||
|
|
||||||
|
animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
|
||||||
|
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0)];
|
||||||
|
|
||||||
|
animation.duration = 0.25;
|
||||||
|
animation.cumulative = YES;
|
||||||
|
animation.repeatCount = MAXFLOAT;
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The attributed string for the title of the empty state:
|
||||||
|
```objc
|
||||||
|
- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
NSString *text = @"Please Allow Photo Access";
|
||||||
|
|
||||||
|
NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:18.0f],
|
||||||
|
NSForegroundColorAttributeName: [UIColor darkGrayColor]};
|
||||||
|
|
||||||
|
return [[NSAttributedString alloc] initWithString:text attributes:attributes];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The attributed string for the description of the empty state:
|
||||||
|
```objc
|
||||||
|
- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
NSString *text = @"This allows you to share photos from your library and save photos to your camera roll.";
|
||||||
|
|
||||||
|
NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
|
||||||
|
paragraph.lineBreakMode = NSLineBreakByWordWrapping;
|
||||||
|
paragraph.alignment = NSTextAlignmentCenter;
|
||||||
|
|
||||||
|
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f],
|
||||||
|
NSForegroundColorAttributeName: [UIColor lightGrayColor],
|
||||||
|
NSParagraphStyleAttributeName: paragraph};
|
||||||
|
|
||||||
|
return [[NSAttributedString alloc] initWithString:text attributes:attributes];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The attributed string to be used for the specified button state:
|
||||||
|
```objc
|
||||||
|
- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state
|
||||||
|
{
|
||||||
|
NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0f]};
|
||||||
|
|
||||||
|
return [[NSAttributedString alloc] initWithString:@"Continue" attributes:attributes];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
or the image to be used for the specified button state:
|
||||||
|
```objc
|
||||||
|
- (UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state
|
||||||
|
{
|
||||||
|
return [UIImage imageNamed:@"button_image"];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The background color for the empty state:
|
||||||
|
```objc
|
||||||
|
- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return [UIColor whiteColor];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need a more complex layout, you can return a custom view instead:
|
||||||
|
```objc
|
||||||
|
- (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||||
|
[activityView startAnimating];
|
||||||
|
return activityView;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, you can also adjust the vertical alignment of the content view (ie: useful when there is tableHeaderView visible):
|
||||||
|
```objc
|
||||||
|
- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return -self.tableView.tableHeaderView.frame.size.height/2.0f;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, you can separate components from each other (default separation is 11 pts):
|
||||||
|
```objc
|
||||||
|
- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return 20.0f;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Delegate Implementation
|
||||||
|
Return the behaviours you would expect from the empty states, and receive the user events.
|
||||||
|
|
||||||
|
Asks to know if the empty state should be rendered and displayed (Default is YES) :
|
||||||
|
```objc
|
||||||
|
- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Asks for interaction permission (Default is YES) :
|
||||||
|
```objc
|
||||||
|
- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Asks for scrolling permission (Default is NO) :
|
||||||
|
```objc
|
||||||
|
- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Asks for image view animation permission (Default is NO) :
|
||||||
|
```objc
|
||||||
|
- (BOOL) emptyDataSetShouldAllowImageViewAnimate:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Notifies when the dataset view was tapped:
|
||||||
|
```objc
|
||||||
|
- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view
|
||||||
|
{
|
||||||
|
// Do something
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Notifies when the data set call to action button was tapped:
|
||||||
|
```objc
|
||||||
|
- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button
|
||||||
|
{
|
||||||
|
// Do something
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Refresh layout
|
||||||
|
If you need to refresh the empty state layout, simply call:
|
||||||
|
|
||||||
|
```objc
|
||||||
|
[self.tableView reloadData];
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```objc
|
||||||
|
[self.collectionView reloadData];
|
||||||
|
```
|
||||||
|
depending of which you are using.
|
||||||
|
|
||||||
|
### Force layout update
|
||||||
|
You can also call `[self.tableView reloadEmptyDataSet]` to invalidate the current empty state layout and trigger a layout update, bypassing `-reloadData`. This might be useful if you have a lot of logic on your data source that you want to avoid calling, when not needed. `[self.scrollView reloadEmptyDataSet]` is the only way to refresh content when using with UIScrollView.
|
||||||
|
|
||||||
|
|
||||||
|
## Sample projects
|
||||||
|
|
||||||
|
#### Applications
|
||||||
|
This project replicates several popular application's empty states (~20) with their exact content and appearance, such as Airbnb, Dropbox, Facebook, Foursquare, and many others. See how easy and flexible it is to customize the appearance of your empty states. You can also use this project as a playground to test things.
|
||||||
|
|
||||||
|
#### Countries
|
||||||
|
This project shows a list of the world countries loaded from CoreData. It uses NSFecthedResultController for filtering search. When searching and no content is matched, a simple empty state is shown. See how to interact between the UITableViewDataSource and the DZNEmptyDataSetSource protocols, while using a typical CoreData stack.
|
||||||
|
|
||||||
|
#### Colors
|
||||||
|
This project is a simple example of how this library also works with UICollectionView and UISearchDisplayController, while using Storyboards.
|
||||||
|
|
||||||
|
|
||||||
|
## Collaboration
|
||||||
|
Feel free to collaborate with ideas, issues and/or pull requests.
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl
|
||||||
|
|
||||||
|
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.
|
||||||
280
Pods/DZNEmptyDataSet/Source/UIScrollView+EmptyDataSet.h
generated
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
//
|
||||||
|
// UIScrollView+EmptyDataSet.h
|
||||||
|
// DZNEmptyDataSet
|
||||||
|
// https://github.com/dzenbot/DZNEmptyDataSet
|
||||||
|
//
|
||||||
|
// Created by Ignacio Romero Zurbuchen on 6/20/14.
|
||||||
|
// Copyright (c) 2016 DZN Labs. All rights reserved.
|
||||||
|
// Licence: MIT-Licence
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@protocol DZNEmptyDataSetSource;
|
||||||
|
@protocol DZNEmptyDataSetDelegate;
|
||||||
|
|
||||||
|
#define DZNEmptyDataSetDeprecated(instead) DEPRECATED_MSG_ATTRIBUTE(" Use " # instead " instead")
|
||||||
|
|
||||||
|
/**
|
||||||
|
A drop-in UITableView/UICollectionView superclass category for showing empty datasets whenever the view has no content to display.
|
||||||
|
@discussion It will work automatically, by just conforming to DZNEmptyDataSetSource, and returning the data you want to show.
|
||||||
|
*/
|
||||||
|
@interface UIScrollView (EmptyDataSet)
|
||||||
|
|
||||||
|
/** The empty datasets data source. */
|
||||||
|
@property (nonatomic, weak) IBOutlet id <DZNEmptyDataSetSource> emptyDataSetSource;
|
||||||
|
/** The empty datasets delegate. */
|
||||||
|
@property (nonatomic, weak) IBOutlet id <DZNEmptyDataSetDelegate> emptyDataSetDelegate;
|
||||||
|
/** YES if any empty dataset is visible. */
|
||||||
|
@property (nonatomic, readonly, getter = isEmptyDataSetVisible) BOOL emptyDataSetVisible;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reloads the empty dataset content receiver.
|
||||||
|
@discussion Call this method to force all the data to refresh. Calling -reloadData is similar, but this forces only the empty dataset to reload, not the entire table view or collection view.
|
||||||
|
*/
|
||||||
|
- (void)reloadEmptyDataSet;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
The object that acts as the data source of the empty datasets.
|
||||||
|
@discussion The data source must adopt the DZNEmptyDataSetSource protocol. The data source is not retained. All data source methods are optional.
|
||||||
|
*/
|
||||||
|
@protocol DZNEmptyDataSetSource <NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for the title of the dataset.
|
||||||
|
The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the data source.
|
||||||
|
@return An attributed string for the dataset title, combining font, text color, text pararaph style, etc.
|
||||||
|
*/
|
||||||
|
- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for the description of the dataset.
|
||||||
|
The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the data source.
|
||||||
|
@return An attributed string for the dataset description text, combining font, text color, text pararaph style, etc.
|
||||||
|
*/
|
||||||
|
- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for the image of the dataset.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the data source.
|
||||||
|
@return An image for the dataset.
|
||||||
|
*/
|
||||||
|
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for a tint color of the image dataset. Default is nil.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the data source.
|
||||||
|
@return A color to tint the image of the dataset.
|
||||||
|
*/
|
||||||
|
- (UIColor *)imageTintColorForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the data source for the image animation of the dataset.
|
||||||
|
*
|
||||||
|
* @param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
*
|
||||||
|
* @return image animation
|
||||||
|
*/
|
||||||
|
- (CAAnimation *) imageAnimationForEmptyDataSet:(UIScrollView *) scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for the title to be used for the specified button state.
|
||||||
|
The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the data source.
|
||||||
|
@param state The state that uses the specified title. The possible values are described in UIControlState.
|
||||||
|
@return An attributed string for the dataset button title, combining font, text color, text pararaph style, etc.
|
||||||
|
*/
|
||||||
|
- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for the image to be used for the specified button state.
|
||||||
|
This method will override buttonTitleForEmptyDataSet:forState: and present the image only without any text.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the data source.
|
||||||
|
@param state The state that uses the specified title. The possible values are described in UIControlState.
|
||||||
|
@return An image for the dataset button imageview.
|
||||||
|
*/
|
||||||
|
- (UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for a background image to be used for the specified button state.
|
||||||
|
There is no default style for this call.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the data source.
|
||||||
|
@param state The state that uses the specified image. The values are described in UIControlState.
|
||||||
|
@return An attributed string for the dataset button title, combining font, text color, text pararaph style, etc.
|
||||||
|
*/
|
||||||
|
- (UIImage *)buttonBackgroundImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for the background color of the dataset. Default is clear color.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the data source.
|
||||||
|
@return A color to be applied to the dataset background view.
|
||||||
|
*/
|
||||||
|
- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for a custom view to be displayed instead of the default views such as labels, imageview and button. Default is nil.
|
||||||
|
Use this method to show an activity view indicator for loading feedback, or for complete custom empty data set.
|
||||||
|
Returning a custom view will ignore -offsetForEmptyDataSet and -spaceHeightForEmptyDataSet configurations.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return The custom view.
|
||||||
|
*/
|
||||||
|
- (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for a offset for vertical and horizontal alignment of the content. Default is CGPointZero.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return The offset for vertical and horizontal alignment.
|
||||||
|
*/
|
||||||
|
- (CGPoint)offsetForEmptyDataSet:(UIScrollView *)scrollView DZNEmptyDataSetDeprecated(-verticalOffsetForEmptyDataSet:);
|
||||||
|
- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the data source for a vertical space between elements. Default is 11 pts.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return The space height between elements.
|
||||||
|
*/
|
||||||
|
- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
The object that acts as the delegate of the empty datasets.
|
||||||
|
@discussion The delegate can adopt the DZNEmptyDataSetDelegate protocol. The delegate is not retained. All delegate methods are optional.
|
||||||
|
|
||||||
|
@discussion All delegate methods are optional. Use this delegate for receiving action callbacks.
|
||||||
|
*/
|
||||||
|
@protocol DZNEmptyDataSetDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the delegate to know if the empty dataset should fade in when displayed. Default is YES.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return YES if the empty dataset should fade in.
|
||||||
|
*/
|
||||||
|
- (BOOL)emptyDataSetShouldFadeIn:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the delegate to know if the empty dataset should still be displayed when the amount of items is more than 0. Default is NO
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return YES if empty dataset should be forced to display
|
||||||
|
*/
|
||||||
|
- (BOOL)emptyDataSetShouldBeForcedToDisplay:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the delegate to know if the empty dataset should be rendered and displayed. Default is YES.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return YES if the empty dataset should show.
|
||||||
|
*/
|
||||||
|
- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the delegate for touch permission. Default is YES.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return YES if the empty dataset receives touch gestures.
|
||||||
|
*/
|
||||||
|
- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the delegate for scroll permission. Default is NO.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return YES if the empty dataset is allowed to be scrollable.
|
||||||
|
*/
|
||||||
|
- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Asks the delegate for image view animation permission. Default is NO.
|
||||||
|
Make sure to return a valid CAAnimation object from imageAnimationForEmptyDataSet:
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass object informing the delegate.
|
||||||
|
@return YES if the empty dataset is allowed to animate
|
||||||
|
*/
|
||||||
|
- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the empty dataset view was tapped.
|
||||||
|
Use this method either to resignFirstResponder of a textfield or searchBar.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSetDidTapView:(UIScrollView *)scrollView DZNEmptyDataSetDeprecated(-emptyDataSet:didTapView:);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the action button was tapped.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSetDidTapButton:(UIScrollView *)scrollView DZNEmptyDataSetDeprecated(-emptyDataSet:didTapButton:);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the empty dataset view was tapped.
|
||||||
|
Use this method either to resignFirstResponder of a textfield or searchBar.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
@param view the view tapped by the user
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the action button was tapped.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
@param button the button tapped by the user
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the empty data set will appear.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSetWillAppear:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the empty data set did appear.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSetDidAppear:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the empty data set will disappear.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSetWillDisappear:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the delegate that the empty data set did disappear.
|
||||||
|
|
||||||
|
@param scrollView A scrollView subclass informing the delegate.
|
||||||
|
*/
|
||||||
|
- (void)emptyDataSetDidDisappear:(UIScrollView *)scrollView;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#undef DZNEmptyDataSetDeprecated
|
||||||
|
|
||||||
1074
Pods/DZNEmptyDataSet/Source/UIScrollView+EmptyDataSet.m
generated
Normal file
820
Pods/FLAnimatedImage/FLAnimatedImage/FLAnimatedImage.m
generated
Executable file
@@ -0,0 +1,820 @@
|
|||||||
|
//
|
||||||
|
// FLAnimatedImage.m
|
||||||
|
// Flipboard
|
||||||
|
//
|
||||||
|
// Created by Raphael Schaad on 7/8/13.
|
||||||
|
// Copyright (c) Flipboard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#import "FLAnimatedImage.h"
|
||||||
|
#import <ImageIO/ImageIO.h>
|
||||||
|
#if __has_include(<MobileCoreServices/MobileCoreServices.h>)
|
||||||
|
#import <MobileCoreServices/MobileCoreServices.h>
|
||||||
|
#else
|
||||||
|
#import <CoreServices/CoreServices.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// From vm_param.h, define for iOS 8.0 or higher to build on device.
|
||||||
|
#ifndef BYTE_SIZE
|
||||||
|
#define BYTE_SIZE 8 // byte size in bits
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MEGABYTE (1024 * 1024)
|
||||||
|
|
||||||
|
// This is how the fastest browsers do it as per 2012: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser-compatibility
|
||||||
|
const NSTimeInterval kFLAnimatedImageDelayTimeIntervalMinimum = 0.02;
|
||||||
|
|
||||||
|
// An animated image's data size (dimensions * frameCount) category; its value is the max allowed memory (in MB).
|
||||||
|
// E.g.: A 100x200px GIF with 30 frames is ~2.3MB in our pixel format and would fall into the `FLAnimatedImageDataSizeCategoryAll` category.
|
||||||
|
typedef NS_ENUM(NSUInteger, FLAnimatedImageDataSizeCategory) {
|
||||||
|
FLAnimatedImageDataSizeCategoryAll = 10, // All frames permanently in memory (be nice to the CPU)
|
||||||
|
FLAnimatedImageDataSizeCategoryDefault = 75, // A frame cache of default size in memory (usually real-time performance and keeping low memory profile)
|
||||||
|
FLAnimatedImageDataSizeCategoryOnDemand = 250, // Only keep one frame at the time in memory (easier on memory, slowest performance)
|
||||||
|
FLAnimatedImageDataSizeCategoryUnsupported // Even for one frame too large, computer says no.
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, FLAnimatedImageFrameCacheSize) {
|
||||||
|
FLAnimatedImageFrameCacheSizeNoLimit = 0, // 0 means no specific limit
|
||||||
|
FLAnimatedImageFrameCacheSizeLowMemory = 1, // The minimum frame cache size; this will produce frames on-demand.
|
||||||
|
FLAnimatedImageFrameCacheSizeGrowAfterMemoryWarning = 2, // If we can produce the frames faster than we consume, one frame ahead will already result in a stutter-free playback.
|
||||||
|
FLAnimatedImageFrameCacheSizeDefault = 5 // Build up a comfy buffer window to cope with CPU hiccups etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
@protocol FLAnimatedImageDebugDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
- (void)debug_animatedImage:(FLAnimatedImage *)animatedImage didUpdateCachedFrames:(NSIndexSet *)indexesOfFramesInCache;
|
||||||
|
- (void)debug_animatedImage:(FLAnimatedImage *)animatedImage didRequestCachedFrame:(NSUInteger)index;
|
||||||
|
- (CGFloat)debug_animatedImagePredrawingSlowdownFactor:(FLAnimatedImage *)animatedImage;
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@interface FLAnimatedImage ()
|
||||||
|
|
||||||
|
@property (nonatomic, assign, readonly) NSUInteger frameCacheSizeOptimal; // The optimal number of frames to cache based on image size & number of frames; never changes
|
||||||
|
@property (nonatomic, assign, readonly, getter=isPredrawingEnabled) BOOL predrawingEnabled; // Enables predrawing of images to improve performance.
|
||||||
|
@property (nonatomic, assign) NSUInteger frameCacheSizeMaxInternal; // Allow to cap the cache size e.g. when memory warnings occur; 0 means no specific limit (default)
|
||||||
|
@property (nonatomic, assign) NSUInteger requestedFrameIndex; // Most recently requested frame index
|
||||||
|
@property (nonatomic, assign, readonly) NSUInteger posterImageFrameIndex; // Index of non-purgable poster image; never changes
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableDictionary *cachedFramesForIndexes;
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableIndexSet *cachedFrameIndexes; // Indexes of cached frames
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableIndexSet *requestedFrameIndexes; // Indexes of frames that are currently produced in the background
|
||||||
|
@property (nonatomic, strong, readonly) NSIndexSet *allFramesIndexSet; // Default index set with the full range of indexes; never changes
|
||||||
|
@property (nonatomic, assign) NSUInteger memoryWarningCount;
|
||||||
|
@property (nonatomic, strong, readonly) dispatch_queue_t serialQueue;
|
||||||
|
@property (nonatomic, strong, readonly) __attribute__((NSObject)) CGImageSourceRef imageSource;
|
||||||
|
|
||||||
|
// The weak proxy is used to break retain cycles with delayed actions from memory warnings.
|
||||||
|
// We are lying about the actual type here to gain static type checking and eliminate casts.
|
||||||
|
// The actual type of the object is `FLWeakProxy`.
|
||||||
|
@property (nonatomic, strong, readonly) FLAnimatedImage *weakProxy;
|
||||||
|
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
@property (nonatomic, weak) id<FLAnimatedImageDebugDelegate> debug_delegate;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
// For custom dispatching of memory warnings to avoid deallocation races since NSNotificationCenter doesn't retain objects it is notifying.
|
||||||
|
static NSHashTable *allAnimatedImagesWeak;
|
||||||
|
|
||||||
|
@implementation FLAnimatedImage
|
||||||
|
|
||||||
|
#pragma mark - Accessors
|
||||||
|
#pragma mark Public
|
||||||
|
|
||||||
|
// This is the definite value the frame cache needs to size itself to.
|
||||||
|
- (NSUInteger)frameCacheSizeCurrent
|
||||||
|
{
|
||||||
|
NSUInteger frameCacheSizeCurrent = self.frameCacheSizeOptimal;
|
||||||
|
|
||||||
|
// If set, respect the caps.
|
||||||
|
if (self.frameCacheSizeMax > FLAnimatedImageFrameCacheSizeNoLimit) {
|
||||||
|
frameCacheSizeCurrent = MIN(frameCacheSizeCurrent, self.frameCacheSizeMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.frameCacheSizeMaxInternal > FLAnimatedImageFrameCacheSizeNoLimit) {
|
||||||
|
frameCacheSizeCurrent = MIN(frameCacheSizeCurrent, self.frameCacheSizeMaxInternal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return frameCacheSizeCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)setFrameCacheSizeMax:(NSUInteger)frameCacheSizeMax
|
||||||
|
{
|
||||||
|
if (_frameCacheSizeMax != frameCacheSizeMax) {
|
||||||
|
|
||||||
|
// Remember whether the new cap will cause the current cache size to shrink; then we'll make sure to purge from the cache if needed.
|
||||||
|
const BOOL willFrameCacheSizeShrink = (frameCacheSizeMax < self.frameCacheSizeCurrent);
|
||||||
|
|
||||||
|
// Update the value
|
||||||
|
_frameCacheSizeMax = frameCacheSizeMax;
|
||||||
|
|
||||||
|
if (willFrameCacheSizeShrink) {
|
||||||
|
[self purgeFrameCacheIfNeeded];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Private
|
||||||
|
|
||||||
|
- (void)setFrameCacheSizeMaxInternal:(NSUInteger)frameCacheSizeMaxInternal
|
||||||
|
{
|
||||||
|
if (_frameCacheSizeMaxInternal != frameCacheSizeMaxInternal) {
|
||||||
|
|
||||||
|
// Remember whether the new cap will cause the current cache size to shrink; then we'll make sure to purge from the cache if needed.
|
||||||
|
BOOL willFrameCacheSizeShrink = (frameCacheSizeMaxInternal < self.frameCacheSizeCurrent);
|
||||||
|
|
||||||
|
// Update the value
|
||||||
|
_frameCacheSizeMaxInternal = frameCacheSizeMaxInternal;
|
||||||
|
|
||||||
|
if (willFrameCacheSizeShrink) {
|
||||||
|
[self purgeFrameCacheIfNeeded];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Life Cycle
|
||||||
|
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
if (self == [FLAnimatedImage class]) {
|
||||||
|
// UIKit memory warning notification handler shared by all of the instances
|
||||||
|
allAnimatedImagesWeak = [NSHashTable weakObjectsHashTable];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
|
||||||
|
// UIKit notifications are posted on the main thread. didReceiveMemoryWarning: is expecting the main run loop, and we don't lock on allAnimatedImagesWeak
|
||||||
|
NSAssert([NSThread isMainThread], @"Received memory warning on non-main thread");
|
||||||
|
// Get a strong reference to all of the images. If an instance is returned in this array, it is still live and has not entered dealloc.
|
||||||
|
// Note that FLAnimatedImages can be created on any thread, so the hash table must be locked.
|
||||||
|
NSArray *images = nil;
|
||||||
|
@synchronized(allAnimatedImagesWeak) {
|
||||||
|
images = [[allAnimatedImagesWeak allObjects] copy];
|
||||||
|
}
|
||||||
|
// Now issue notifications to all of the images while holding a strong reference to them
|
||||||
|
[images makeObjectsPerformSelector:@selector(didReceiveMemoryWarning:) withObject:note];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
FLAnimatedImage *_Nullable const animatedImage = [self initWithAnimatedGIFData:nil];
|
||||||
|
if (!animatedImage) {
|
||||||
|
FLLog(FLLogLevelError, @"Use `-initWithAnimatedGIFData:` and supply the animated GIF data as an argument to initialize an object of type `FLAnimatedImage`.");
|
||||||
|
}
|
||||||
|
return animatedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (instancetype)initWithAnimatedGIFData:(NSData *)data
|
||||||
|
{
|
||||||
|
return [self initWithAnimatedGIFData:data optimalFrameCacheSize:0 predrawingEnabled:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithAnimatedGIFData:(NSData *)data optimalFrameCacheSize:(NSUInteger)optimalFrameCacheSize predrawingEnabled:(BOOL)isPredrawingEnabled
|
||||||
|
{
|
||||||
|
// Early return if no data supplied!
|
||||||
|
const BOOL hasData = (data.length > 0);
|
||||||
|
if (!hasData) {
|
||||||
|
FLLog(FLLogLevelError, @"No animated GIF data supplied.");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
// Do one-time initializations of `readonly` properties directly to ivar to prevent implicit actions and avoid need for private `readwrite` property overrides.
|
||||||
|
|
||||||
|
// Keep a strong reference to `data` and expose it read-only publicly.
|
||||||
|
// However, we will use the `_imageSource` as handler to the image data throughout our life cycle.
|
||||||
|
_data = data;
|
||||||
|
_predrawingEnabled = isPredrawingEnabled;
|
||||||
|
|
||||||
|
// Initialize internal data structures
|
||||||
|
_cachedFramesForIndexes = [[NSMutableDictionary alloc] init];
|
||||||
|
_cachedFrameIndexes = [[NSMutableIndexSet alloc] init];
|
||||||
|
_requestedFrameIndexes = [[NSMutableIndexSet alloc] init];
|
||||||
|
|
||||||
|
// Note: We could leverage `CGImageSourceCreateWithURL` too to add a second initializer `-initWithAnimatedGIFContentsOfURL:`.
|
||||||
|
_imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data,
|
||||||
|
(__bridge CFDictionaryRef)@{(NSString *)kCGImageSourceShouldCache: @NO});
|
||||||
|
// Early return on failure!
|
||||||
|
if (!_imageSource) {
|
||||||
|
FLLog(FLLogLevelError, @"Failed to `CGImageSourceCreateWithData` for animated GIF data %@", data);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Early return if not GIF!
|
||||||
|
const CFStringRef _Nullable imageSourceContainerType = CGImageSourceGetType(_imageSource);
|
||||||
|
const BOOL isGIFData = imageSourceContainerType ? UTTypeConformsTo(imageSourceContainerType, kUTTypeGIF) : NO;
|
||||||
|
if (!isGIFData) {
|
||||||
|
FLLog(FLLogLevelError, @"Supplied data is of type %@ and doesn't seem to be GIF data %@", imageSourceContainerType, data);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get `LoopCount`
|
||||||
|
// Note: 0 means repeating the animation indefinitely.
|
||||||
|
// Image properties example:
|
||||||
|
// {
|
||||||
|
// FileSize = 314446;
|
||||||
|
// "{GIF}" = {
|
||||||
|
// HasGlobalColorMap = 1;
|
||||||
|
// LoopCount = 0;
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
NSDictionary *_Nullable const imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(_imageSource, NULL);
|
||||||
|
_loopCount = [[[imageProperties objectForKey:(id)kCGImagePropertyGIFDictionary] objectForKey:(id)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
|
||||||
|
|
||||||
|
// Iterate through frame images
|
||||||
|
const size_t imageCount = CGImageSourceGetCount(_imageSource);
|
||||||
|
NSUInteger skippedFrameCount = 0;
|
||||||
|
NSMutableDictionary *const delayTimesForIndexesMutable = [NSMutableDictionary dictionaryWithCapacity:imageCount];
|
||||||
|
for (size_t i = 0; i < imageCount; i++) {
|
||||||
|
@autoreleasepool {
|
||||||
|
const CGImageRef _Nullable frameImageRef = CGImageSourceCreateImageAtIndex(_imageSource, i, NULL);
|
||||||
|
if (frameImageRef) {
|
||||||
|
UIImage *frameImage = [UIImage imageWithCGImage:frameImageRef];
|
||||||
|
// Check for valid `frameImage` before parsing its properties as frames can be corrupted (and `frameImage` even `nil` when `frameImageRef` was valid).
|
||||||
|
if (frameImage) {
|
||||||
|
// Set poster image
|
||||||
|
if (!self.posterImage) {
|
||||||
|
_posterImage = frameImage;
|
||||||
|
// Set its size to proxy our size.
|
||||||
|
_size = _posterImage.size;
|
||||||
|
// Remember index of poster image so we never purge it; also add it to the cache.
|
||||||
|
_posterImageFrameIndex = i;
|
||||||
|
[self.cachedFramesForIndexes setObject:self.posterImage forKey:@(self.posterImageFrameIndex)];
|
||||||
|
[self.cachedFrameIndexes addIndex:self.posterImageFrameIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get `DelayTime`
|
||||||
|
// Note: It's not in (1/100) of a second like still falsely described in the documentation as per iOS 8 (rdar://19507384) but in seconds stored as `kCFNumberFloat32Type`.
|
||||||
|
// Frame properties example:
|
||||||
|
// {
|
||||||
|
// ColorModel = RGB;
|
||||||
|
// Depth = 8;
|
||||||
|
// PixelHeight = 960;
|
||||||
|
// PixelWidth = 640;
|
||||||
|
// "{GIF}" = {
|
||||||
|
// DelayTime = "0.4";
|
||||||
|
// UnclampedDelayTime = "0.4";
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
NSDictionary *_Nullable const frameProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(_imageSource, i, NULL);
|
||||||
|
NSDictionary *_Nullable const framePropertiesGIF = [frameProperties objectForKey:(id)kCGImagePropertyGIFDictionary];
|
||||||
|
|
||||||
|
// Try to use the unclamped delay time; fall back to the normal delay time.
|
||||||
|
NSNumber *_Nullable delayTime = [framePropertiesGIF objectForKey:(id)kCGImagePropertyGIFUnclampedDelayTime];
|
||||||
|
if (delayTime == nil) {
|
||||||
|
delayTime = [framePropertiesGIF objectForKey:(id)kCGImagePropertyGIFDelayTime];
|
||||||
|
}
|
||||||
|
// If we don't get a delay time from the properties, fall back to `kDelayTimeIntervalDefault` or carry over the preceding frame's value.
|
||||||
|
const NSTimeInterval kDelayTimeIntervalDefault = 0.1;
|
||||||
|
if (delayTime == nil) {
|
||||||
|
if (i == 0) {
|
||||||
|
FLLog(FLLogLevelInfo, @"Falling back to default delay time for first frame %@ because none found in GIF properties %@", frameImage, frameProperties);
|
||||||
|
delayTime = @(kDelayTimeIntervalDefault);
|
||||||
|
} else {
|
||||||
|
FLLog(FLLogLevelInfo, @"Falling back to preceding delay time for frame %zu %@ because none found in GIF properties %@", i, frameImage, frameProperties);
|
||||||
|
delayTime = delayTimesForIndexesMutable[@(i - 1)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Support frame delays as low as `kFLAnimatedImageDelayTimeIntervalMinimum`, with anything below being rounded up to `kDelayTimeIntervalDefault` for legacy compatibility.
|
||||||
|
// To support the minimum even when rounding errors occur, use an epsilon when comparing. We downcast to float because that's what we get for delayTime from ImageIO.
|
||||||
|
if ([delayTime floatValue] < ((float)kFLAnimatedImageDelayTimeIntervalMinimum - FLT_EPSILON)) {
|
||||||
|
FLLog(FLLogLevelInfo, @"Rounding frame %zu's `delayTime` from %f up to default %f (minimum supported: %f).", i, [delayTime floatValue], kDelayTimeIntervalDefault, kFLAnimatedImageDelayTimeIntervalMinimum);
|
||||||
|
delayTime = @(kDelayTimeIntervalDefault);
|
||||||
|
}
|
||||||
|
delayTimesForIndexesMutable[@(i)] = delayTime;
|
||||||
|
} else {
|
||||||
|
skippedFrameCount++;
|
||||||
|
FLLog(FLLogLevelInfo, @"Dropping frame %zu because valid `CGImageRef` %@ did result in `nil`-`UIImage`.", i, frameImageRef);
|
||||||
|
}
|
||||||
|
CFRelease(frameImageRef);
|
||||||
|
} else {
|
||||||
|
skippedFrameCount++;
|
||||||
|
FLLog(FLLogLevelInfo, @"Dropping frame %zu because failed to `CGImageSourceCreateImageAtIndex` with image source %@", i, self->_imageSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_delayTimesForIndexes = [delayTimesForIndexesMutable copy];
|
||||||
|
_frameCount = imageCount;
|
||||||
|
|
||||||
|
if (self.frameCount == 0) {
|
||||||
|
FLLog(FLLogLevelInfo, @"Failed to create any valid frames for GIF with properties %@", imageProperties);
|
||||||
|
return nil;
|
||||||
|
} else if (self.frameCount == 1) {
|
||||||
|
// Warn when we only have a single frame but return a valid GIF.
|
||||||
|
FLLog(FLLogLevelInfo, @"Created valid GIF but with only a single frame. Image properties: %@", imageProperties);
|
||||||
|
} else {
|
||||||
|
// We have multiple frames, rock on!
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no value is provided, select a default based on the GIF.
|
||||||
|
if (optimalFrameCacheSize == 0) {
|
||||||
|
// Calculate the optimal frame cache size: try choosing a larger buffer window depending on the predicted image size.
|
||||||
|
// It's only dependent on the image size & number of frames and never changes.
|
||||||
|
const CGFloat animatedImageDataSize = (CGFloat)CGImageGetBytesPerRow(self.posterImage.CGImage) * self.size.height * (CGFloat)(self.frameCount - skippedFrameCount) / (CGFloat)MEGABYTE;
|
||||||
|
if (animatedImageDataSize <= FLAnimatedImageDataSizeCategoryAll) {
|
||||||
|
_frameCacheSizeOptimal = self.frameCount;
|
||||||
|
} else if (animatedImageDataSize <= FLAnimatedImageDataSizeCategoryDefault) {
|
||||||
|
// This value doesn't depend on device memory much because if we're not keeping all frames in memory we will always be decoding 1 frame up ahead per 1 frame that gets played and at this point we might as well just keep a small buffer just large enough to keep from running out of frames.
|
||||||
|
_frameCacheSizeOptimal = FLAnimatedImageFrameCacheSizeDefault;
|
||||||
|
} else {
|
||||||
|
// The predicted size exceeds the limits to build up a cache and we go into low memory mode from the beginning.
|
||||||
|
_frameCacheSizeOptimal = FLAnimatedImageFrameCacheSizeLowMemory;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use the provided value.
|
||||||
|
_frameCacheSizeOptimal = optimalFrameCacheSize;
|
||||||
|
}
|
||||||
|
// In any case, cap the optimal cache size at the frame count.
|
||||||
|
_frameCacheSizeOptimal = MIN(_frameCacheSizeOptimal, self.frameCount);
|
||||||
|
|
||||||
|
// Convenience/minor performance optimization; keep an index set handy with the full range to return in `-frameIndexesToCache`.
|
||||||
|
_allFramesIndexSet = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, self.frameCount)];
|
||||||
|
|
||||||
|
// See the property declarations for descriptions.
|
||||||
|
_weakProxy = (id)[FLWeakProxy weakProxyForObject:self];
|
||||||
|
|
||||||
|
// Register this instance in the weak table for memory notifications. The NSHashTable will clean up after itself when we're gone.
|
||||||
|
// Note that FLAnimatedImages can be created on any thread, so the hash table must be locked.
|
||||||
|
@synchronized(allAnimatedImagesWeak) {
|
||||||
|
[allAnimatedImagesWeak addObject:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (instancetype)animatedImageWithGIFData:(NSData *)data
|
||||||
|
{
|
||||||
|
FLAnimatedImage *const animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:data];
|
||||||
|
return animatedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if (_weakProxy) {
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:_weakProxy];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_imageSource) {
|
||||||
|
CFRelease(_imageSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Public Methods
|
||||||
|
|
||||||
|
// See header for more details.
|
||||||
|
// Note: both consumer and producer are throttled: consumer by frame timings and producer by the available memory (max buffer window size).
|
||||||
|
- (UIImage *)imageLazilyCachedAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
// Early return if the requested index is beyond bounds.
|
||||||
|
// Note: We're comparing an index with a count and need to bail on greater than or equal to.
|
||||||
|
if (index >= self.frameCount) {
|
||||||
|
FLLog(FLLogLevelWarn, @"Skipping requested frame %lu beyond bounds (total frame count: %lu) for animated image: %@", (unsigned long)index, (unsigned long)self.frameCount, self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember requested frame index, this influences what we should cache next.
|
||||||
|
self.requestedFrameIndex = index;
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
if ([self.debug_delegate respondsToSelector:@selector(debug_animatedImage:didRequestCachedFrame:)]) {
|
||||||
|
[self.debug_delegate debug_animatedImage:self didRequestCachedFrame:index];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Quick check to avoid doing any work if we already have all possible frames cached, a common case.
|
||||||
|
if ([self.cachedFrameIndexes count] < self.frameCount) {
|
||||||
|
// If we have frames that should be cached but aren't and aren't requested yet, request them.
|
||||||
|
// Exclude existing cached frames, frames already requested, and specially cached poster image.
|
||||||
|
NSMutableIndexSet *frameIndexesToAddToCacheMutable = [self frameIndexesToCache];
|
||||||
|
[frameIndexesToAddToCacheMutable removeIndexes:self.cachedFrameIndexes];
|
||||||
|
[frameIndexesToAddToCacheMutable removeIndexes:self.requestedFrameIndexes];
|
||||||
|
[frameIndexesToAddToCacheMutable removeIndex:self.posterImageFrameIndex];
|
||||||
|
NSIndexSet *frameIndexesToAddToCache = [frameIndexesToAddToCacheMutable copy];
|
||||||
|
|
||||||
|
// Asynchronously add frames to our cache.
|
||||||
|
if ([frameIndexesToAddToCache count] > 0) {
|
||||||
|
[self addFrameIndexesToCache:frameIndexesToAddToCache];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the specified image.
|
||||||
|
UIImage *const image = self.cachedFramesForIndexes[@(index)];
|
||||||
|
|
||||||
|
// Purge if needed based on the current playhead position.
|
||||||
|
[self purgeFrameCacheIfNeeded];
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Only called once from `-imageLazilyCachedAtIndex` but factored into its own method for logical grouping.
|
||||||
|
- (void)addFrameIndexesToCache:(NSIndexSet *)frameIndexesToAddToCache
|
||||||
|
{
|
||||||
|
// Order matters. First, iterate over the indexes starting from the requested frame index.
|
||||||
|
// Then, if there are any indexes before the requested frame index, do those.
|
||||||
|
const NSRange firstRange = NSMakeRange(self.requestedFrameIndex, self.frameCount - self.requestedFrameIndex);
|
||||||
|
const NSRange secondRange = NSMakeRange(0, self.requestedFrameIndex);
|
||||||
|
if (firstRange.length + secondRange.length != self.frameCount) {
|
||||||
|
FLLog(FLLogLevelWarn, @"Two-part frame cache range doesn't equal full range.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the requested list before we actually kick them off, so they don't get into the queue twice.
|
||||||
|
[self.requestedFrameIndexes addIndexes:frameIndexesToAddToCache];
|
||||||
|
|
||||||
|
// Lazily create dedicated isolation queue.
|
||||||
|
if (!self.serialQueue) {
|
||||||
|
_serialQueue = dispatch_queue_create("com.flipboard.framecachingqueue", DISPATCH_QUEUE_SERIAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start streaming requested frames in the background into the cache.
|
||||||
|
// Avoid capturing self in the block as there's no reason to keep doing work if the animated image went away.
|
||||||
|
__weak __typeof(self) weakSelf = self;
|
||||||
|
dispatch_async(self.serialQueue, ^{
|
||||||
|
// Produce and cache next needed frame.
|
||||||
|
void (^frameRangeBlock)(NSRange, BOOL *) = ^(NSRange range, BOOL *stop) {
|
||||||
|
// Iterate through contiguous indexes; can be faster than `enumerateIndexesInRange:options:usingBlock:`.
|
||||||
|
for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
const CFTimeInterval predrawBeginTime = CACurrentMediaTime();
|
||||||
|
#endif
|
||||||
|
UIImage *const image = [weakSelf imageAtIndex:i];
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
const CFTimeInterval predrawDuration = CACurrentMediaTime() - predrawBeginTime;
|
||||||
|
CFTimeInterval slowdownDuration = 0.0;
|
||||||
|
if ([self.debug_delegate respondsToSelector:@selector(debug_animatedImagePredrawingSlowdownFactor:)]) {
|
||||||
|
CGFloat predrawingSlowdownFactor = [self.debug_delegate debug_animatedImagePredrawingSlowdownFactor:self];
|
||||||
|
slowdownDuration = predrawDuration * predrawingSlowdownFactor - predrawDuration;
|
||||||
|
[NSThread sleepForTimeInterval:slowdownDuration];
|
||||||
|
}
|
||||||
|
FLLog(FLLogLevelVerbose, @"Predrew frame %lu in %f ms for animated image: %@", (unsigned long)i, (predrawDuration + slowdownDuration) * 1000, self);
|
||||||
|
#endif
|
||||||
|
// The results get returned one by one as soon as they're ready (and not in batch).
|
||||||
|
// The benefits of having the first frames as quick as possible outweigh building up a buffer to cope with potential hiccups when the CPU suddenly gets busy.
|
||||||
|
if (image && weakSelf) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
weakSelf.cachedFramesForIndexes[@(i)] = image;
|
||||||
|
[weakSelf.cachedFrameIndexes addIndex:i];
|
||||||
|
[weakSelf.requestedFrameIndexes removeIndex:i];
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
if ([weakSelf.debug_delegate respondsToSelector:@selector(debug_animatedImage:didUpdateCachedFrames:)]) {
|
||||||
|
[weakSelf.debug_delegate debug_animatedImage:weakSelf didUpdateCachedFrames:weakSelf.cachedFrameIndexes];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[frameIndexesToAddToCache enumerateRangesInRange:firstRange options:0 usingBlock:frameRangeBlock];
|
||||||
|
[frameIndexesToAddToCache enumerateRangesInRange:secondRange options:0 usingBlock:frameRangeBlock];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (CGSize)sizeForImage:(id)image
|
||||||
|
{
|
||||||
|
CGSize imageSize = CGSizeZero;
|
||||||
|
|
||||||
|
// Early return for nil
|
||||||
|
if (!image) {
|
||||||
|
return imageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([image isKindOfClass:[UIImage class]]) {
|
||||||
|
UIImage *const uiImage = (UIImage *)image;
|
||||||
|
imageSize = uiImage.size;
|
||||||
|
} else if ([image isKindOfClass:[FLAnimatedImage class]]) {
|
||||||
|
FLAnimatedImage *const animatedImage = (FLAnimatedImage *)image;
|
||||||
|
imageSize = animatedImage.size;
|
||||||
|
} else {
|
||||||
|
// Bear trap to capture bad images; we have seen crashers cropping up on iOS 7.
|
||||||
|
FLLog(FLLogLevelError, @"`image` isn't of expected types `UIImage` or `FLAnimatedImage`: %@", image);
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Private Methods
|
||||||
|
#pragma mark Frame Loading
|
||||||
|
|
||||||
|
- (UIImage *)imageAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
// It's very important to use the cached `_imageSource` since the random access to a frame with `CGImageSourceCreateImageAtIndex` turns from an O(1) into an O(n) operation when re-initializing the image source every time.
|
||||||
|
const CGImageRef _Nullable imageRef = CGImageSourceCreateImageAtIndex(_imageSource, index, NULL);
|
||||||
|
|
||||||
|
// Early return for nil
|
||||||
|
if (!imageRef) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIImage *image = [UIImage imageWithCGImage:imageRef];
|
||||||
|
CFRelease(imageRef);
|
||||||
|
|
||||||
|
// Loading in the image object is only half the work, the displaying image view would still have to synchronosly wait and decode the image, so we go ahead and do that here on the background thread.
|
||||||
|
if (self.isPredrawingEnabled) {
|
||||||
|
image = [[self class] predrawnImageFromImage:image];
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Frame Caching
|
||||||
|
|
||||||
|
- (NSMutableIndexSet *)frameIndexesToCache
|
||||||
|
{
|
||||||
|
NSMutableIndexSet *indexesToCache = nil;
|
||||||
|
// Quick check to avoid building the index set if the number of frames to cache equals the total frame count.
|
||||||
|
if (self.frameCacheSizeCurrent == self.frameCount) {
|
||||||
|
indexesToCache = [self.allFramesIndexSet mutableCopy];
|
||||||
|
} else {
|
||||||
|
indexesToCache = [[NSMutableIndexSet alloc] init];
|
||||||
|
|
||||||
|
// Add indexes to the set in two separate blocks- the first starting from the requested frame index, up to the limit or the end.
|
||||||
|
// The second, if needed, the remaining number of frames beginning at index zero.
|
||||||
|
const NSUInteger firstLength = MIN(self.frameCacheSizeCurrent, self.frameCount - self.requestedFrameIndex);
|
||||||
|
const NSRange firstRange = NSMakeRange(self.requestedFrameIndex, firstLength);
|
||||||
|
[indexesToCache addIndexesInRange:firstRange];
|
||||||
|
const NSUInteger secondLength = self.frameCacheSizeCurrent - firstLength;
|
||||||
|
if (secondLength > 0) {
|
||||||
|
NSRange secondRange = NSMakeRange(0, secondLength);
|
||||||
|
[indexesToCache addIndexesInRange:secondRange];
|
||||||
|
}
|
||||||
|
// Double check our math, before we add the poster image index which may increase it by one.
|
||||||
|
if ([indexesToCache count] != self.frameCacheSizeCurrent) {
|
||||||
|
FLLog(FLLogLevelWarn, @"Number of frames to cache doesn't equal expected cache size.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[indexesToCache addIndex:self.posterImageFrameIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
return indexesToCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)purgeFrameCacheIfNeeded
|
||||||
|
{
|
||||||
|
// Purge frames that are currently cached but don't need to be.
|
||||||
|
// But not if we're still under the number of frames to cache.
|
||||||
|
// This way, if all frames are allowed to be cached (the common case), we can skip all the `NSIndexSet` math below.
|
||||||
|
if ([self.cachedFrameIndexes count] > self.frameCacheSizeCurrent) {
|
||||||
|
NSMutableIndexSet *indexesToPurge = [self.cachedFrameIndexes mutableCopy];
|
||||||
|
[indexesToPurge removeIndexes:[self frameIndexesToCache]];
|
||||||
|
[indexesToPurge enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
|
||||||
|
// Iterate through contiguous indexes; can be faster than `enumerateIndexesInRange:options:usingBlock:`.
|
||||||
|
for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
|
||||||
|
[self.cachedFrameIndexes removeIndex:i];
|
||||||
|
[self.cachedFramesForIndexes removeObjectForKey:@(i)];
|
||||||
|
// Note: Don't `CGImageSourceRemoveCacheAtIndex` on the image source for frames that we don't want cached any longer to maintain O(1) time access.
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
if ([self.debug_delegate respondsToSelector:@selector(debug_animatedImage:didUpdateCachedFrames:)]) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self.debug_delegate debug_animatedImage:self didUpdateCachedFrames:self.cachedFrameIndexes];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)growFrameCacheSizeAfterMemoryWarning:(NSNumber *)frameCacheSize
|
||||||
|
{
|
||||||
|
self.frameCacheSizeMaxInternal = [frameCacheSize unsignedIntegerValue];
|
||||||
|
FLLog(FLLogLevelDebug, @"Grew frame cache size max to %lu after memory warning for animated image: %@", (unsigned long)self.frameCacheSizeMaxInternal, self);
|
||||||
|
|
||||||
|
// Schedule resetting the frame cache size max completely after a while.
|
||||||
|
const NSTimeInterval kResetDelay = 3.0;
|
||||||
|
[self.weakProxy performSelector:@selector(resetFrameCacheSizeMaxInternal) withObject:nil afterDelay:kResetDelay];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)resetFrameCacheSizeMaxInternal
|
||||||
|
{
|
||||||
|
self.frameCacheSizeMaxInternal = FLAnimatedImageFrameCacheSizeNoLimit;
|
||||||
|
FLLog(FLLogLevelDebug, @"Reset frame cache size max (current frame cache size: %lu) for animated image: %@", (unsigned long)self.frameCacheSizeCurrent, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark System Memory Warnings Notification Handler
|
||||||
|
|
||||||
|
- (void)didReceiveMemoryWarning:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
self.memoryWarningCount++;
|
||||||
|
|
||||||
|
// If we were about to grow larger, but got rapped on our knuckles by the system again, cancel.
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self.weakProxy selector:@selector(growFrameCacheSizeAfterMemoryWarning:) object:@(FLAnimatedImageFrameCacheSizeGrowAfterMemoryWarning)];
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self.weakProxy selector:@selector(resetFrameCacheSizeMaxInternal) object:nil];
|
||||||
|
|
||||||
|
// Go down to the minimum and by that implicitly immediately purge from the cache if needed to not get jettisoned by the system and start producing frames on-demand.
|
||||||
|
FLLog(FLLogLevelDebug, @"Attempt setting frame cache size max to %lu (previous was %lu) after memory warning #%lu for animated image: %@", (unsigned long)FLAnimatedImageFrameCacheSizeLowMemory, (unsigned long)self.frameCacheSizeMaxInternal, (unsigned long)self.memoryWarningCount, self);
|
||||||
|
self.frameCacheSizeMaxInternal = FLAnimatedImageFrameCacheSizeLowMemory;
|
||||||
|
|
||||||
|
// Schedule growing larger again after a while, but cap our attempts to prevent a periodic sawtooth wave (ramps upward and then sharply drops) of memory usage.
|
||||||
|
//
|
||||||
|
// [mem]^ (2) (5) (6) 1) Loading frames for the first time
|
||||||
|
// (*)| , , , 2) Mem warning #1; purge cache
|
||||||
|
// | /| (4)/| /| 3) Grow cache size a bit after a while, if no mem warning occurs
|
||||||
|
// | / | _/ | _/ | 4) Try to grow cache size back to optimum after a while, if no mem warning occurs
|
||||||
|
// |(1)/ |_/ |/ |__(7) 5) Mem warning #2; purge cache
|
||||||
|
// |__/ (3) 6) After repetition of (3) and (4), mem warning #3; purge cache
|
||||||
|
// +----------------------> 7) After 3 mem warnings, stay at minimum cache size
|
||||||
|
// [t]
|
||||||
|
// *) The mem high water mark before we get warned might change for every cycle.
|
||||||
|
//
|
||||||
|
const NSUInteger kGrowAttemptsMax = 2;
|
||||||
|
const NSTimeInterval kGrowDelay = 2.0;
|
||||||
|
if ((self.memoryWarningCount - 1) <= kGrowAttemptsMax) {
|
||||||
|
[self.weakProxy performSelector:@selector(growFrameCacheSizeAfterMemoryWarning:) withObject:@(FLAnimatedImageFrameCacheSizeGrowAfterMemoryWarning) afterDelay:kGrowDelay];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: It's not possible to get the level of a memory warning with a public API: http://stackoverflow.com/questions/2915247/iphone-os-memory-warnings-what-do-the-different-levels-mean/2915477#2915477
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Image Decoding
|
||||||
|
|
||||||
|
// Decodes the image's data and draws it off-screen fully in memory; it's thread-safe and hence can be called on a background thread.
|
||||||
|
// On success, the returned object is a new `UIImage` instance with the same content as the one passed in.
|
||||||
|
// On failure, the returned object is the unchanged passed in one; the data will not be predrawn in memory though and an error will be logged.
|
||||||
|
// First inspired by & good Karma to: https://gist.github.com/steipete/1144242
|
||||||
|
+ (UIImage *)predrawnImageFromImage:(UIImage *)imageToPredraw
|
||||||
|
{
|
||||||
|
// Always use a device RGB color space for simplicity and predictability what will be going on.
|
||||||
|
const CGColorSpaceRef _Nullable colorSpaceDeviceRGBRef = CGColorSpaceCreateDeviceRGB();
|
||||||
|
// Early return on failure!
|
||||||
|
if (!colorSpaceDeviceRGBRef) {
|
||||||
|
FLLog(FLLogLevelError, @"Failed to `CGColorSpaceCreateDeviceRGB` for image %@", imageToPredraw);
|
||||||
|
return imageToPredraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Even when the image doesn't have transparency, we have to add the extra channel because Quartz doesn't support other pixel formats than 32 bpp/8 bpc for RGB:
|
||||||
|
// kCGImageAlphaNoneSkipFirst, kCGImageAlphaNoneSkipLast, kCGImageAlphaPremultipliedFirst, kCGImageAlphaPremultipliedLast
|
||||||
|
// (source: docs "Quartz 2D Programming Guide > Graphics Contexts > Table 2-1 Pixel formats supported for bitmap graphics contexts")
|
||||||
|
const size_t numberOfComponents = CGColorSpaceGetNumberOfComponents(colorSpaceDeviceRGBRef) + 1; // 4: RGB + A
|
||||||
|
|
||||||
|
// "In iOS 4.0 and later, and OS X v10.6 and later, you can pass NULL if you want Quartz to allocate memory for the bitmap." (source: docs)
|
||||||
|
void *_Nullable data = NULL;
|
||||||
|
const size_t width = imageToPredraw.size.width;
|
||||||
|
const size_t height = imageToPredraw.size.height;
|
||||||
|
const size_t bitsPerComponent = CHAR_BIT;
|
||||||
|
|
||||||
|
const size_t bitsPerPixel = (bitsPerComponent * numberOfComponents);
|
||||||
|
const size_t bytesPerPixel = (bitsPerPixel / BYTE_SIZE);
|
||||||
|
const size_t bytesPerRow = (bytesPerPixel * width);
|
||||||
|
|
||||||
|
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
|
||||||
|
|
||||||
|
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageToPredraw.CGImage);
|
||||||
|
// If the alpha info doesn't match to one of the supported formats (see above), pick a reasonable supported one.
|
||||||
|
// "For bitmaps created in iOS 3.2 and later, the drawing environment uses the premultiplied ARGB format to store the bitmap data." (source: docs)
|
||||||
|
if (alphaInfo == kCGImageAlphaNone || alphaInfo == kCGImageAlphaOnly) {
|
||||||
|
alphaInfo = kCGImageAlphaNoneSkipFirst;
|
||||||
|
} else if (alphaInfo == kCGImageAlphaFirst) {
|
||||||
|
alphaInfo = kCGImageAlphaPremultipliedFirst;
|
||||||
|
} else if (alphaInfo == kCGImageAlphaLast) {
|
||||||
|
alphaInfo = kCGImageAlphaPremultipliedLast;
|
||||||
|
}
|
||||||
|
// "The constants for specifying the alpha channel information are declared with the `CGImageAlphaInfo` type but can be passed to this parameter safely." (source: docs)
|
||||||
|
bitmapInfo |= alphaInfo;
|
||||||
|
|
||||||
|
// Create our own graphics context to draw to; `UIGraphicsGetCurrentContext`/`UIGraphicsBeginImageContextWithOptions` doesn't create a new context but returns the current one which isn't thread-safe (e.g. main thread could use it at the same time).
|
||||||
|
// Note: It's not worth caching the bitmap context for multiple frames ("unique key" would be `width`, `height` and `hasAlpha`), it's ~50% slower. Time spent in libRIP's `CGSBlendBGRA8888toARGB8888` suddenly shoots up -- not sure why.
|
||||||
|
const CGContextRef _Nullable bitmapContextRef = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorSpaceDeviceRGBRef, bitmapInfo);
|
||||||
|
CGColorSpaceRelease(colorSpaceDeviceRGBRef);
|
||||||
|
// Early return on failure!
|
||||||
|
if (!bitmapContextRef) {
|
||||||
|
FLLog(FLLogLevelError, @"Failed to `CGBitmapContextCreate` with color space %@ and parameters (width: %zu height: %zu bitsPerComponent: %zu bytesPerRow: %zu) for image %@", colorSpaceDeviceRGBRef, width, height, bitsPerComponent, bytesPerRow, imageToPredraw);
|
||||||
|
return imageToPredraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw image in bitmap context and create image by preserving receiver's properties.
|
||||||
|
CGContextDrawImage(bitmapContextRef, CGRectMake(0.0, 0.0, imageToPredraw.size.width, imageToPredraw.size.height), imageToPredraw.CGImage);
|
||||||
|
const CGImageRef _Nullable predrawnImageRef = CGBitmapContextCreateImage(bitmapContextRef);
|
||||||
|
UIImage *_Nullable predrawnImage = predrawnImageRef ? [UIImage imageWithCGImage:predrawnImageRef scale:imageToPredraw.scale orientation:imageToPredraw.imageOrientation] : nil;
|
||||||
|
CGImageRelease(predrawnImageRef);
|
||||||
|
CGContextRelease(bitmapContextRef);
|
||||||
|
|
||||||
|
// Early return on failure!
|
||||||
|
if (!predrawnImage) {
|
||||||
|
FLLog(FLLogLevelError, @"Failed to `imageWithCGImage:scale:orientation:` with image ref %@ created with color space %@ and bitmap context %@ and properties and properties (scale: %f orientation: %ld) for image %@", predrawnImageRef, colorSpaceDeviceRGBRef, bitmapContextRef, imageToPredraw.scale, (long)imageToPredraw.imageOrientation, imageToPredraw);
|
||||||
|
return imageToPredraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return predrawnImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Description
|
||||||
|
|
||||||
|
- (NSString *)description
|
||||||
|
{
|
||||||
|
NSString *description = [super description];
|
||||||
|
|
||||||
|
description = [description stringByAppendingFormat:@" size=%@", NSStringFromCGSize(self.size)];
|
||||||
|
description = [description stringByAppendingFormat:@" frameCount=%lu", (unsigned long)self.frameCount];
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - Logging
|
||||||
|
|
||||||
|
@implementation FLAnimatedImage (Logging)
|
||||||
|
|
||||||
|
static void (^_logBlock)(NSString *logString, FLLogLevel logLevel) = nil;
|
||||||
|
static FLLogLevel _logLevel;
|
||||||
|
|
||||||
|
+ (void)setLogBlock:(void (^_Nullable)(NSString *logString, FLLogLevel logLevel))logBlock logLevel:(FLLogLevel)logLevel
|
||||||
|
{
|
||||||
|
_logBlock = [logBlock copy];
|
||||||
|
_logLevel = logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)logStringFromBlock:(NSString *(^_Nullable)(void))stringBlock withLevel:(FLLogLevel)level
|
||||||
|
{
|
||||||
|
if (level <= _logLevel && _logBlock && stringBlock) {
|
||||||
|
_logBlock(stringBlock(), level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - FLWeakProxy
|
||||||
|
|
||||||
|
@interface FLWeakProxy ()
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id target;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation FLWeakProxy
|
||||||
|
|
||||||
|
#pragma mark Life Cycle
|
||||||
|
|
||||||
|
// This is the designated creation method of an `FLWeakProxy` and
|
||||||
|
// as a subclass of `NSProxy` it doesn't respond to or need `-init`.
|
||||||
|
+ (instancetype)weakProxyForObject:(id)targetObject
|
||||||
|
{
|
||||||
|
FLWeakProxy *weakProxy = [FLWeakProxy alloc];
|
||||||
|
weakProxy.target = targetObject;
|
||||||
|
return weakProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Forwarding Messages
|
||||||
|
|
||||||
|
- (id)forwardingTargetForSelector:(SEL)selector
|
||||||
|
{
|
||||||
|
// Keep it lightweight: access the ivar directly
|
||||||
|
return _target;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - NSWeakProxy Method Overrides
|
||||||
|
#pragma mark Handling Unimplemented Methods
|
||||||
|
|
||||||
|
- (void)forwardInvocation:(NSInvocation *)invocation
|
||||||
|
{
|
||||||
|
// Fallback for when target is nil. Don't do anything, just return 0/NULL/nil.
|
||||||
|
// The method signature we've received to get here is just a dummy to keep `doesNotRecognizeSelector:` from firing.
|
||||||
|
// We can't really handle struct return types here because we don't know the length.
|
||||||
|
void *_Nullable nullPointer = NULL;
|
||||||
|
[invocation setReturnValue:&nullPointer];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
|
||||||
|
{
|
||||||
|
// We only get here if `forwardingTargetForSelector:` returns nil.
|
||||||
|
// In that case, our weak target has been reclaimed. Return a dummy method signature to keep `doesNotRecognizeSelector:` from firing.
|
||||||
|
// We'll emulate the Obj-c messaging nil behavior by setting the return value to nil in `forwardInvocation:`, but we'll assume that the return value is `sizeof(void *)`.
|
||||||
|
// Other libraries handle this situation by making use of a global method signature cache, but that seems heavier than necessary and has issues as well.
|
||||||
|
// See https://www.mikeash.com/pyblog/friday-qa-2010-02-26-futures.html and https://github.com/steipete/PSTDelegateProxy/issues/1 for examples of using a method signature cache.
|
||||||
|
return [NSObject instanceMethodSignatureForSelector:@selector(init)];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
460
Pods/FLAnimatedImage/FLAnimatedImage/FLAnimatedImageView.m
generated
Executable file
@@ -0,0 +1,460 @@
|
|||||||
|
//
|
||||||
|
// FLAnimatedImageView.h
|
||||||
|
// Flipboard
|
||||||
|
//
|
||||||
|
// Created by Raphael Schaad on 7/8/13.
|
||||||
|
// Copyright (c) Flipboard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#import "FLAnimatedImageView.h"
|
||||||
|
#import "FLAnimatedImage.h"
|
||||||
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
@protocol FLAnimatedImageViewDebugDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
- (void)debug_animatedImageView:(FLAnimatedImageView *)animatedImageView waitingForFrame:(NSUInteger)index duration:(NSTimeInterval)duration;
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@interface FLAnimatedImageView ()
|
||||||
|
|
||||||
|
// Override of public `readonly` properties as private `readwrite`
|
||||||
|
@property (nonatomic, strong, readwrite) UIImage *currentFrame;
|
||||||
|
@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) NSUInteger loopCountdown;
|
||||||
|
@property (nonatomic, assign) NSTimeInterval accumulator;
|
||||||
|
@property (nonatomic, strong) CADisplayLink *displayLink;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL shouldAnimate; // Before checking this value, call `-updateShouldAnimate` whenever the animated image or visibility (window, superview, hidden, alpha) has changed.
|
||||||
|
@property (nonatomic, assign) BOOL needsDisplayWhenImageBecomesAvailable;
|
||||||
|
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
@property (nonatomic, weak) id<FLAnimatedImageViewDebugDelegate> debug_delegate;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation FLAnimatedImageView
|
||||||
|
@synthesize runLoopMode = _runLoopMode;
|
||||||
|
|
||||||
|
#pragma mark - Initializers
|
||||||
|
|
||||||
|
// -initWithImage: isn't documented as a designated initializer of UIImageView, but it actually seems to be.
|
||||||
|
// Using -initWithImage: doesn't call any of the other designated initializers.
|
||||||
|
- (instancetype)initWithImage:(UIImage *)image
|
||||||
|
{
|
||||||
|
self = [super initWithImage:image];
|
||||||
|
if (self) {
|
||||||
|
[self commonInit];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -initWithImage:highlightedImage: also isn't documented as a designated initializer of UIImageView, but it doesn't call any other designated initializers.
|
||||||
|
- (instancetype)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage
|
||||||
|
{
|
||||||
|
self = [super initWithImage:image highlightedImage:highlightedImage];
|
||||||
|
if (self) {
|
||||||
|
[self commonInit];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
self = [super initWithFrame:frame];
|
||||||
|
if (self) {
|
||||||
|
[self commonInit];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithCoder:(NSCoder *)aDecoder
|
||||||
|
{
|
||||||
|
self = [super initWithCoder:aDecoder];
|
||||||
|
if (self) {
|
||||||
|
[self commonInit];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)commonInit
|
||||||
|
{
|
||||||
|
self.runLoopMode = [[self class] defaultRunLoopMode];
|
||||||
|
|
||||||
|
if (@available(iOS 11.0, *)) {
|
||||||
|
self.accessibilityIgnoresInvertColors = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Accessors
|
||||||
|
#pragma mark Public
|
||||||
|
|
||||||
|
- (void)setAnimatedImage:(FLAnimatedImage *)animatedImage
|
||||||
|
{
|
||||||
|
if (![_animatedImage isEqual:animatedImage]) {
|
||||||
|
if (animatedImage) {
|
||||||
|
if (super.image) {
|
||||||
|
// UIImageView's `setImage:` will internally call its layer's `setContentsTransform:` based on the `image.imageOrientation`.
|
||||||
|
// The `contentsTransform` will affect layer rendering rotation because the CGImage's bitmap buffer does not actually take rotation.
|
||||||
|
// However, when calling `setImage:nil`, this `contentsTransform` will not be reset to identity.
|
||||||
|
// Further animation frame will be rendered as rotated. So we must set it to the poster image to clear the previous state.
|
||||||
|
// See more here: https://github.com/Flipboard/FLAnimatedImage/issues/100
|
||||||
|
super.image = animatedImage.posterImage;
|
||||||
|
// Clear out the image.
|
||||||
|
super.image = nil;
|
||||||
|
}
|
||||||
|
// Ensure disabled highlighting; it's not supported (see `-setHighlighted:`).
|
||||||
|
super.highlighted = NO;
|
||||||
|
// UIImageView seems to bypass some accessors when calculating its intrinsic content size, so this ensures its intrinsic content size comes from the animated image.
|
||||||
|
[self invalidateIntrinsicContentSize];
|
||||||
|
} else {
|
||||||
|
// Stop animating before the animated image gets cleared out.
|
||||||
|
[self stopAnimating];
|
||||||
|
}
|
||||||
|
|
||||||
|
_animatedImage = animatedImage;
|
||||||
|
|
||||||
|
self.currentFrame = animatedImage.posterImage;
|
||||||
|
self.currentFrameIndex = 0;
|
||||||
|
if (animatedImage.loopCount > 0) {
|
||||||
|
self.loopCountdown = animatedImage.loopCount;
|
||||||
|
} else {
|
||||||
|
self.loopCountdown = NSUIntegerMax;
|
||||||
|
}
|
||||||
|
self.accumulator = 0.0;
|
||||||
|
|
||||||
|
// Start animating after the new animated image has been set.
|
||||||
|
[self updateShouldAnimate];
|
||||||
|
if (self.shouldAnimate) {
|
||||||
|
[self startAnimating];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.layer setNeedsDisplay];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Life Cycle
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
// Removes the display link from all run loop modes.
|
||||||
|
[_displayLink invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - UIView Method Overrides
|
||||||
|
#pragma mark Observing View-Related Changes
|
||||||
|
|
||||||
|
- (void)didMoveToSuperview
|
||||||
|
{
|
||||||
|
[super didMoveToSuperview];
|
||||||
|
|
||||||
|
[self updateShouldAnimate];
|
||||||
|
if (self.shouldAnimate) {
|
||||||
|
[self startAnimating];
|
||||||
|
} else {
|
||||||
|
[self stopAnimating];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)didMoveToWindow
|
||||||
|
{
|
||||||
|
[super didMoveToWindow];
|
||||||
|
|
||||||
|
[self updateShouldAnimate];
|
||||||
|
if (self.shouldAnimate) {
|
||||||
|
[self startAnimating];
|
||||||
|
} else {
|
||||||
|
[self stopAnimating];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAlpha:(CGFloat)alpha
|
||||||
|
{
|
||||||
|
[super setAlpha:alpha];
|
||||||
|
|
||||||
|
[self updateShouldAnimate];
|
||||||
|
if (self.shouldAnimate) {
|
||||||
|
[self startAnimating];
|
||||||
|
} else {
|
||||||
|
[self stopAnimating];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setHidden:(BOOL)hidden
|
||||||
|
{
|
||||||
|
[super setHidden:hidden];
|
||||||
|
|
||||||
|
[self updateShouldAnimate];
|
||||||
|
if (self.shouldAnimate) {
|
||||||
|
[self startAnimating];
|
||||||
|
} else {
|
||||||
|
[self stopAnimating];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Auto Layout
|
||||||
|
|
||||||
|
- (CGSize)intrinsicContentSize
|
||||||
|
{
|
||||||
|
// Default to let UIImageView handle the sizing of its image, and anything else it might consider.
|
||||||
|
CGSize intrinsicContentSize = [super intrinsicContentSize];
|
||||||
|
|
||||||
|
// If we have have an animated image, use its image size.
|
||||||
|
// UIImageView's intrinsic content size seems to be the size of its image. The obvious approach, simply calling `-invalidateIntrinsicContentSize` when setting an animated image, results in UIImageView steadfastly returning `{UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric}` for its intrinsicContentSize.
|
||||||
|
// (Perhaps UIImageView bypasses its `-image` getter in its implementation of `-intrinsicContentSize`, as `-image` is not called after calling `-invalidateIntrinsicContentSize`.)
|
||||||
|
if (self.animatedImage) {
|
||||||
|
intrinsicContentSize = self.image.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return intrinsicContentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - UIImageView Method Overrides
|
||||||
|
#pragma mark Image Data
|
||||||
|
|
||||||
|
- (UIImage *)image
|
||||||
|
{
|
||||||
|
UIImage *image = nil;
|
||||||
|
if (self.animatedImage) {
|
||||||
|
// Initially set to the poster image.
|
||||||
|
image = self.currentFrame;
|
||||||
|
} else {
|
||||||
|
image = super.image;
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)setImage:(UIImage *)image
|
||||||
|
{
|
||||||
|
if (image) {
|
||||||
|
// Clear out the animated image and implicitly pause animation playback.
|
||||||
|
self.animatedImage = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Animating Images
|
||||||
|
|
||||||
|
- (NSTimeInterval)frameDelayGreatestCommonDivisor
|
||||||
|
{
|
||||||
|
// Presision is set to half of the `kFLAnimatedImageDelayTimeIntervalMinimum` in order to minimize frame dropping.
|
||||||
|
const NSTimeInterval kGreatestCommonDivisorPrecision = 2.0 / kFLAnimatedImageDelayTimeIntervalMinimum;
|
||||||
|
|
||||||
|
NSArray *const delays = self.animatedImage.delayTimesForIndexes.allValues;
|
||||||
|
|
||||||
|
// Scales the frame delays by `kGreatestCommonDivisorPrecision`
|
||||||
|
// then converts it to an UInteger for in order to calculate the GCD.
|
||||||
|
NSUInteger scaledGCD = lrint([delays.firstObject floatValue] * kGreatestCommonDivisorPrecision);
|
||||||
|
for (NSNumber *value in delays) {
|
||||||
|
scaledGCD = gcd(lrint([value floatValue] * kGreatestCommonDivisorPrecision), scaledGCD);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse to scale to get the value back into seconds.
|
||||||
|
return (double)scaledGCD / kGreatestCommonDivisorPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NSUInteger gcd(NSUInteger a, NSUInteger b)
|
||||||
|
{
|
||||||
|
// http://en.wikipedia.org/wiki/Greatest_common_divisor
|
||||||
|
if (a < b) {
|
||||||
|
return gcd(b, a);
|
||||||
|
} else if (a == b) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const NSUInteger remainder = a % b;
|
||||||
|
if (remainder == 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
a = b;
|
||||||
|
b = remainder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)startAnimating
|
||||||
|
{
|
||||||
|
if (self.animatedImage) {
|
||||||
|
// Lazily create the display link.
|
||||||
|
if (!self.displayLink) {
|
||||||
|
// It is important to note the use of a weak proxy here to avoid a retain cycle. `-displayLinkWithTarget:selector:`
|
||||||
|
// will retain its target until it is invalidated. We use a weak proxy so that the image view will get deallocated
|
||||||
|
// independent of the display link's lifetime. Upon image view deallocation, we invalidate the display
|
||||||
|
// link which will lead to the deallocation of both the display link and the weak proxy.
|
||||||
|
FLWeakProxy *weakProxy = [FLWeakProxy weakProxyForObject:self];
|
||||||
|
self.displayLink = [CADisplayLink displayLinkWithTarget:weakProxy selector:@selector(displayDidRefresh:)];
|
||||||
|
|
||||||
|
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:self.runLoopMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 10, *)) {
|
||||||
|
// Adjusting preferredFramesPerSecond allows us to skip unnecessary calls to displayDidRefresh: when showing GIFs
|
||||||
|
// that don't animate quickly. Use ceil to err on the side of too many FPS so we don't miss a frame transition moment.
|
||||||
|
self.displayLink.preferredFramesPerSecond = ceil(1.0 / [self frameDelayGreatestCommonDivisor]);
|
||||||
|
} else {
|
||||||
|
const NSTimeInterval kDisplayRefreshRate = 60.0; // 60Hz
|
||||||
|
self.displayLink.frameInterval = MAX([self frameDelayGreatestCommonDivisor] * kDisplayRefreshRate, 1);
|
||||||
|
}
|
||||||
|
self.displayLink.paused = NO;
|
||||||
|
} else {
|
||||||
|
[super startAnimating];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode
|
||||||
|
{
|
||||||
|
if (![@[NSDefaultRunLoopMode, NSRunLoopCommonModes] containsObject:runLoopMode]) {
|
||||||
|
NSAssert(NO, @"Invalid run loop mode: %@", runLoopMode);
|
||||||
|
_runLoopMode = [[self class] defaultRunLoopMode];
|
||||||
|
} else {
|
||||||
|
_runLoopMode = runLoopMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopAnimating
|
||||||
|
{
|
||||||
|
if (self.animatedImage) {
|
||||||
|
self.displayLink.paused = YES;
|
||||||
|
} else {
|
||||||
|
[super stopAnimating];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (BOOL)isAnimating
|
||||||
|
{
|
||||||
|
BOOL isAnimating = NO;
|
||||||
|
if (self.animatedImage) {
|
||||||
|
isAnimating = self.displayLink && !self.displayLink.isPaused;
|
||||||
|
} else {
|
||||||
|
isAnimating = [super isAnimating];
|
||||||
|
}
|
||||||
|
return isAnimating;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Highlighted Image Unsupport
|
||||||
|
|
||||||
|
- (void)setHighlighted:(BOOL)highlighted
|
||||||
|
{
|
||||||
|
// Highlighted image is unsupported for animated images, but implementing it breaks the image view when embedded in a UICollectionViewCell.
|
||||||
|
if (!self.animatedImage) {
|
||||||
|
[super setHighlighted:highlighted];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Private Methods
|
||||||
|
#pragma mark Animation
|
||||||
|
|
||||||
|
// Don't repeatedly check our window & superview in `-displayDidRefresh:` for performance reasons.
|
||||||
|
// Just update our cached value whenever the animated image or visibility (window, superview, hidden, alpha) is changed.
|
||||||
|
- (void)updateShouldAnimate
|
||||||
|
{
|
||||||
|
const BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alpha > 0.0;
|
||||||
|
self.shouldAnimate = self.animatedImage && isVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)displayDidRefresh:(CADisplayLink *)displayLink
|
||||||
|
{
|
||||||
|
// If for some reason a wild call makes it through when we shouldn't be animating, bail.
|
||||||
|
// Early return!
|
||||||
|
if (!self.shouldAnimate) {
|
||||||
|
FLLog(FLLogLevelWarn, @"Trying to animate image when we shouldn't: %@", self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSNumber *_Nullable const delayTimeNumber = [self.animatedImage.delayTimesForIndexes objectForKey:@(self.currentFrameIndex)];
|
||||||
|
// If we don't have a frame delay (e.g. corrupt frame), don't update the view but skip the playhead to the next frame (in else-block).
|
||||||
|
if (delayTimeNumber != nil) {
|
||||||
|
const NSTimeInterval delayTime = [delayTimeNumber floatValue];
|
||||||
|
// If we have a nil image (e.g. waiting for frame), don't update the view nor playhead.
|
||||||
|
UIImage *_Nullable const image = [self.animatedImage imageLazilyCachedAtIndex:self.currentFrameIndex];
|
||||||
|
if (image) {
|
||||||
|
FLLog(FLLogLevelVerbose, @"Showing frame %lu for animated image: %@", (unsigned long)self.currentFrameIndex, self.animatedImage);
|
||||||
|
self.currentFrame = image;
|
||||||
|
if (self.needsDisplayWhenImageBecomesAvailable) {
|
||||||
|
[self.layer setNeedsDisplay];
|
||||||
|
self.needsDisplayWhenImageBecomesAvailable = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 10, *)) {
|
||||||
|
self.accumulator += displayLink.targetTimestamp - CACurrentMediaTime();
|
||||||
|
} else {
|
||||||
|
self.accumulator += displayLink.duration * (NSTimeInterval)displayLink.frameInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// While-loop first inspired by & good Karma to: https://github.com/ondalabs/OLImageView/blob/master/OLImageView.m
|
||||||
|
while (self.accumulator >= delayTime) {
|
||||||
|
self.accumulator -= delayTime;
|
||||||
|
self.currentFrameIndex++;
|
||||||
|
if (self.currentFrameIndex >= self.animatedImage.frameCount) {
|
||||||
|
// If we've looped the number of times that this animated image describes, stop looping.
|
||||||
|
self.loopCountdown--;
|
||||||
|
if (self.loopCompletionBlock) {
|
||||||
|
self.loopCompletionBlock(self.loopCountdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.loopCountdown == 0) {
|
||||||
|
[self stopAnimating];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.currentFrameIndex = 0;
|
||||||
|
}
|
||||||
|
// Calling `-setNeedsDisplay` will just paint the current frame, not the new frame that we may have moved to.
|
||||||
|
// Instead, set `needsDisplayWhenImageBecomesAvailable` to `YES` -- this will paint the new image once loaded.
|
||||||
|
self.needsDisplayWhenImageBecomesAvailable = YES;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FLLog(FLLogLevelDebug, @"Waiting for frame %lu for animated image: %@", (unsigned long)self.currentFrameIndex, self.animatedImage);
|
||||||
|
#if defined(DEBUG) && DEBUG
|
||||||
|
if ([self.debug_delegate respondsToSelector:@selector(debug_animatedImageView:waitingForFrame:duration:)]) {
|
||||||
|
if (@available(iOS 10, *)) {
|
||||||
|
[self.debug_delegate debug_animatedImageView:self waitingForFrame:self.currentFrameIndex duration:displayLink.targetTimestamp - CACurrentMediaTime()];
|
||||||
|
} else {
|
||||||
|
[self.debug_delegate debug_animatedImageView:self waitingForFrame:self.currentFrameIndex duration:displayLink.duration * (NSTimeInterval)displayLink.frameInterval];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.currentFrameIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSRunLoopMode)defaultRunLoopMode
|
||||||
|
{
|
||||||
|
// Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations.
|
||||||
|
return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - CALayerDelegate (Informal)
|
||||||
|
#pragma mark Providing the Layer's Content
|
||||||
|
|
||||||
|
- (void)displayLayer:(CALayer *)layer
|
||||||
|
{
|
||||||
|
layer.contents = (__bridge id)self.image.CGImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
83
Pods/FLAnimatedImage/FLAnimatedImage/include/FLAnimatedImage.h
generated
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// FLAnimatedImage.h
|
||||||
|
// Flipboard
|
||||||
|
//
|
||||||
|
// Created by Raphael Schaad on 7/8/13.
|
||||||
|
// Copyright (c) Flipboard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
// Allow user classes conveniently just importing one header.
|
||||||
|
#import "FLAnimatedImageView.h"
|
||||||
|
|
||||||
|
#ifndef NS_DESIGNATED_INITIALIZER
|
||||||
|
#if __has_attribute(objc_designated_initializer)
|
||||||
|
#define NS_DESIGNATED_INITIALIZER __attribute((objc_designated_initializer))
|
||||||
|
#else
|
||||||
|
#define NS_DESIGNATED_INITIALIZER
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const NSTimeInterval kFLAnimatedImageDelayTimeIntervalMinimum;
|
||||||
|
|
||||||
|
//
|
||||||
|
// An `FLAnimatedImage`'s job is to deliver frames in a highly performant way and works in conjunction with `FLAnimatedImageView`.
|
||||||
|
// It subclasses `NSObject` and not `UIImage` because it's only an "image" in the sense that a sea lion is a lion.
|
||||||
|
// It tries to intelligently choose the frame cache size depending on the image and memory situation with the goal to lower CPU usage for smaller ones, lower memory usage for larger ones and always deliver frames for high performant play-back.
|
||||||
|
// Note: `posterImage`, `size`, `loopCount`, `delayTimes` and `frameCount` don't change after successful initialization.
|
||||||
|
//
|
||||||
|
@interface FLAnimatedImage : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) UIImage *posterImage; // Guaranteed to be loaded; usually equivalent to `-imageLazilyCachedAtIndex:0`
|
||||||
|
@property (nonatomic, assign, readonly) CGSize size; // The `.posterImage`'s `.size`
|
||||||
|
|
||||||
|
@property (nonatomic, assign, readonly) NSUInteger loopCount; // "The number of times to repeat an animated sequence." according to ImageIO (note the slightly different definition to Netscape 2.0 Loop Extension); 0 means repeating the animation forever
|
||||||
|
@property (nonatomic, strong, readonly) NSDictionary *delayTimesForIndexes; // Of type `NSTimeInterval` boxed in `NSNumber`s
|
||||||
|
@property (nonatomic, assign, readonly) NSUInteger frameCount; // Number of valid frames; equal to `[.delayTimes count]`
|
||||||
|
|
||||||
|
@property (nonatomic, assign, readonly) NSUInteger frameCacheSizeCurrent; // Current size of intelligently chosen buffer window; can range in the interval [1..frameCount]
|
||||||
|
@property (nonatomic, assign) NSUInteger frameCacheSizeMax; // Allow to cap the cache size; 0 means no specific limit (default)
|
||||||
|
|
||||||
|
// Intended to be called from main thread synchronously; will return immediately.
|
||||||
|
// If the result isn't cached, will return `nil`; the caller should then pause playback, not increment frame counter and keep polling.
|
||||||
|
// After an initial loading time, depending on `frameCacheSize`, frames should be available immediately from the cache.
|
||||||
|
- (UIImage *)imageLazilyCachedAtIndex:(NSUInteger)index;
|
||||||
|
|
||||||
|
// Pass either a `UIImage` or an `FLAnimatedImage` and get back its size
|
||||||
|
+ (CGSize)sizeForImage:(id)image;
|
||||||
|
|
||||||
|
// On success, the initializers return an `FLAnimatedImage` with all fields initialized, on failure they return `nil` and an error will be logged.
|
||||||
|
- (instancetype)initWithAnimatedGIFData:(NSData *)data;
|
||||||
|
// Pass 0 for optimalFrameCacheSize to get the default, predrawing is enabled by default.
|
||||||
|
- (instancetype)initWithAnimatedGIFData:(NSData *)data optimalFrameCacheSize:(NSUInteger)optimalFrameCacheSize predrawingEnabled:(BOOL)isPredrawingEnabled NS_DESIGNATED_INITIALIZER;
|
||||||
|
+ (instancetype)animatedImageWithGIFData:(NSData *)data;
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) NSData *data; // The data the receiver was initialized with; read-only
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, FLLogLevel) {
|
||||||
|
FLLogLevelNone = 0,
|
||||||
|
FLLogLevelError,
|
||||||
|
FLLogLevelWarn,
|
||||||
|
FLLogLevelInfo,
|
||||||
|
FLLogLevelDebug,
|
||||||
|
FLLogLevelVerbose
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface FLAnimatedImage (Logging)
|
||||||
|
|
||||||
|
+ (void)setLogBlock:(void (^)(NSString *logString, FLLogLevel logLevel))logBlock logLevel:(FLLogLevel)logLevel;
|
||||||
|
+ (void)logStringFromBlock:(NSString *(^)(void))stringBlock withLevel:(FLLogLevel)level;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#define FLLog(logLevel, format, ...) [FLAnimatedImage logStringFromBlock:^NSString *{ return [NSString stringWithFormat:(format), ## __VA_ARGS__]; } withLevel:(logLevel)]
|
||||||
|
|
||||||
|
@interface FLWeakProxy : NSProxy
|
||||||
|
|
||||||
|
+ (instancetype)weakProxyForObject:(id)targetObject;
|
||||||
|
|
||||||
|
@end
|
||||||
36
Pods/FLAnimatedImage/FLAnimatedImage/include/FLAnimatedImageView.h
generated
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// FLAnimatedImageView.h
|
||||||
|
// Flipboard
|
||||||
|
//
|
||||||
|
// Created by Raphael Schaad on 7/8/13.
|
||||||
|
// Copyright (c) Flipboard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@class FLAnimatedImage;
|
||||||
|
@protocol FLAnimatedImageViewDebugDelegate;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// An `FLAnimatedImageView` can take an `FLAnimatedImage` and plays it automatically when in view hierarchy and stops when removed.
|
||||||
|
// The animation can also be controlled with the `UIImageView` methods `-start/stop/isAnimating`.
|
||||||
|
// It is a fully compatible `UIImageView` subclass and can be used as a drop-in component to work with existing code paths expecting to display a `UIImage`.
|
||||||
|
// Under the hood it uses a `CADisplayLink` for playback, which can be inspected with `currentFrame` & `currentFrameIndex`.
|
||||||
|
//
|
||||||
|
@interface FLAnimatedImageView : UIImageView
|
||||||
|
|
||||||
|
// Setting `[UIImageView.image]` to a non-`nil` value clears out existing `animatedImage`.
|
||||||
|
// And vice versa, setting `animatedImage` will initially populate the `[UIImageView.image]` to its `posterImage` and then start animating and hold `currentFrame`.
|
||||||
|
@property (nonatomic, strong) FLAnimatedImage *animatedImage;
|
||||||
|
@property (nonatomic, copy) void(^loopCompletionBlock)(NSUInteger loopCountRemaining);
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) UIImage *currentFrame;
|
||||||
|
@property (nonatomic, assign, readonly) NSUInteger currentFrameIndex;
|
||||||
|
|
||||||
|
// The animation runloop mode. Enables playback during scrolling by allowing timer events (i.e. animation) with NSRunLoopCommonModes.
|
||||||
|
// To keep scrolling smooth on single-core devices such as iPhone 3GS/4 and iPod Touch 4th gen, the default run loop mode is NSDefaultRunLoopMode. Otherwise, the default is NSDefaultRunLoopMode.
|
||||||
|
@property (nonatomic, copy) NSRunLoopMode runLoopMode;
|
||||||
|
|
||||||
|
@end
|
||||||
21
Pods/FLAnimatedImage/LICENSE
generated
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2016 Flipboard
|
||||||
|
|
||||||
|
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.
|
||||||
122
Pods/FLAnimatedImage/README.md
generated
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) · [](https://github.com/Flipboard/FLAnimatedImage/blob/master/LICENSE) [](https://github.com/Flipboard/FLAnimatedImage/pulls)
|
||||||
|
|
||||||
|
FLAnimatedImage is a performant animated GIF engine for iOS:
|
||||||
|
|
||||||
|
- Plays multiple GIFs simultaneously with a playback speed comparable to desktop browsers
|
||||||
|
- Honors variable frame delays
|
||||||
|
- Behaves gracefully under memory pressure
|
||||||
|
- Eliminates delays or blocking during the first playback loop
|
||||||
|
- Interprets the frame delays of fast GIFs the same way modern browsers do
|
||||||
|
|
||||||
|
It's a well-tested [component that powers all GIFs in Flipboard](http://engineering.flipboard.com/2014/05/animated-gif). To understand its behavior it comes with an interactive demo:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Who is this for?
|
||||||
|
|
||||||
|
- Apps that don't support animated GIFs yet
|
||||||
|
- Apps that already support animated GIFs but want a higher performance solution
|
||||||
|
- People who want to tinker with the code ([the corresponding blog post](http://engineering.flipboard.com/2014/05/animated-gif/) is a great place to start; also see the *To Do* section below)
|
||||||
|
|
||||||
|
## Installation & Usage
|
||||||
|
|
||||||
|
FLAnimatedImage is a well-encapsulated drop-in component. Simply replace your `UIImageView` instances with instances of `FLAnimatedImageView` to get animated GIF support. There is no central cache or state to manage.
|
||||||
|
|
||||||
|
If using CocoaPods, the quickest way to try it out is to type this on the command line:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ pod try FLAnimatedImage
|
||||||
|
```
|
||||||
|
|
||||||
|
To add it to your app, copy the two classes `FLAnimatedImage.h/.m` and `FLAnimatedImageView.h/.m` into your Xcode project or add via [CocoaPods](http://cocoapods.org) by adding this to your Podfile:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
pod 'FLAnimatedImage', '~> 1.0'
|
||||||
|
```
|
||||||
|
|
||||||
|
If using [Carthage](https://github.com/Carthage/Carthage), add the following line into your `Cartfile`
|
||||||
|
|
||||||
|
```
|
||||||
|
github "Flipboard/FLAnimatedImage"
|
||||||
|
```
|
||||||
|
|
||||||
|
If using [Swift Package Manager](https://github.com/apple/swift-package-manager), add the following to your `Package.swift` or add via XCode:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
dependencies: [
|
||||||
|
.package(url: "https://github.com/Flipboard/FLAnimatedImage.git", .upToNextMajor(from: "1.0.16"))
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
.target(name: "TestProject", dependencies: ["FLAnimatedImage""])
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
In your code, `#import "FLAnimatedImage.h"`, create an image from an animated GIF, and setup the image view to display it:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"]]];
|
||||||
|
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
|
||||||
|
imageView.animatedImage = image;
|
||||||
|
imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
|
||||||
|
[self.view addSubview:imageView];
|
||||||
|
```
|
||||||
|
|
||||||
|
It's flexible to integrate in your custom image loading stack and backwards compatible to iOS 9.
|
||||||
|
|
||||||
|
It uses ARC and the Apple frameworks `QuartzCore`, `ImageIO`, `MobileCoreServices`, and `CoreGraphics`.
|
||||||
|
|
||||||
|
It is capable of fine-grained logging. A block can be set on `FLAnimatedImage` that's invoked when logging occurs with various log levels via the `+setLogBlock:logLevel:` method. For example:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
// Set up FLAnimatedImage logging.
|
||||||
|
[FLAnimatedImage setLogBlock:^(NSString *logString, FLLogLevel logLevel) {
|
||||||
|
// Using NSLog
|
||||||
|
NSLog(@"%@", logString);
|
||||||
|
|
||||||
|
// ...or CocoaLumberjackLogger only logging warnings and errors
|
||||||
|
if (logLevel == FLLogLevelError) {
|
||||||
|
DDLogError(@"%@", logString);
|
||||||
|
} else if (logLevel == FLLogLevelWarn) {
|
||||||
|
DDLogWarn(@"%@", logString);
|
||||||
|
}
|
||||||
|
} logLevel:FLLogLevelWarn];
|
||||||
|
```
|
||||||
|
|
||||||
|
Since FLAnimatedImage is licensed under MIT, it's compatible with the terms of using it for any app on the App Store.
|
||||||
|
|
||||||
|
## Release process
|
||||||
|
1. Bump version in `FLAnimatedImage.podspec`, update CHANGES, and commit.
|
||||||
|
2. Tag commit with `> git tag -a <VERSION> -m "<VERSION>"` and `> git push --tags`.
|
||||||
|
3. [Submit Podspec to Trunk with](https://guides.cocoapods.org/making/specs-and-specs-repo.html#how-do-i-update-an-existing-pod) `> pod trunk push FLAnimatedImage.podspec` ([ensure you're auth'ed](https://guides.cocoapods.org/making/getting-setup-with-trunk.html#getting-started)).
|
||||||
|
## To Do
|
||||||
|
- Support other animated image formats such as APNG or WebP (WebP support implemented [here](https://github.com/Flipboard/FLAnimatedImage/pull/86))
|
||||||
|
- Integration into network libraries and image caches
|
||||||
|
- Investigate whether `FLAnimatedImage` should become a `UIImage` subclass
|
||||||
|
- Smarter buffering
|
||||||
|
- Bring demo app to iPhone
|
||||||
|
|
||||||
|
This code has successfully shipped to many people as is, but please do come with your questions, issues and pull requests!
|
||||||
|
|
||||||
|
## Select apps using FLAnimatedImage
|
||||||
|
(alphabetically)
|
||||||
|
|
||||||
|
- [Close-up](http://closeu.pe)
|
||||||
|
- [Design Shots](https://itunes.apple.com/app/id792517951)
|
||||||
|
- [Dropbox](https://www.dropbox.com)
|
||||||
|
- [Dumpert](http://dumpert.nl)
|
||||||
|
- [Ello](https://ello.co/)
|
||||||
|
- [Facebook](https://facebook.com)
|
||||||
|
- [Flipboard](https://flipboard.com)
|
||||||
|
- [getGIF](https://itunes.apple.com/app/id964784701)
|
||||||
|
- [Gifalicious](https://itunes.apple.com/us/app/gifalicious-see-your-gifs/id965346708?mt=8)
|
||||||
|
- [HashPhotos](https://itunes.apple.com/app/id685784609)
|
||||||
|
- [Instagram](https://www.instagram.com/)
|
||||||
|
- [LiveBooth](http://www.liveboothapp.com)
|
||||||
|
- [lWlVl Festival](http://lwlvl.com)
|
||||||
|
- [Medium](https://medium.com)
|
||||||
|
- [Pinterest](https://pinterest.com)
|
||||||
|
- [Slack](https://slack.com/)
|
||||||
|
- [Telegram](https://telegram.org/)
|
||||||
|
- [Zip Code Finder](https://itunes.apple.com/app/id893031254)
|
||||||
|
|
||||||
|
If you're using FLAnimatedImage in your app, please open a PR to add it to this list!
|
||||||
20
Pods/Manifest.lock
generated
@@ -89,6 +89,8 @@ PODS:
|
|||||||
- BRPickerView/TextPicker (2.9.1):
|
- BRPickerView/TextPicker (2.9.1):
|
||||||
- BRPickerView/Core
|
- BRPickerView/Core
|
||||||
- Bugly (2.6.1)
|
- Bugly (2.6.1)
|
||||||
|
- DZNEmptyDataSet (1.8.1)
|
||||||
|
- FLAnimatedImage (1.0.17)
|
||||||
- FMDB (2.7.12):
|
- FMDB (2.7.12):
|
||||||
- FMDB/standard (= 2.7.12)
|
- FMDB/standard (= 2.7.12)
|
||||||
- FMDB/Core (2.7.12)
|
- FMDB/Core (2.7.12)
|
||||||
@@ -189,6 +191,9 @@ PODS:
|
|||||||
- SVGAPlayer/ProtoFiles
|
- SVGAPlayer/ProtoFiles
|
||||||
- SVGAPlayer/ProtoFiles (2.5.7):
|
- SVGAPlayer/ProtoFiles (2.5.7):
|
||||||
- Protobuf (~> 3.4)
|
- Protobuf (~> 3.4)
|
||||||
|
- SVProgressHUD (2.3.1):
|
||||||
|
- SVProgressHUD/Core (= 2.3.1)
|
||||||
|
- SVProgressHUD/Core (2.3.1)
|
||||||
- TencentCloudHuiyanSDKFace_framework (8.7.0)
|
- TencentCloudHuiyanSDKFace_framework (8.7.0)
|
||||||
- TIMCommon (8.5.6864):
|
- TIMCommon (8.5.6864):
|
||||||
- Masonry
|
- Masonry
|
||||||
@@ -222,6 +227,8 @@ PODS:
|
|||||||
- TZImagePickerController/Basic (3.8.8)
|
- TZImagePickerController/Basic (3.8.8)
|
||||||
- TZImagePickerController/Location (3.8.8)
|
- TZImagePickerController/Location (3.8.8)
|
||||||
- WechatOpenSDK-XCFramework (2.0.4)
|
- WechatOpenSDK-XCFramework (2.0.4)
|
||||||
|
- XHLaunchAd (3.9.12):
|
||||||
|
- FLAnimatedImage (~> 1.0.12)
|
||||||
- YBImageBrowser (3.0.9):
|
- YBImageBrowser (3.0.9):
|
||||||
- YBImageBrowser/Core (= 3.0.9)
|
- YBImageBrowser/Core (= 3.0.9)
|
||||||
- YBImageBrowser/Core (3.0.9):
|
- YBImageBrowser/Core (3.0.9):
|
||||||
@@ -254,6 +261,7 @@ DEPENDENCIES:
|
|||||||
- AvoidCrash
|
- AvoidCrash
|
||||||
- BRPickerView
|
- BRPickerView
|
||||||
- Bugly
|
- Bugly
|
||||||
|
- DZNEmptyDataSet
|
||||||
- FMDB
|
- FMDB
|
||||||
- IQKeyboardManager
|
- IQKeyboardManager
|
||||||
- JXCategoryView
|
- JXCategoryView
|
||||||
@@ -269,6 +277,7 @@ DEPENDENCIES:
|
|||||||
- SDWebImage
|
- SDWebImage
|
||||||
- SDWebImageWebPCoder
|
- SDWebImageWebPCoder
|
||||||
- SVGAPlayer
|
- SVGAPlayer
|
||||||
|
- SVProgressHUD
|
||||||
- TencentCloudHuiyanSDKFace_framework (from `./TencentCloudHuiyanSDKFace_framework`)
|
- TencentCloudHuiyanSDKFace_framework (from `./TencentCloudHuiyanSDKFace_framework`)
|
||||||
- TIMCommon (from `./TUIKit/TIMCommon`)
|
- TIMCommon (from `./TUIKit/TIMCommon`)
|
||||||
- TIMPush
|
- TIMPush
|
||||||
@@ -277,6 +286,7 @@ DEPENDENCIES:
|
|||||||
- TUICore (from `./TUIKit/TUICore`)
|
- TUICore (from `./TUIKit/TUICore`)
|
||||||
- TZImagePickerController
|
- TZImagePickerController
|
||||||
- WechatOpenSDK-XCFramework (~> 2.0.2)
|
- WechatOpenSDK-XCFramework (~> 2.0.2)
|
||||||
|
- XHLaunchAd
|
||||||
- YBImageBrowser (~> 3.0.9)
|
- YBImageBrowser (~> 3.0.9)
|
||||||
- YBImageBrowser/Video
|
- YBImageBrowser/Video
|
||||||
- YYCache
|
- YYCache
|
||||||
@@ -298,6 +308,8 @@ SPEC REPOS:
|
|||||||
- AvoidCrash
|
- AvoidCrash
|
||||||
- BRPickerView
|
- BRPickerView
|
||||||
- Bugly
|
- Bugly
|
||||||
|
- DZNEmptyDataSet
|
||||||
|
- FLAnimatedImage
|
||||||
- FMDB
|
- FMDB
|
||||||
- IQKeyboardManager
|
- IQKeyboardManager
|
||||||
- JXCategoryView
|
- JXCategoryView
|
||||||
@@ -318,10 +330,12 @@ SPEC REPOS:
|
|||||||
- SDWebImageWebPCoder
|
- SDWebImageWebPCoder
|
||||||
- SSZipArchive
|
- SSZipArchive
|
||||||
- SVGAPlayer
|
- SVGAPlayer
|
||||||
|
- SVProgressHUD
|
||||||
- TIMPush
|
- TIMPush
|
||||||
- TXIMSDK_Plus_iOS_XCFramework
|
- TXIMSDK_Plus_iOS_XCFramework
|
||||||
- TZImagePickerController
|
- TZImagePickerController
|
||||||
- WechatOpenSDK-XCFramework
|
- WechatOpenSDK-XCFramework
|
||||||
|
- XHLaunchAd
|
||||||
- YBImageBrowser
|
- YBImageBrowser
|
||||||
- YYCache
|
- YYCache
|
||||||
- YYCategories
|
- YYCategories
|
||||||
@@ -354,6 +368,8 @@ SPEC CHECKSUMS:
|
|||||||
AvoidCrash: 28c6916fe19bd2b84126b8dec7cbe61c9a12741d
|
AvoidCrash: 28c6916fe19bd2b84126b8dec7cbe61c9a12741d
|
||||||
BRPickerView: 6dd69ea2c48e0a0abf1d197a705050e13143ee63
|
BRPickerView: 6dd69ea2c48e0a0abf1d197a705050e13143ee63
|
||||||
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
|
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
|
||||||
|
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
|
||||||
|
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
|
||||||
FMDB: 728731dd336af3936ce00f91d9d8495f5718a0e6
|
FMDB: 728731dd336af3936ce00f91d9d8495f5718a0e6
|
||||||
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
|
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
|
||||||
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
|
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
|
||||||
@@ -374,6 +390,7 @@ SPEC CHECKSUMS:
|
|||||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||||
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
|
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
|
||||||
|
SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
|
||||||
TencentCloudHuiyanSDKFace_framework: 1a9398776aac617c2ea7e580fbaf797be96256e1
|
TencentCloudHuiyanSDKFace_framework: 1a9398776aac617c2ea7e580fbaf797be96256e1
|
||||||
TIMCommon: 23ed3f287fe194ce5139ce421f96cfb81232562f
|
TIMCommon: 23ed3f287fe194ce5139ce421f96cfb81232562f
|
||||||
TIMPush: e1d85ff0ee0c22cc3f51010ddd8de5316d60102c
|
TIMPush: e1d85ff0ee0c22cc3f51010ddd8de5316d60102c
|
||||||
@@ -383,6 +400,7 @@ SPEC CHECKSUMS:
|
|||||||
TXIMSDK_Plus_iOS_XCFramework: ae200b67e618fef504947de6551b127d35b18d67
|
TXIMSDK_Plus_iOS_XCFramework: ae200b67e618fef504947de6551b127d35b18d67
|
||||||
TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf
|
TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf
|
||||||
WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f
|
WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f
|
||||||
|
XHLaunchAd: 6320f9c68732667323072fc3a5f104e40fbe9cfe
|
||||||
YBImageBrowser: 7ecc8bf33ffa5f3b94c397c29b4f3638dd37f527
|
YBImageBrowser: 7ecc8bf33ffa5f3b94c397c29b4f3638dd37f527
|
||||||
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
|
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
|
||||||
YYCategories: 6bcd4314c6661a561410dce4a793379ebd306abd
|
YYCategories: 6bcd4314c6661a561410dce4a793379ebd306abd
|
||||||
@@ -392,6 +410,6 @@ SPEC CHECKSUMS:
|
|||||||
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
|
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
|
||||||
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67
|
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67
|
||||||
|
|
||||||
PODFILE CHECKSUM: 0bc5dc8150dc827b074af9f826d3454f1feacf07
|
PODFILE CHECKSUM: 068f3e03c3d864b09a8c3ffbb0275bbd06bd6ed7
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
26788
Pods/Pods.xcodeproj/project.pbxproj
generated
21
Pods/SVProgressHUD/LICENSE
generated
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors.
|
||||||
|
|
||||||
|
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.
|
||||||
221
Pods/SVProgressHUD/README.md
generated
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
# SVProgressHUD
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
[](https://swift.org/package-manager/)
|
||||||
|
[](https://cocoapods.org)
|
||||||
|
[](https://github.com/Carthage/Carthage)
|
||||||
|
|
||||||
|
`SVProgressHUD` is a clean and easy-to-use HUD meant to display the progress of an ongoing task on iOS and tvOS.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Swift Package Manager
|
||||||
|
|
||||||
|
[Swift Package Manager](https://swift.org/package-manager/) (SwiftPM) is a tool for managing the distribution of Swift code. It simplifies the process of managing Swift package dependencies.
|
||||||
|
|
||||||
|
To integrate `SVProgressHUD` into your project using SwiftPM:
|
||||||
|
|
||||||
|
1. In Xcode, select **File > Add Package Dependency**.
|
||||||
|
2. Enter the following package repository URL: https://github.com/SVProgressHUD/SVProgressHUD.git
|
||||||
|
3. Choose the appropriate version (e.g. a specific version, branch, or commit).
|
||||||
|
4. Add `SVProgressHUD` to your target dependencies.
|
||||||
|
|
||||||
|
`SVProgressHUD` requires at least Swift tools version 5.3.
|
||||||
|
|
||||||
|
### From CocoaPods
|
||||||
|
|
||||||
|
[CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like `SVProgressHUD` in your projects. First, add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html):
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
pod 'SVProgressHUD'
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to use the latest features of `SVProgressHUD` use normal external source dependencies.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
pod 'SVProgressHUD', :git => 'https://github.com/SVProgressHUD/SVProgressHUD.git'
|
||||||
|
```
|
||||||
|
|
||||||
|
This pulls from the `master` branch directly.
|
||||||
|
|
||||||
|
Second, install `SVProgressHUD` into your project:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
pod install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Carthage
|
||||||
|
|
||||||
|
[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate `SVProgressHUD` into your Xcode project using Carthage, specify it in your `Cartfile`:
|
||||||
|
|
||||||
|
```ogdl
|
||||||
|
github "SVProgressHUD/SVProgressHUD"
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `carthage bootstrap` to build the framework in your repository's Carthage directory. You can then include it in your target's `carthage copy-frameworks` build phase. For more information on this, please see [Carthage's documentation](https://github.com/carthage/carthage#if-youre-building-for-ios-tvos-or-watchos).
|
||||||
|
|
||||||
|
### Manually
|
||||||
|
|
||||||
|
* Drag the `SVProgressHUD/SVProgressHUD` folder into your project.
|
||||||
|
* Take care that `SVProgressHUD.bundle` is added to `Targets->Build Phases->Copy Bundle Resources`.
|
||||||
|
* Add the **QuartzCore** framework to your project.
|
||||||
|
|
||||||
|
## Swift
|
||||||
|
|
||||||
|
Even though `SVProgressHUD` is written in Objective-C, it can be used in Swift with no hassle.
|
||||||
|
|
||||||
|
If you use [CocoaPods](http://cocoapods.org) add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html):
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
use_frameworks!
|
||||||
|
```
|
||||||
|
|
||||||
|
If you added `SVProgressHUD` manually, just add a [bridging header](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html) file to your project with the `SVProgressHUD` header included.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
(see sample Xcode project in `/Demo`)
|
||||||
|
|
||||||
|
`SVProgressHUD` is created as a singleton (i.e. it doesn't need to be explicitly allocated and instantiated; you directly call `[SVProgressHUD method]` / `SVProgressHUD.method()`).
|
||||||
|
|
||||||
|
**Use `SVProgressHUD` wisely! Only use it if you absolutely need to perform a task before taking the user forward. Bad use case examples: pull to refresh, infinite scrolling, sending message.**
|
||||||
|
|
||||||
|
Using `SVProgressHUD` in your app will usually look as simple as this.
|
||||||
|
|
||||||
|
**Objective-C:**
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
[SVProgressHUD show];
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
// time-consuming task
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[SVProgressHUD dismiss];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Swift:**
|
||||||
|
|
||||||
|
```swift
|
||||||
|
SVProgressHUD.show()
|
||||||
|
DispatchQueue.global(qos: .default).async {
|
||||||
|
// time-consuming task
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
SVProgressHUD.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Showing the HUD
|
||||||
|
|
||||||
|
You can show the status of indeterminate tasks using one of the following:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
+ (void)show;
|
||||||
|
+ (void)showWithStatus:(NSString*)string;
|
||||||
|
```
|
||||||
|
|
||||||
|
If you'd like the HUD to reflect the progress of a task, use one of these:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
+ (void)showProgress:(CGFloat)progress;
|
||||||
|
+ (void)showProgress:(CGFloat)progress status:(NSString*)status;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dismissing the HUD
|
||||||
|
|
||||||
|
The HUD can be dismissed using:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
+ (void)dismiss;
|
||||||
|
+ (void)dismissWithDelay:(NSTimeInterval)delay;
|
||||||
|
```
|
||||||
|
|
||||||
|
If you'd like to stack HUDs, you can balance out every show call using:
|
||||||
|
|
||||||
|
```
|
||||||
|
+ (void)popActivity;
|
||||||
|
```
|
||||||
|
|
||||||
|
The HUD will get dismissed once the `popActivity` calls will match the number of show calls.
|
||||||
|
|
||||||
|
Or show an image with status before getting dismissed a little bit later. The display time depends on `minimumDismissTimeInterval` and the length of the given string.
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
+ (void)showInfoWithStatus:(NSString*)string;
|
||||||
|
+ (void)showSuccessWithStatus:(NSString*)string;
|
||||||
|
+ (void)showErrorWithStatus:(NSString*)string;
|
||||||
|
+ (void)showImage:(UIImage*)image status:(NSString*)string;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
`SVProgressHUD` is designed with flexibility in mind, providing a myriad of customization options to fit the look and feel of your application seamlessly.
|
||||||
|
|
||||||
|
* Appearance: Make use of the `UI_APPEARANCE_SELECTOR` to adjust styles, colors, fonts, size, and images app-wide.
|
||||||
|
* Behavior: Control visibility durations, display delays, and animation speeds.
|
||||||
|
* Feedback: Enhance the user experience with options for haptic feedback and motion effects.
|
||||||
|
|
||||||
|
For a comprehensive list of properties and detailed explanations, refer to the `SVProgressHUD.h` file in the API documentation.
|
||||||
|
|
||||||
|
### Hint
|
||||||
|
|
||||||
|
As standard `SVProgressHUD` offers three preconfigured styles:
|
||||||
|
|
||||||
|
* `SVProgressHUDStyleAutomatic`: Automatically switch between the light and dark style
|
||||||
|
* `SVProgressHUDStyleLight`: White background with black spinner and text
|
||||||
|
* `SVProgressHUDStyleDark`: Black background with white spinner and text
|
||||||
|
|
||||||
|
If you want to use custom colors use `setForegroundColor:` and/or `setBackgroundColor:`. These implicitly set the HUD's style to `SVProgressHUDStyleCustom`.
|
||||||
|
|
||||||
|
## Haptic Feedback
|
||||||
|
|
||||||
|
Available on iPhone 7 and newer, `SVProgressHUD` can automatically trigger haptic feedback depending on which HUD is being displayed. The feedback maps as follows:
|
||||||
|
|
||||||
|
* `showSuccessWithStatus:` <-> `UINotificationFeedbackTypeSuccess`
|
||||||
|
* `showInfoWithStatus:` <-> `UINotificationFeedbackTypeWarning`
|
||||||
|
* `showErrorWithStatus:` <-> `UINotificationFeedbackTypeError`
|
||||||
|
|
||||||
|
To enable this functionality, use `setHapticsEnabled:`.
|
||||||
|
|
||||||
|
## Notifications
|
||||||
|
|
||||||
|
`SVProgressHUD` posts four notifications via `NSNotificationCenter` in response to being shown/dismissed:
|
||||||
|
|
||||||
|
* `SVProgressHUDWillAppearNotification` when the show animation starts
|
||||||
|
* `SVProgressHUDDidAppearNotification` when the show animation completes
|
||||||
|
* `SVProgressHUDWillDisappearNotification` when the dismiss animation starts
|
||||||
|
* `SVProgressHUDDidDisappearNotification` when the dismiss animation completes
|
||||||
|
|
||||||
|
Each notification passes a `userInfo` dictionary holding the HUD's status string (if any), retrievable via `SVProgressHUDStatusUserInfoKey`.
|
||||||
|
|
||||||
|
`SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For these notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch.
|
||||||
|
|
||||||
|
## App Extensions
|
||||||
|
|
||||||
|
When using `SVProgressHUD` in an App Extension, `#define SV_APP_EXTENSIONS` to avoid using unavailable APIs. This will be done automatically when using the `AppExtension` CocoaPods subspec. Additionally, call `setViewForExtension:` from your extensions view controller with `self.view`.
|
||||||
|
|
||||||
|
## Contributing to this project
|
||||||
|
|
||||||
|
If you have feature requests or bug reports, feel free to help out by sending pull requests or by [creating new issues](https://github.com/SVProgressHUD/SVProgressHUD/issues/new). Please take a moment to
|
||||||
|
review the guidelines written by [Nicolas Gallagher](https://github.com/necolas):
|
||||||
|
|
||||||
|
* [Bug reports](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#bugs)
|
||||||
|
* [Feature requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#features)
|
||||||
|
* [Pull requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#pull-requests)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
`SVProgressHUD` is distributed under the terms and conditions of the [MIT license](https://github.com/SVProgressHUD/SVProgressHUD/blob/master/LICENSE). The success, error and info icons used on iOS 12 are made by [Freepik](http://www.freepik.com) from [Flaticon](https://www.flaticon.com) and are licensed under [Creative Commons BY 3.0](https://creativecommons.org/licenses/by/3.0/).
|
||||||
|
|
||||||
|
## Privacy
|
||||||
|
|
||||||
|
`SVProgressHUD` does not collect any data. A [privacy manifest file](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files) is [provided](SVProgressHUD/PrivacyInfo.xcprivacy).
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
`SVProgressHUD` is brought to you by Sam Vermette, [Tobias Totzek](https://totzek.me) and [contributors to the project](https://github.com/SVProgressHUD/SVProgressHUD/contributors). If you're using `SVProgressHUD` in your project, attribution would be very appreciated.
|
||||||
14
Pods/SVProgressHUD/SVProgressHUD/PrivacyInfo.xcprivacy
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyTracking</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypes</key>
|
||||||
|
<array/>
|
||||||
|
<key>NSPrivacyTrackingDomains</key>
|
||||||
|
<array/>
|
||||||
|
<key>NSPrivacyAccessedAPITypes</key>
|
||||||
|
<array/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
17
Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// SVIndefiniteAnimatedView.h
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2023 Guillaume Campagna and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface SVIndefiniteAnimatedView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, assign) CGFloat strokeThickness;
|
||||||
|
@property (nonatomic, assign) CGFloat radius;
|
||||||
|
@property (nonatomic, strong) UIColor *strokeColor;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
142
Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m
generated
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
//
|
||||||
|
// SVIndefiniteAnimatedView.m
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2023 Guillaume Campagna and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "SVIndefiniteAnimatedView.h"
|
||||||
|
#import "SVProgressHUD.h"
|
||||||
|
|
||||||
|
@interface SVIndefiniteAnimatedView ()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SVIndefiniteAnimatedView
|
||||||
|
|
||||||
|
- (void)willMoveToSuperview:(UIView*)newSuperview {
|
||||||
|
if (newSuperview) {
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
} else {
|
||||||
|
[_indefiniteAnimatedLayer removeFromSuperlayer];
|
||||||
|
_indefiniteAnimatedLayer = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutAnimatedLayer {
|
||||||
|
CALayer *layer = self.indefiniteAnimatedLayer;
|
||||||
|
|
||||||
|
if (!layer.superlayer) {
|
||||||
|
[self.layer addSublayer:layer];
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds);
|
||||||
|
CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds);
|
||||||
|
layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CAShapeLayer*)indefiniteAnimatedLayer {
|
||||||
|
if(!_indefiniteAnimatedLayer) {
|
||||||
|
CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5);
|
||||||
|
UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat) (M_PI*3/2) endAngle:(CGFloat) (M_PI/2+M_PI*5) clockwise:YES];
|
||||||
|
|
||||||
|
_indefiniteAnimatedLayer = [CAShapeLayer layer];
|
||||||
|
_indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale];
|
||||||
|
_indefiniteAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2);
|
||||||
|
_indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor;
|
||||||
|
_indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor;
|
||||||
|
_indefiniteAnimatedLayer.lineWidth = self.strokeThickness;
|
||||||
|
_indefiniteAnimatedLayer.lineCap = kCALineCapRound;
|
||||||
|
_indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel;
|
||||||
|
_indefiniteAnimatedLayer.path = smoothedPath.CGPath;
|
||||||
|
|
||||||
|
CALayer *maskLayer = [CALayer layer];
|
||||||
|
|
||||||
|
NSBundle *imageBundle = [SVProgressHUD imageBundle];
|
||||||
|
|
||||||
|
maskLayer.contents = (__bridge id)[[UIImage imageNamed:@"angle-mask.png" inBundle:imageBundle compatibleWithTraitCollection:nil] CGImage];
|
||||||
|
maskLayer.frame = _indefiniteAnimatedLayer.bounds;
|
||||||
|
_indefiniteAnimatedLayer.mask = maskLayer;
|
||||||
|
|
||||||
|
NSTimeInterval animationDuration = 1;
|
||||||
|
CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
|
||||||
|
|
||||||
|
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
|
||||||
|
animation.fromValue = (id) 0;
|
||||||
|
animation.toValue = @(M_PI*2);
|
||||||
|
animation.duration = animationDuration;
|
||||||
|
animation.timingFunction = linearCurve;
|
||||||
|
animation.removedOnCompletion = NO;
|
||||||
|
animation.repeatCount = INFINITY;
|
||||||
|
animation.fillMode = kCAFillModeForwards;
|
||||||
|
animation.autoreverses = NO;
|
||||||
|
[_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"];
|
||||||
|
|
||||||
|
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
|
||||||
|
animationGroup.duration = animationDuration;
|
||||||
|
animationGroup.repeatCount = INFINITY;
|
||||||
|
animationGroup.removedOnCompletion = NO;
|
||||||
|
animationGroup.timingFunction = linearCurve;
|
||||||
|
|
||||||
|
CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
|
||||||
|
strokeStartAnimation.fromValue = @0.015;
|
||||||
|
strokeStartAnimation.toValue = @0.515;
|
||||||
|
|
||||||
|
CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
|
||||||
|
strokeEndAnimation.fromValue = @0.485;
|
||||||
|
strokeEndAnimation.toValue = @0.985;
|
||||||
|
|
||||||
|
animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation];
|
||||||
|
[_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"];
|
||||||
|
|
||||||
|
}
|
||||||
|
return _indefiniteAnimatedLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFrame:(CGRect)frame {
|
||||||
|
if(!CGRectEqualToRect(frame, super.frame)) {
|
||||||
|
[super setFrame:frame];
|
||||||
|
|
||||||
|
if(self.superview) {
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setRadius:(CGFloat)radius {
|
||||||
|
if(radius != _radius) {
|
||||||
|
_radius = radius;
|
||||||
|
|
||||||
|
[_indefiniteAnimatedLayer removeFromSuperlayer];
|
||||||
|
_indefiniteAnimatedLayer = nil;
|
||||||
|
|
||||||
|
if(self.superview) {
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeColor:(UIColor*)strokeColor {
|
||||||
|
_strokeColor = strokeColor;
|
||||||
|
_indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeThickness:(CGFloat)strokeThickness {
|
||||||
|
_strokeThickness = strokeThickness;
|
||||||
|
_indefiniteAnimatedLayer.lineWidth = _strokeThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)sizeThatFits:(CGSize)size {
|
||||||
|
return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// SVProgressAnimatedView.h
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017-2023 Tobias Totzek and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface SVProgressAnimatedView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, assign) CGFloat radius;
|
||||||
|
@property (nonatomic, assign) CGFloat strokeThickness;
|
||||||
|
@property (nonatomic, strong) UIColor *strokeColor;
|
||||||
|
@property (nonatomic, assign) CGFloat strokeEnd;
|
||||||
|
|
||||||
|
@end
|
||||||
96
Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m
generated
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
//
|
||||||
|
// SVProgressAnimatedView.m
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017-2023 Tobias Totzek and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "SVProgressAnimatedView.h"
|
||||||
|
|
||||||
|
@interface SVProgressAnimatedView ()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) CAShapeLayer *ringAnimatedLayer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SVProgressAnimatedView
|
||||||
|
|
||||||
|
- (void)willMoveToSuperview:(UIView*)newSuperview {
|
||||||
|
if (newSuperview) {
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
} else {
|
||||||
|
[_ringAnimatedLayer removeFromSuperlayer];
|
||||||
|
_ringAnimatedLayer = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutAnimatedLayer {
|
||||||
|
CALayer *layer = self.ringAnimatedLayer;
|
||||||
|
[self.layer addSublayer:layer];
|
||||||
|
|
||||||
|
CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds);
|
||||||
|
CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds);
|
||||||
|
layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CAShapeLayer*)ringAnimatedLayer {
|
||||||
|
if(!_ringAnimatedLayer) {
|
||||||
|
CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5);
|
||||||
|
UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat)-M_PI_2 endAngle:(CGFloat) (M_PI + M_PI_2) clockwise:YES];
|
||||||
|
|
||||||
|
_ringAnimatedLayer = [CAShapeLayer layer];
|
||||||
|
_ringAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale];
|
||||||
|
_ringAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2);
|
||||||
|
_ringAnimatedLayer.fillColor = [UIColor clearColor].CGColor;
|
||||||
|
_ringAnimatedLayer.strokeColor = self.strokeColor.CGColor;
|
||||||
|
_ringAnimatedLayer.lineWidth = self.strokeThickness;
|
||||||
|
_ringAnimatedLayer.lineCap = kCALineCapRound;
|
||||||
|
_ringAnimatedLayer.lineJoin = kCALineJoinBevel;
|
||||||
|
_ringAnimatedLayer.path = smoothedPath.CGPath;
|
||||||
|
}
|
||||||
|
return _ringAnimatedLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFrame:(CGRect)frame {
|
||||||
|
if(!CGRectEqualToRect(frame, super.frame)) {
|
||||||
|
[super setFrame:frame];
|
||||||
|
|
||||||
|
if(self.superview) {
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setRadius:(CGFloat)radius {
|
||||||
|
if(radius != _radius) {
|
||||||
|
_radius = radius;
|
||||||
|
|
||||||
|
[_ringAnimatedLayer removeFromSuperlayer];
|
||||||
|
_ringAnimatedLayer = nil;
|
||||||
|
|
||||||
|
if(self.superview) {
|
||||||
|
[self layoutAnimatedLayer];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeColor:(UIColor*)strokeColor {
|
||||||
|
_strokeColor = strokeColor;
|
||||||
|
_ringAnimatedLayer.strokeColor = strokeColor.CGColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeThickness:(CGFloat)strokeThickness {
|
||||||
|
_strokeThickness = strokeThickness;
|
||||||
|
_ringAnimatedLayer.lineWidth = _strokeThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeEnd:(CGFloat)strokeEnd {
|
||||||
|
_strokeEnd = strokeEnd;
|
||||||
|
_ringAnimatedLayer.strokeEnd = _strokeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)sizeThatFits:(CGSize)size {
|
||||||
|
return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png
generated
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png
generated
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png
generated
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png
generated
Normal file
|
After Width: | Height: | Size: 184 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png
generated
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png
generated
Normal file
|
After Width: | Height: | Size: 398 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png
generated
Normal file
|
After Width: | Height: | Size: 365 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png
generated
Normal file
|
After Width: | Height: | Size: 816 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png
generated
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png
generated
Normal file
|
After Width: | Height: | Size: 262 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png
generated
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png
generated
Normal file
|
After Width: | Height: | Size: 714 B |
392
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h
generated
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
//
|
||||||
|
// SVProgressHUD.h
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2011-2023 Sam Vermette and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDDidReceiveTouchEventNotification;
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDDidTouchDownInsideNotification;
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDWillDisappearNotification;
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDDidDisappearNotification;
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDWillAppearNotification;
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDDidAppearNotification;
|
||||||
|
|
||||||
|
extern NSString * _Nonnull const SVProgressHUDStatusUserInfoKey;
|
||||||
|
|
||||||
|
/// Represents the appearance style of the HUD.
|
||||||
|
typedef NS_ENUM(NSInteger, SVProgressHUDStyle) {
|
||||||
|
/// White HUD with black text. HUD background will be blurred.
|
||||||
|
SVProgressHUDStyleLight NS_SWIFT_NAME(light),
|
||||||
|
|
||||||
|
/// Black HUD with white text. HUD background will be blurred.
|
||||||
|
SVProgressHUDStyleDark NS_SWIFT_NAME(dark),
|
||||||
|
|
||||||
|
/// Uses the fore- and background color properties.
|
||||||
|
SVProgressHUDStyleCustom NS_SWIFT_NAME(custom),
|
||||||
|
|
||||||
|
/// Automatically switch between light or dark mode appearance.
|
||||||
|
SVProgressHUDStyleAutomatic NS_SWIFT_NAME(automatic)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents the type of mask to be applied when the HUD is displayed.
|
||||||
|
typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) {
|
||||||
|
/// Allow user interactions while HUD is displayed.
|
||||||
|
SVProgressHUDMaskTypeNone NS_SWIFT_NAME(none) = 1,
|
||||||
|
|
||||||
|
/// Don't allow user interactions with background objects.
|
||||||
|
SVProgressHUDMaskTypeClear NS_SWIFT_NAME(clear),
|
||||||
|
|
||||||
|
/// Don't allow user interactions and dim the UI behind the HUD (as in iOS 7+).
|
||||||
|
SVProgressHUDMaskTypeBlack NS_SWIFT_NAME(black),
|
||||||
|
|
||||||
|
/// Don't allow user interactions and dim the UI with an UIAlertView-like background gradient (as in iOS 6).
|
||||||
|
SVProgressHUDMaskTypeGradient NS_SWIFT_NAME(gradient),
|
||||||
|
|
||||||
|
/// Don't allow user interactions and dim the UI behind the HUD with a custom color.
|
||||||
|
SVProgressHUDMaskTypeCustom NS_SWIFT_NAME(custom)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents the animation type of the HUD when it's shown or hidden.
|
||||||
|
typedef NS_ENUM(NSUInteger, SVProgressHUDAnimationType) {
|
||||||
|
/// Custom flat animation (indefinite animated ring).
|
||||||
|
SVProgressHUDAnimationTypeFlat NS_SWIFT_NAME(flat),
|
||||||
|
|
||||||
|
/// iOS native UIActivityIndicatorView.
|
||||||
|
SVProgressHUDAnimationTypeNative NS_SWIFT_NAME(native)
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (^SVProgressHUDShowCompletion)(void);
|
||||||
|
typedef void (^SVProgressHUDDismissCompletion)(void);
|
||||||
|
|
||||||
|
@interface SVProgressHUD : UIView
|
||||||
|
|
||||||
|
#pragma mark - Customization
|
||||||
|
|
||||||
|
/// Represents the default style for the HUD.
|
||||||
|
/// @discussion Default: SVProgressHUDStyleAutomatic.
|
||||||
|
@property (assign, nonatomic) SVProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Represents the type of mask applied when the HUD is displayed.
|
||||||
|
/// @discussion Default: SVProgressHUDMaskTypeNone.
|
||||||
|
@property (assign, nonatomic) SVProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Defines the animation type used when the HUD is displayed.
|
||||||
|
/// @discussion Default: SVProgressHUDAnimationTypeFlat.
|
||||||
|
@property (assign, nonatomic) SVProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// The container view used for displaying the HUD. If nil, the default window level is used.
|
||||||
|
@property (strong, nonatomic, nullable) UIView *containerView;
|
||||||
|
|
||||||
|
/// The minimum size for the HUD. Useful for maintaining a consistent size when the message might cause resizing.
|
||||||
|
/// @discussion Default: CGSizeZero.
|
||||||
|
@property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Thickness of the ring shown in the HUD.
|
||||||
|
/// @discussion Default: 2 pt.
|
||||||
|
@property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Radius of the ring shown in the HUD when there's associated text.
|
||||||
|
/// @discussion Default: 18 pt.
|
||||||
|
@property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Radius of the ring shown in the HUD when there's no associated text.
|
||||||
|
/// @discussion Default: 24 pt.
|
||||||
|
@property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Corner radius of the HUD view.
|
||||||
|
/// @discussion Default: 14 pt.
|
||||||
|
@property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Font used for text within the HUD.
|
||||||
|
/// @discussion Default: [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline].
|
||||||
|
@property (strong, nonatomic, nonnull) UIFont *font UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Background color of the HUD.
|
||||||
|
/// @discussion Default: [UIColor whiteColor].
|
||||||
|
@property (strong, nonatomic, nonnull) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Foreground color used for content in the HUD.
|
||||||
|
/// @discussion Default: [UIColor blackColor].
|
||||||
|
@property (strong, nonatomic, nonnull) UIColor *foregroundColor UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Color for any foreground images in the HUD.
|
||||||
|
/// @discussion Default: same as foregroundColor.
|
||||||
|
@property (strong, nonatomic, nullable) UIColor *foregroundImageColor UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Color for the background layer behind the HUD.
|
||||||
|
/// @discussion Default: [UIColor colorWithWhite:0 alpha:0.4].
|
||||||
|
@property (strong, nonatomic, nonnull) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Size of any images displayed within the HUD.
|
||||||
|
/// @discussion Default: 28x28 pt.
|
||||||
|
@property (assign, nonatomic) CGSize imageViewSize UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Indicates whether images within the HUD should be tinted.
|
||||||
|
/// @discussion Default: YES.
|
||||||
|
@property (assign, nonatomic) BOOL shouldTintImages UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// The image displayed when showing informational messages.
|
||||||
|
/// @discussion Default: info.circle from SF Symbols (iOS 13+) or the bundled info image provided by Freepik.
|
||||||
|
@property (strong, nonatomic, nonnull) UIImage *infoImage UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// The image displayed when showing success messages.
|
||||||
|
/// @discussion Default: checkmark from SF Symbols (iOS 13+) or the bundled success image provided by Freepik.
|
||||||
|
@property (strong, nonatomic, nonnull) UIImage *successImage UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// The image displayed when showing error messages.
|
||||||
|
/// @discussion Default: xmark from SF Symbols (iOS 13+) or the bundled error image provided by Freepik.
|
||||||
|
@property (strong, nonatomic, nonnull) UIImage *errorImage UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// A specific view for extensions. This property is only used if #define SV_APP_EXTENSIONS is set.
|
||||||
|
/// @discussion Default: nil.
|
||||||
|
@property (strong, nonatomic, nonnull) UIView *viewForExtension UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// The interval in seconds to wait before displaying the HUD. If the HUD is displayed before this time elapses, this timer is reset.
|
||||||
|
/// @discussion Default: 0 seconds.
|
||||||
|
@property (assign, nonatomic) NSTimeInterval graceTimeInterval;
|
||||||
|
|
||||||
|
/// The minimum amount of time in seconds the HUD will display.
|
||||||
|
/// @discussion Default: 5.0 seconds.
|
||||||
|
@property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval;
|
||||||
|
|
||||||
|
/// The maximum amount of time in seconds the HUD will display.
|
||||||
|
/// @discussion Default: CGFLOAT_MAX.
|
||||||
|
@property (assign, nonatomic) NSTimeInterval maximumDismissTimeInterval;
|
||||||
|
|
||||||
|
/// Offset from the center position, can be used to adjust the HUD position.
|
||||||
|
/// @discussion Default: 0, 0.
|
||||||
|
@property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Duration of the fade-in animation when showing the HUD.
|
||||||
|
/// @discussion Default: 0.15.
|
||||||
|
@property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// Duration of the fade-out animation when hiding the HUD.
|
||||||
|
/// @discussion Default: 0.15.
|
||||||
|
@property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration UI_APPEARANCE_SELECTOR;
|
||||||
|
|
||||||
|
/// The maximum window level on which the HUD can be displayed.
|
||||||
|
/// @discussion Default: UIWindowLevelNormal.
|
||||||
|
@property (assign, nonatomic) UIWindowLevel maxSupportedWindowLevel;
|
||||||
|
|
||||||
|
/// Indicates if haptic feedback should be used.
|
||||||
|
/// @discussion Default: NO.
|
||||||
|
@property (assign, nonatomic) BOOL hapticsEnabled;
|
||||||
|
|
||||||
|
/// Indicates if motion effects should be applied to the HUD.
|
||||||
|
/// @discussion Default: YES.
|
||||||
|
@property (assign, nonatomic) BOOL motionEffectEnabled;
|
||||||
|
|
||||||
|
@property (class, strong, nonatomic, readonly, nonnull) NSBundle *imageBundle;
|
||||||
|
|
||||||
|
/// Sets the default style for the HUD.
|
||||||
|
/// @param style The desired style for the HUD.
|
||||||
|
+ (void)setDefaultStyle:(SVProgressHUDStyle)style;
|
||||||
|
|
||||||
|
/// Sets the default mask type for the HUD.
|
||||||
|
/// @param maskType The mask type to apply.
|
||||||
|
+ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType;
|
||||||
|
|
||||||
|
/// Sets the default animation type for the HUD.
|
||||||
|
/// @param type The desired animation type.
|
||||||
|
+ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type;
|
||||||
|
|
||||||
|
/// Sets the container view for the HUD.
|
||||||
|
/// @param containerView The view to contain the HUD.
|
||||||
|
+ (void)setContainerView:(nullable UIView*)containerView;
|
||||||
|
|
||||||
|
/// Sets the minimum size for the HUD.
|
||||||
|
/// @param minimumSize The minimum size for the HUD.
|
||||||
|
+ (void)setMinimumSize:(CGSize)minimumSize;
|
||||||
|
|
||||||
|
/// Sets the ring thickness for the HUD.
|
||||||
|
/// @param ringThickness Thickness of the ring.
|
||||||
|
+ (void)setRingThickness:(CGFloat)ringThickness;
|
||||||
|
|
||||||
|
/// Sets the ring radius for the HUD.
|
||||||
|
/// @param radius Radius of the ring.
|
||||||
|
+ (void)setRingRadius:(CGFloat)radius;
|
||||||
|
|
||||||
|
/// Sets the no text ring radius for the HUD.
|
||||||
|
/// @param radius Radius of the ring when no text is displayed.
|
||||||
|
+ (void)setRingNoTextRadius:(CGFloat)radius;
|
||||||
|
|
||||||
|
/// Sets the corner radius for the HUD.
|
||||||
|
/// @param cornerRadius Desired corner radius.
|
||||||
|
+ (void)setCornerRadius:(CGFloat)cornerRadius;
|
||||||
|
|
||||||
|
/// Sets the border color for the HUD.
|
||||||
|
/// @param color Desired border color.
|
||||||
|
+ (void)setBorderColor:(nonnull UIColor*)color;
|
||||||
|
|
||||||
|
/// Sets the border width for the HUD.
|
||||||
|
/// @param width Desired border width.
|
||||||
|
+ (void)setBorderWidth:(CGFloat)width;
|
||||||
|
|
||||||
|
/// Sets the font for the HUD's text.
|
||||||
|
/// @param font Desired font for the text.
|
||||||
|
+ (void)setFont:(nonnull UIFont*)font;
|
||||||
|
|
||||||
|
/// Sets the foreground color for the HUD.
|
||||||
|
/// @param color Desired foreground color.
|
||||||
|
/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`.
|
||||||
|
+ (void)setForegroundColor:(nonnull UIColor*)color;
|
||||||
|
|
||||||
|
/// Sets the foreground image color for the HUD.
|
||||||
|
/// @param color Desired color for the image.
|
||||||
|
/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`.
|
||||||
|
+ (void)setForegroundImageColor:(nullable UIColor*)color;
|
||||||
|
|
||||||
|
/// Sets the background color for the HUD.
|
||||||
|
/// @param color Desired background color.
|
||||||
|
/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`.
|
||||||
|
+ (void)setBackgroundColor:(nonnull UIColor*)color;
|
||||||
|
|
||||||
|
/// Sets a custom blur effect for the HUD view.
|
||||||
|
/// @param blurEffect Desired blur effect.
|
||||||
|
/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`.
|
||||||
|
+ (void)setHudViewCustomBlurEffect:(nullable UIBlurEffect*)blurEffect;
|
||||||
|
|
||||||
|
/// Sets the background layer color for the HUD.
|
||||||
|
/// @param color Desired color for the background layer.
|
||||||
|
+ (void)setBackgroundLayerColor:(nonnull UIColor*)color;
|
||||||
|
|
||||||
|
/// Sets the size for the HUD's image view.
|
||||||
|
/// @param size Desired size for the image view.
|
||||||
|
+ (void)setImageViewSize:(CGSize)size;
|
||||||
|
|
||||||
|
/// Determines if images should be tinted in the HUD.
|
||||||
|
/// @param shouldTintImages Whether images should be tinted.
|
||||||
|
+ (void)setShouldTintImages:(BOOL)shouldTintImages;
|
||||||
|
|
||||||
|
/// Sets the info image for the HUD.
|
||||||
|
/// @param image The desired info image.
|
||||||
|
+ (void)setInfoImage:(nonnull UIImage*)image;
|
||||||
|
|
||||||
|
/// Sets the success image for the HUD.
|
||||||
|
/// @param image The desired success image.
|
||||||
|
+ (void)setSuccessImage:(nonnull UIImage*)image;
|
||||||
|
|
||||||
|
/// Sets the error image for the HUD.
|
||||||
|
/// @param image The desired error image.
|
||||||
|
+ (void)setErrorImage:(nonnull UIImage*)image;
|
||||||
|
|
||||||
|
/// Sets the view for extensions.
|
||||||
|
/// @param view The desired view for extensions.
|
||||||
|
+ (void)setViewForExtension:(nonnull UIView*)view;
|
||||||
|
|
||||||
|
/// Sets the grace time interval for the HUD.
|
||||||
|
/// @param interval Desired grace time interval.
|
||||||
|
+ (void)setGraceTimeInterval:(NSTimeInterval)interval;
|
||||||
|
|
||||||
|
/// Sets the minimum dismiss time interval.
|
||||||
|
/// @param interval The minimum time interval, in seconds, that the HUD should be displayed.
|
||||||
|
+ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval;
|
||||||
|
|
||||||
|
/// Sets the maximum dismiss time interval.
|
||||||
|
/// @param interval The maximum time interval, in seconds, that the HUD should be displayed.
|
||||||
|
+ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval;
|
||||||
|
|
||||||
|
/// Sets the fade-in animation duration.
|
||||||
|
/// @param duration The duration, in seconds, for the fade-in animation.
|
||||||
|
+ (void)setFadeInAnimationDuration:(NSTimeInterval)duration;
|
||||||
|
|
||||||
|
/// Sets the fade-out animation duration.
|
||||||
|
/// @param duration The duration, in seconds, for the fade-out animation.
|
||||||
|
+ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration;
|
||||||
|
|
||||||
|
/// Sets the max supported window level.
|
||||||
|
/// @param windowLevel The UIWindowLevel to which the HUD should be displayed.
|
||||||
|
+ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel;
|
||||||
|
|
||||||
|
/// Determines if haptics are enabled.
|
||||||
|
/// @param hapticsEnabled A boolean that determines if haptic feedback is enabled.
|
||||||
|
+ (void)setHapticsEnabled:(BOOL)hapticsEnabled;
|
||||||
|
|
||||||
|
/// Determines if motion effect is enabled.
|
||||||
|
/// @param motionEffectEnabled A boolean that determines if motion effects are enabled.
|
||||||
|
+ (void)setMotionEffectEnabled:(BOOL)motionEffectEnabled;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Show Methods
|
||||||
|
|
||||||
|
/// Shows the HUD without any additional status message.
|
||||||
|
+ (void)show;
|
||||||
|
|
||||||
|
/// Shows the HUD with a provided status message.
|
||||||
|
/// @param status The message to be displayed alongside the HUD.
|
||||||
|
+ (void)showWithStatus:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Display methods to show progress on the HUD.
|
||||||
|
|
||||||
|
/// Shows the HUD with a progress indicator.
|
||||||
|
/// @param progress A float value between 0.0 and 1.0 indicating the progress.
|
||||||
|
+ (void)showProgress:(float)progress;
|
||||||
|
|
||||||
|
/// Shows the HUD with a progress indicator and a provided status message.
|
||||||
|
/// @param progress A float value between 0.0 and 1.0 indicating the progress.
|
||||||
|
/// @param status The message to be displayed alongside the progress indicator.
|
||||||
|
+ (void)showProgress:(float)progress status:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Updates the current status of the loading HUD.
|
||||||
|
/// @param status The new status message to update the HUD with.
|
||||||
|
+ (void)setStatus:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Shows an info status with the provided message.
|
||||||
|
/// @param status The info message to be displayed.
|
||||||
|
+ (void)showInfoWithStatus:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Shows a success status with the provided message.
|
||||||
|
/// @param status The success message to be displayed.
|
||||||
|
+ (void)showSuccessWithStatus:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Shows an error status with the provided message.
|
||||||
|
/// @param status The error message to be displayed.
|
||||||
|
+ (void)showErrorWithStatus:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Shows a custom image with the provided status message.
|
||||||
|
/// @param image The custom image to be displayed.
|
||||||
|
/// @param status The message to accompany the custom image.
|
||||||
|
+ (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status;
|
||||||
|
|
||||||
|
/// Sets the offset from the center for the HUD.
|
||||||
|
/// @param offset The UIOffset value indicating how much the HUD should be offset from its center position.
|
||||||
|
+ (void)setOffsetFromCenter:(UIOffset)offset;
|
||||||
|
|
||||||
|
/// Resets the offset to center the HUD.
|
||||||
|
+ (void)resetOffsetFromCenter;
|
||||||
|
|
||||||
|
/// Decreases the activity count, dismissing the HUD if count reaches 0.
|
||||||
|
+ (void)popActivity;
|
||||||
|
|
||||||
|
/// Dismisses the HUD immediately.
|
||||||
|
+ (void)dismiss;
|
||||||
|
|
||||||
|
/// Dismisses the HUD and triggers a completion block.
|
||||||
|
/// @param completion A block that gets executed after the HUD is dismissed.
|
||||||
|
+ (void)dismissWithCompletion:(nullable SVProgressHUDDismissCompletion)completion;
|
||||||
|
|
||||||
|
/// Dismisses the HUD after a specified delay.
|
||||||
|
/// @param delay The time in seconds after which the HUD should be dismissed.
|
||||||
|
+ (void)dismissWithDelay:(NSTimeInterval)delay;
|
||||||
|
|
||||||
|
/// Dismisses the HUD after a specified delay and triggers a completion block.
|
||||||
|
/// @param delay The time in seconds after which the HUD should be dismissed.
|
||||||
|
/// @param completion A block that gets executed after the HUD is dismissed.
|
||||||
|
+ (void)dismissWithDelay:(NSTimeInterval)delay completion:(nullable SVProgressHUDDismissCompletion)completion;
|
||||||
|
|
||||||
|
/// Checks if the HUD is currently visible.
|
||||||
|
/// @return A boolean value indicating whether the HUD is visible.
|
||||||
|
+ (BOOL)isVisible;
|
||||||
|
|
||||||
|
/// Calculates the display duration based on a given string's length.
|
||||||
|
/// @param string The string whose length determines the display duration.
|
||||||
|
/// @return A time interval representing the display duration.
|
||||||
|
+ (NSTimeInterval)displayDurationForString:(nullable NSString*)string;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
1524
Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m
generated
Normal file
14
Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// SVRadialGradientLayer.h
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2023 Tobias Totzek and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
|
@interface SVRadialGradientLayer : CALayer
|
||||||
|
|
||||||
|
@property (nonatomic) CGPoint gradientCenter;
|
||||||
|
|
||||||
|
@end
|
||||||
25
Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m
generated
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// SVRadialGradientLayer.m
|
||||||
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2023 Tobias Totzek and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "SVRadialGradientLayer.h"
|
||||||
|
|
||||||
|
@implementation SVRadialGradientLayer
|
||||||
|
|
||||||
|
- (void)drawInContext:(CGContextRef)context {
|
||||||
|
size_t locationsCount = 2;
|
||||||
|
CGFloat locations[2] = {0.0f, 1.0f};
|
||||||
|
CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f};
|
||||||
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
|
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
|
||||||
|
CGColorSpaceRelease(colorSpace);
|
||||||
|
|
||||||
|
float radius = MIN(self.bounds.size.width , self.bounds.size.height);
|
||||||
|
CGContextDrawRadialGradient (context, gradient, self.gradientCenter, 0, self.gradientCenter, radius, kCGGradientDrawsAfterEndLocation);
|
||||||
|
CGGradientRelease(gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
26
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet-Info.plist
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.8.1</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
5
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet-dummy.m
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
@interface PodsDummy_DZNEmptyDataSet : NSObject
|
||||||
|
@end
|
||||||
|
@implementation PodsDummy_DZNEmptyDataSet
|
||||||
|
@end
|
||||||
12
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet-prefix.pch
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
17
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet-umbrella.h
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#import "UIScrollView+EmptyDataSet.h"
|
||||||
|
|
||||||
|
FOUNDATION_EXPORT double DZNEmptyDataSetVersionNumber;
|
||||||
|
FOUNDATION_EXPORT const unsigned char DZNEmptyDataSetVersionString[];
|
||||||
|
|
||||||
13
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet.debug.xcconfig
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "UIKit"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/DZNEmptyDataSet
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
6
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet.modulemap
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
framework module DZNEmptyDataSet {
|
||||||
|
umbrella header "DZNEmptyDataSet-umbrella.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
13
Pods/Target Support Files/DZNEmptyDataSet/DZNEmptyDataSet.release.xcconfig
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "UIKit"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/DZNEmptyDataSet
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
26
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage-Info.plist
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0.17</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
5
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage-dummy.m
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
@interface PodsDummy_FLAnimatedImage : NSObject
|
||||||
|
@end
|
||||||
|
@implementation PodsDummy_FLAnimatedImage
|
||||||
|
@end
|
||||||
12
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage-prefix.pch
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
18
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage-umbrella.h
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#import "FLAnimatedImage.h"
|
||||||
|
#import "FLAnimatedImageView.h"
|
||||||
|
|
||||||
|
FOUNDATION_EXPORT double FLAnimatedImageVersionNumber;
|
||||||
|
FOUNDATION_EXPORT const unsigned char FLAnimatedImageVersionString[];
|
||||||
|
|
||||||
13
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage.debug.xcconfig
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "ImageIO" -framework "QuartzCore"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/FLAnimatedImage
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
6
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage.modulemap
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
framework module FLAnimatedImage {
|
||||||
|
umbrella header "FLAnimatedImage-umbrella.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
13
Pods/Target Support Files/FLAnimatedImage/FLAnimatedImage.release.xcconfig
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "ImageIO" -framework "QuartzCore"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/FLAnimatedImage
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
@@ -130,6 +130,44 @@ SOFTWARE.
|
|||||||
Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved.
|
Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
## DZNEmptyDataSet
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
## FLAnimatedImage
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2016 Flipboard
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
## FMDB
|
## FMDB
|
||||||
|
|
||||||
If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
||||||
@@ -2221,6 +2259,31 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
|
## SVProgressHUD
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
## TIMCommon
|
## TIMCommon
|
||||||
|
|
||||||
copyright 2017 tencent Ltd. All rights reserved.
|
copyright 2017 tencent Ltd. All rights reserved.
|
||||||
@@ -2282,6 +2345,31 @@ SOFTWARE.
|
|||||||
Copyright 2020 tencent.com. All rights reserved.
|
Copyright 2020 tencent.com. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
## XHLaunchAd
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 XHLaunchAd (https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
## YBImageBrowser
|
## YBImageBrowser
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|||||||
@@ -189,6 +189,56 @@ SOFTWARE.
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl
|
||||||
|
|
||||||
|
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>DZNEmptyDataSet</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2016 Flipboard
|
||||||
|
|
||||||
|
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>FLAnimatedImage</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
<string>If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
||||||
@@ -2382,6 +2432,37 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors.
|
||||||
|
|
||||||
|
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>SVProgressHUD</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>copyright 2017 tencent Ltd. All rights reserved.
|
<string>copyright 2017 tencent Ltd. All rights reserved.
|
||||||
@@ -2491,6 +2572,37 @@ SOFTWARE.
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 XHLaunchAd (https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
|
||||||
|
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>XHLaunchAd</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>MIT License
|
<string>MIT License
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ ${BUILT_PRODUCTS_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
||||||
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
||||||
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework
|
||||||
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
||||||
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
||||||
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
||||||
@@ -21,11 +23,13 @@ ${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraLyricsScore.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FLAnimatedImage.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
||||||
@@ -20,11 +22,13 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XHLaunchAd.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ ${BUILT_PRODUCTS_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
||||||
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
||||||
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework
|
||||||
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
||||||
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
||||||
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
||||||
@@ -20,11 +22,13 @@ ${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraLyricsScore.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FLAnimatedImage.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
||||||
@@ -19,11 +21,13 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XHLaunchAd.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
||||||
@@ -198,11 +200,13 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
||||||
@@ -247,6 +251,8 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
||||||
@@ -263,11 +269,13 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
DEFINES_MODULE = YES
|
DEFINES_MODULE = YES
|
||||||
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
||||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool/LLDebugTool.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage/FLAnimatedImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool/LLDebugTool.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd/XHLaunchAd.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
|
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
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "AVKit" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "LLDebugTool" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "MapKit" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "QuickLook" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "AVKit" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "DZNEmptyDataSet" -framework "FLAnimatedImage" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "LLDebugTool" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "MapKit" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "QuickLook" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "SVProgressHUD" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "XHLaunchAd" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
||||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
DEFINES_MODULE = YES
|
DEFINES_MODULE = YES
|
||||||
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
||||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage/FLAnimatedImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd/XHLaunchAd.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
|
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
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "DZNEmptyDataSet" -framework "FLAnimatedImage" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "SVProgressHUD" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "XHLaunchAd" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
||||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
|||||||
@@ -130,6 +130,44 @@ SOFTWARE.
|
|||||||
Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved.
|
Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
## DZNEmptyDataSet
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
## FLAnimatedImage
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2016 Flipboard
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
## FMDB
|
## FMDB
|
||||||
|
|
||||||
If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
||||||
@@ -2221,6 +2259,31 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
|
## SVProgressHUD
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
## TIMCommon
|
## TIMCommon
|
||||||
|
|
||||||
copyright 2017 tencent Ltd. All rights reserved.
|
copyright 2017 tencent Ltd. All rights reserved.
|
||||||
@@ -2282,6 +2345,31 @@ SOFTWARE.
|
|||||||
Copyright 2020 tencent.com. All rights reserved.
|
Copyright 2020 tencent.com. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
## XHLaunchAd
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 XHLaunchAd (https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
## YBImageBrowser
|
## YBImageBrowser
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|||||||
@@ -189,6 +189,56 @@ SOFTWARE.
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ignacio Romero Zurbuchen iromero@dzen.cl
|
||||||
|
|
||||||
|
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>DZNEmptyDataSet</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2016 Flipboard
|
||||||
|
|
||||||
|
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>FLAnimatedImage</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
<string>If you are using FMDB in your project, I'd love to hear about it. Let Gus know
|
||||||
@@ -2382,6 +2432,37 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors.
|
||||||
|
|
||||||
|
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>SVProgressHUD</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>copyright 2017 tencent Ltd. All rights reserved.
|
<string>copyright 2017 tencent Ltd. All rights reserved.
|
||||||
@@ -2491,6 +2572,37 @@ SOFTWARE.
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 XHLaunchAd (https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
|
||||||
|
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>XHLaunchAd</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>MIT License
|
<string>MIT License
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ ${BUILT_PRODUCTS_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
||||||
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
||||||
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework
|
||||||
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
||||||
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
||||||
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
||||||
@@ -21,11 +23,13 @@ ${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraLyricsScore.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FLAnimatedImage.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
||||||
@@ -20,11 +22,13 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XHLaunchAd.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ ${BUILT_PRODUCTS_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework
|
||||||
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework
|
||||||
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework
|
||||||
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework
|
||||||
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
|
||||||
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework
|
||||||
@@ -20,11 +22,13 @@ ${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework
|
|||||||
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework
|
||||||
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework
|
||||||
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework
|
||||||
|
${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework
|
||||||
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraLyricsScore.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AvoidCrash.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BRPickerView.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FLAnimatedImage.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXCategoryView.framework
|
||||||
@@ -19,11 +21,13 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework
|
|||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVGAPlayer.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TIMCommon.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIChat.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUIConversation.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TUICore.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TZImagePickerController.framework
|
||||||
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XHLaunchAd.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YBImageBrowser.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework
|
||||||
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCategories.framework
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
||||||
@@ -198,11 +200,13 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
||||||
@@ -247,6 +251,8 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/AvoidCrash/AvoidCrash.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/BRPickerView/BRPickerView.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/FLAnimatedImage/FLAnimatedImage.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/JXCategoryView/JXCategoryView.framework"
|
||||||
@@ -263,11 +269,13 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
|
|||||||
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/SVGAPlayer/SVGAPlayer.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TIMCommon/TIMCommon.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIChat/TUIChat.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUIConversation/TUIConversation.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TUICore/TUICore.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/TZImagePickerController/TZImagePickerController.framework"
|
||||||
|
install_framework "${BUILT_PRODUCTS_DIR}/XHLaunchAd/XHLaunchAd.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YBImageBrowser/YBImageBrowser.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework"
|
||||||
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/YYCategories/YYCategories.framework"
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
DEFINES_MODULE = YES
|
DEFINES_MODULE = YES
|
||||||
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
||||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool/LLDebugTool.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage/FLAnimatedImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool/LLDebugTool.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd/XHLaunchAd.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
|
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
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "AVKit" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "LLDebugTool" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "MapKit" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "QuickLook" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "AVKit" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "DZNEmptyDataSet" -framework "FLAnimatedImage" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "LLDebugTool" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "MapKit" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "QuickLook" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "SVProgressHUD" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "XHLaunchAd" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
||||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/LLDebugTool" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
DEFINES_MODULE = YES
|
DEFINES_MODULE = YES
|
||||||
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_CONFIGURATION_BUILD_DIR}/YYText" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/Zip" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp" "${PODS_ROOT}/../TencentCloudHuiyanSDKFace_framework/Libs" "${PODS_ROOT}/AgoraComponetLog" "${PODS_ROOT}/AgoraInfra_iOS" "${PODS_ROOT}/AgoraRtcEngine_iOS" "${PODS_ROOT}/AlipaySDK-iOS" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/TIMPush" "${PODS_ROOT}/TXIMSDK_Plus_iOS_XCFramework" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_ROOT}/YYImage/Vendor" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraComponetLog" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraInfra_iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAEC" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AIAECLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINSLL" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AudioBeauty" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ClearVision" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceCapture" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FaceDetection" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/LipSync" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VQA" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoAv1CodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecDec" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoCodecEnc" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AlipaySDK-iOS" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TIMPush" "${PODS_XCFRAMEWORKS_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) SD_WEBP=1
|
||||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore/AgoraLyricsScore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash/AvoidCrash.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView/BRPickerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage/FLAnimatedImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FMDB/FMDB.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView/JXCategoryView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient/MQTTClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf/Protobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore/QCloudCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer/QGVAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView/SDCycleScrollView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer/SVGAPlayer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon/TIMCommon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIChat/TUIChat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation/TUIConversation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TUICore/TUICore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController/TZImagePickerController.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd/XHLaunchAd.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser/YBImageBrowser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCache/YYCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYImage/YYImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYText/YYText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage/YYWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zip/Zip.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/libwebp/libwebp.framework/Headers" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/Headers" **/TIMPush.xcframework/ios-arm64/TIMPush.framework/Headers/*.h
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
|
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
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework" "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"WechatOpenSDK" -l"c++" -l"iconv" -l"resolv" -l"sqlite3" -l"sqlite3.0" -l"z" -framework "AFNetworking" -framework "AVFoundation" -framework "Accelerate" -framework "AgoraAiEchoCancellationExtension" -framework "AgoraAiEchoCancellationLLExtension" -framework "AgoraAiNoiseSuppressionExtension" -framework "AgoraAiNoiseSuppressionLLExtension" -framework "AgoraAudioBeautyExtension" -framework "AgoraClearVisionExtension" -framework "AgoraComponetLog" -framework "AgoraContentInspectExtension" -framework "AgoraFaceCaptureExtension" -framework "AgoraFaceDetectionExtension" -framework "AgoraLipSyncExtension" -framework "AgoraLyricsScore" -framework "AgoraReplayKitExtension" -framework "AgoraRtcKit" -framework "AgoraSoundTouch" -framework "AgoraSpatialAudioExtension" -framework "AgoraVideoAv1DecoderExtension" -framework "AgoraVideoAv1EncoderExtension" -framework "AgoraVideoDecoderExtension" -framework "AgoraVideoEncoderExtension" -framework "AgoraVideoQualityAnalyzerExtension" -framework "AgoraVideoSegmentationExtension" -framework "Agorafdkaac" -framework "Agoraffmpeg" -framework "AlipaySDK" -framework "AliyunOSSiOS" -framework "AssetsLibrary" -framework "AvoidCrash" -framework "BRPickerView" -framework "Bugly" -framework "CFNetwork" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreMedia" -framework "CoreMotion" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "DZNEmptyDataSet" -framework "FLAnimatedImage" -framework "FMDB" -framework "Foundation" -framework "IQKeyboardManager" -framework "ImSDK_Plus" -framework "ImageIO" -framework "JXCategoryView" -framework "JXPagingView" -framework "MBProgressHUD" -framework "MJRefresh" -framework "MQTTClient" -framework "Masonry" -framework "MediaPlayer" -framework "Metal" -framework "MetalKit" -framework "MobileCoreServices" -framework "Photos" -framework "PhotosUI" -framework "Protobuf" -framework "QCloudCOSXML" -framework "QCloudCore" -framework "QGVAPlayer" -framework "QuartzCore" -framework "ReactiveObjC" -framework "SDCycleScrollView" -framework "SDWebImage" -framework "SDWebImageWebPCoder" -framework "SSZipArchive" -framework "SVGAPlayer" -framework "SVProgressHUD" -framework "Security" -framework "SystemConfiguration" -framework "TIMCommon" -framework "TIMPush" -framework "TUIChat" -framework "TUIConversation" -framework "TUICore" -framework "TZImagePickerController" -framework "TencentCloudHuiyanSDKFace" -framework "TuringShieldCamRisk" -framework "UIKit" -framework "VideoToolbox" -framework "WebKit" -framework "XHLaunchAd" -framework "YBImageBrowser" -framework "YTCommonLiveness" -framework "YTCv" -framework "YTFaceAlignmentTinyLiveness" -framework "YTFaceDetectorLiveness" -framework "YTFaceLiveReflect" -framework "YTFaceTrackerLiveness" -framework "YTPoseDetector" -framework "YYCache" -framework "YYCategories" -framework "YYImage" -framework "YYModel" -framework "YYText" -framework "YYWebImage" -framework "YtSDKKitFrameworkTool" -framework "Zip" -framework "aosl" -framework "libwebp" -framework "tnnliveness" -framework "video_dec" -framework "video_enc" -weak_framework "AgoraAiEchoCancellationExtension" -weak_framework "AgoraAiEchoCancellationLLExtension" -weak_framework "AgoraAiNoiseSuppressionExtension" -weak_framework "AgoraAiNoiseSuppressionLLExtension" -weak_framework "AgoraAudioBeautyExtension" -weak_framework "AgoraClearVisionExtension" -weak_framework "AgoraContentInspectExtension" -weak_framework "AgoraFaceCaptureExtension" -weak_framework "AgoraFaceDetectionExtension" -weak_framework "AgoraLipSyncExtension" -weak_framework "AgoraReplayKitExtension" -weak_framework "AgoraRtcKit" -weak_framework "AgoraSoundTouch" -weak_framework "AgoraSpatialAudioExtension" -weak_framework "AgoraVideoAv1DecoderExtension" -weak_framework "AgoraVideoAv1EncoderExtension" -weak_framework "AgoraVideoDecoderExtension" -weak_framework "AgoraVideoEncoderExtension" -weak_framework "AgoraVideoQualityAnalyzerExtension" -weak_framework "AgoraVideoSegmentationExtension" -weak_framework "Agorafdkaac" -weak_framework "Agoraffmpeg" -weak_framework "video_dec" -weak_framework "video_enc"
|
||||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraComponetLog" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraInfra_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraLyricsScore" "-F${PODS_CONFIGURATION_BUILD_DIR}/AgoraRtcEngine_iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AlipaySDK-iOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AliyunOSSiOS" "-F${PODS_CONFIGURATION_BUILD_DIR}/AvoidCrash" "-F${PODS_CONFIGURATION_BUILD_DIR}/BRPickerView" "-F${PODS_CONFIGURATION_BUILD_DIR}/Bugly" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/FMDB" "-F${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXCategoryView" "-F${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "-F${PODS_CONFIGURATION_BUILD_DIR}/MQTTClient" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML" "-F${PODS_CONFIGURATION_BUILD_DIR}/QCloudCore" "-F${PODS_CONFIGURATION_BUILD_DIR}/QGVAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDCycleScrollView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImageWebPCoder" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVGAPlayer" "-F${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMCommon" "-F${PODS_CONFIGURATION_BUILD_DIR}/TIMPush" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIChat" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUIConversation" "-F${PODS_CONFIGURATION_BUILD_DIR}/TUICore" "-F${PODS_CONFIGURATION_BUILD_DIR}/TXIMSDK_Plus_iOS_XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/TZImagePickerController" "-F${PODS_CONFIGURATION_BUILD_DIR}/TencentCloudHuiyanSDKFace_framework" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework" "-F${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd" "-F${PODS_CONFIGURATION_BUILD_DIR}/YBImageBrowser" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCache" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYText" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/Zip" "-F${PODS_CONFIGURATION_BUILD_DIR}/libwebp"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
|||||||
26
Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>2.3.1</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
5
Pods/Target Support Files/SVProgressHUD/SVProgressHUD-dummy.m
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
@interface PodsDummy_SVProgressHUD : NSObject
|
||||||
|
@end
|
||||||
|
@implementation PodsDummy_SVProgressHUD
|
||||||
|
@end
|
||||||
12
Pods/Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
20
Pods/Target Support Files/SVProgressHUD/SVProgressHUD-umbrella.h
generated
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#import "SVIndefiniteAnimatedView.h"
|
||||||
|
#import "SVProgressAnimatedView.h"
|
||||||
|
#import "SVProgressHUD.h"
|
||||||
|
#import "SVRadialGradientLayer.h"
|
||||||
|
|
||||||
|
FOUNDATION_EXPORT double SVProgressHUDVersionNumber;
|
||||||
|
FOUNDATION_EXPORT const unsigned char SVProgressHUDVersionString[];
|
||||||
|
|
||||||
13
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "QuartzCore"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SVProgressHUD
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
6
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.modulemap
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
framework module SVProgressHUD {
|
||||||
|
umbrella header "SVProgressHUD-umbrella.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
13
Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "QuartzCore"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SVProgressHUD
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
26
Pods/Target Support Files/XHLaunchAd/XHLaunchAd-Info.plist
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>3.9.12</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
5
Pods/Target Support Files/XHLaunchAd/XHLaunchAd-dummy.m
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
@interface PodsDummy_XHLaunchAd : NSObject
|
||||||
|
@end
|
||||||
|
@implementation PodsDummy_XHLaunchAd
|
||||||
|
@end
|
||||||
12
Pods/Target Support Files/XHLaunchAd/XHLaunchAd-prefix.pch
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
27
Pods/Target Support Files/XHLaunchAd/XHLaunchAd-umbrella.h
generated
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#import "XHLaunchAd.h"
|
||||||
|
#import "XHLaunchAdButton.h"
|
||||||
|
#import "XHLaunchAdCache.h"
|
||||||
|
#import "XHLaunchAdConfiguration.h"
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
#import "XHLaunchAdController.h"
|
||||||
|
#import "XHLaunchAdDownloader.h"
|
||||||
|
#import "XHLaunchAdImageManager.h"
|
||||||
|
#import "XHLaunchAdImageView+XHLaunchAdCache.h"
|
||||||
|
#import "XHLaunchAdView.h"
|
||||||
|
#import "XHLaunchImageView.h"
|
||||||
|
|
||||||
|
FOUNDATION_EXPORT double XHLaunchAdVersionNumber;
|
||||||
|
FOUNDATION_EXPORT const unsigned char XHLaunchAdVersionString[];
|
||||||
|
|
||||||
14
Pods/Target Support Files/XHLaunchAd/XHLaunchAd.debug.xcconfig
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd
|
||||||
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage"
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "FLAnimatedImage" -framework "ImageIO" -framework "QuartzCore"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/XHLaunchAd
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
6
Pods/Target Support Files/XHLaunchAd/XHLaunchAd.modulemap
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
framework module XHLaunchAd {
|
||||||
|
umbrella header "XHLaunchAd-umbrella.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
14
Pods/Target Support Files/XHLaunchAd/XHLaunchAd.release.xcconfig
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/XHLaunchAd
|
||||||
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FLAnimatedImage"
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "FLAnimatedImage" -framework "ImageIO" -framework "QuartzCore"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/XHLaunchAd
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
21
Pods/XHLaunchAd/LICENSE
generated
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 XHLaunchAd (https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
|
||||||
|
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.
|
||||||
696
Pods/XHLaunchAd/README.md
generated
Normal file
@@ -0,0 +1,696 @@
|
|||||||
|

|
||||||
|
|
||||||
|
### Github下载不了/下载慢 可以访问国内下载地址: [https://gitee.com/CoderZhuXH/XHLaunchAd](https://gitee.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
|
||||||
|
### 开屏广告、启动广告解决方案-支持静态/动态图片广告/mp4视频广告
|
||||||
|
|
||||||
|
[](https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
[](http://cocoadocs.org/docsets/XHLaunchAd)
|
||||||
|
[](https://github.com/CoderZhuXH/XHLaunchAd)
|
||||||
|
[](http://cocoadocs.org/docsets/XHLaunchAd/)
|
||||||
|
[](https://github.com/CoderZhuXH/XHLaunchAd/blob/master/LICENSE)
|
||||||
|
|
||||||
|
### 特性:
|
||||||
|
|
||||||
|
* 1.支持静态/动态图片广告.
|
||||||
|
* 2.支持mp4视频广告.
|
||||||
|
* 3.支持全屏/半屏广告.
|
||||||
|
* 4.支持网络及本地资源.
|
||||||
|
* 5.兼容iPhone和iPad.
|
||||||
|
* 6.支持广告点击事件.
|
||||||
|
* 7.支持自定义跳过按钮,添加子视图.
|
||||||
|
* 8.支持设置数据等待时间.
|
||||||
|
* 9.自带图片/视频下载,缓存功能.
|
||||||
|
* 10.支持预缓存图片及视频.
|
||||||
|
* 11.支持设置完成动画.
|
||||||
|
* 12.支持清除指定资源缓存.
|
||||||
|
* 13.支持LaunchImage 和 LaunchScreen.storyboard.
|
||||||
|
* 14.等等等...
|
||||||
|
|
||||||
|
### 技术交流群(群号:537476189)
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
#### 1.为什么设置了本地图片广告,却提示找不到图片资源?
|
||||||
|
* 请将本地广告图片,直接放在工程目录,不要放在Assets里面,XHLaunchAd不是通过imageName:读取图片,而是是通过[NSBundle mainBundle] path....的方式读取本地图片的(此处涉及到内存优化)
|
||||||
|
|
||||||
|
#### 2.为什么我启动的时候会先进入根控制器后,再显示广告页面?
|
||||||
|
* 请确认下,你在请求广告数据之前,是否有调用`[XHLaunchAd setWaitDataDuration:2];`方法设置数据等待时间
|
||||||
|
|
||||||
|
#### 3.为什么有时候启动广告倒计时出现跳秒现象或者出现卡顿现象?
|
||||||
|
* 此问题是你APP启动时主线程阻塞造成的.
|
||||||
|
* XHLaunchAd采用GCD定时器,倒计时不受主线程阻塞影响,但更新秒数/UI是在主线程中进行的.主线程阻塞影响UI更新.
|
||||||
|
* 请检查你程序启动时,有没有掉用同步方法或同步请求,(例如:环信SDK同步登录等).
|
||||||
|
* 建议打开手机-设置-开发者-弱网环境 进行调试比较容易找到阻塞原因.
|
||||||
|
|
||||||
|
#### 4.为什么设置了缓存策略,关闭网络后,开屏广告却不显示?
|
||||||
|
* XHLaunchAd 图片广告设置configuration.imageOption为XHLaunchAdImageDefault 或者XHLaunchAdImageRefreshCached 或者XHLaunchAdImageCacheInBackground后,都会缓存广告image,视频广告会默认缓存视频文件,断网后广告数据请求会失败,你需要在广告数据请求失败的回调里初始化XHLaunchAd,没有初始化XHLaunchAd,开屏广告是不会显示的.
|
||||||
|
[XHLaunchAd cacheImageURLString]和 [XHLaunchAd cacheVideoURLString]可以获取上一次广告显示时的ImageURLString和videoUrlString.
|
||||||
|
|
||||||
|
#### 5.如何用一张广告图,适配所有机型?
|
||||||
|
* 图片广告:设置imageAdconfiguration.contentMode = UIViewContentModeScaleAspectFill; 视频广告:设置videoAdconfiguration.videoGravity = AVLayerVideoGravityResizeAspectFill;.
|
||||||
|
* 广告图片/视频内容到四周保留适当安全距离,多余的会裁剪掉,例如:用8P尺寸1242*2208的广告图,在iphonex,iphonexr,iphonexs,iphonexs max上显示时,左右两侧会多出一部分,多出的的部分会裁剪掉,这一区域不要放广告内容.
|
||||||
|
|
||||||
|
|
||||||
|
### 更新记录:
|
||||||
|
|
||||||
|
* 2020.01.09 -- v3.9.10 -->1.广告点击事件代理支持返回bool值决定是否移除广告(- (BOOL)xhLaunchAd:(XHLaunchAd *)launchAd clickAtOpenModel:(id)openModel clickPoint:(CGPoint)clickPoint) 2.LaunchScreen.storyboard safeAreaInsets问题修复 3.其他bug fix
|
||||||
|
* 2018.01.31 -- v3.9.6 -->1.添加视频广告静音属性(muted),2.显示视频广告时暂停其它APP音频播放显示完恢复,3.增加视频播放失败通知
|
||||||
|
* 2018.01.11 -- v3.9.5 -->1.修复videoGravity修饰符错误bug...
|
||||||
|
* 2017.12.29 -- v3.9.4 -->1.替换视频播放控制器为AVPlayerViewController 2.解决/优化在线程阻塞的情况下视频播放加载慢的问题 3.注意:此次更新后XHLaunchAd支持iOS8及以上版本,不在支持iOS7...
|
||||||
|
* 2017.11.22 -- v3.9.0 -->1.新增部分代理方法,部分旧的代理方法做过期处理,2.几处优化...
|
||||||
|
* 2017.11.14 -- v3.8.4 -->1.版本优化,2.bug fix...
|
||||||
|
* 2017.10.18 -- v3.8.0 -->1.增加对LaunchScreen.storyboard支持,2.修复pod导入编译报错问题...
|
||||||
|
* 2017.10.11 -- v3.7.1 -->1.批量缓存接口增加结果回调...
|
||||||
|
* 2017.10.09 -- v3.7.0 -->1.增加几种清除缓存的接口,2.增加几种倒计时按钮类型,3.已知问题优化与修复...
|
||||||
|
* 2017.09.29 -- v3.6.1 -->1.增加清除指定图片/视频缓存接口,2.优化在iPhoneX上显示效果,3.已知问题优化与修复...
|
||||||
|
* 2017.09.18 -- v3.6.0 -->1.优化图片解码方案,2.支持设置GIF动图是否循环播放...
|
||||||
|
* 2017.09.13 -- v3.5.8 -->增加几种显示完成的动画...
|
||||||
|
* 2017.08.20 -- v3.5.6 -->已知问题修复及内存优化...
|
||||||
|
* 2017.05.26 -- v3.5.4 -->修复横屏启动造成的界面问题...
|
||||||
|
* 2017.05.02 -- v3.5.0 -->Gif动图占用内存优化...
|
||||||
|
* 2017.04.26 -- v3.4.6 -->版本优化,bug fix...
|
||||||
|
* 2017.02.17 -- v3.4.0 -->修复部分出现Crash Bug...
|
||||||
|
* 2016.12.14 -- v3.2.0 -->添加subViews属性2.添加缓存检测...
|
||||||
|
* 2016.12.03 -- v3.0.0 -->1.增加mp4视频开屏广告2.增加对本地资源支持3.增加预缓存接口4.增加更多属性及接口,具有更强的自定义性5.可设置显示完成动画类型6.可自定义跳过按钮7.拥有更优雅的接入接口8.优化缓存机制,bug fix等等...
|
||||||
|
* 2016.11.05 -- v2.2.0 -->增加一种缓存方案:先缓存,下次显示.<br>
|
||||||
|
* 2016.09.13 -- v2.1.8 -->修复在Swift中使用异常.<br>
|
||||||
|
* 2016.09.10 -- v2.1.7 -->适配iPad,增加应用内跳转到广告详情,优化.<br>
|
||||||
|
* 2016.09.07 -- v2.1.5 -->修复跳过按钮类型设为None无效问题.<br>
|
||||||
|
* 2016.09.01 -- v2.1.4 -->广告url传nil或不合法时,按无数据处理.<br>
|
||||||
|
* 2016.08.22 -- v2.1.2 -->增加未检测到广告数据,设置启动页停留时间属性.<br>
|
||||||
|
* 2016.08.19 -- v2.1.1 -->跳过按钮bug修复.<br>
|
||||||
|
* 2016.08.18 -- v2.1.0 -->API微调,增加设置跳过按钮类型选项.<br>
|
||||||
|
* 2016.08.16 -- v2.0 -->1.修复显示广告前RootViewController闪现bug; 2.API重构,增强实用性.<br>
|
||||||
|
* 2016.07.18 -- v1.2 -->增加对GIF动态广告的支持.<br>
|
||||||
|
* 2016.07.02 -- v1.1.2 -->增加设置缓存机制选项.<br>
|
||||||
|
* 2016.06.17 -- v1.1 -->增加倒计时/跳过按钮.<br>
|
||||||
|
* 2016.06.13 -- v1.0
|
||||||
|
|
||||||
|
## 效果
|
||||||
|
|
||||||
|
### 静态/动态广告-图片/视频广告
|
||||||
|
|
||||||
|
  
|
||||||
|
  
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 1.在didFinishLaunchingWithOptions中或UIApplicationDidFinishLaunching时初始化开屏广告
|
||||||
|
|
||||||
|
### -1.1 添加图片开屏广告-使用本地数据
|
||||||
|
#### -1.1.1 使用默认配置快速初始化
|
||||||
|
```objc
|
||||||
|
//1.使用默认配置初始化
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchImageAdConfiguration *imageAdconfiguration = [XHLaunchImageAdConfiguration defaultConfiguration];
|
||||||
|
//广告图片URLString/或本地图片名(.jpg/.gif请带上后缀)
|
||||||
|
imageAdconfiguration.imageNameOrURLString = @"image0.jpg";
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
imageAdconfiguration.openModel = @"http://www.it7090.com";
|
||||||
|
//显示图片开屏广告
|
||||||
|
[XHLaunchAd imageAdWithImageAdConfiguration:imageAdconfiguration delegate:self];
|
||||||
|
```
|
||||||
|
#### -1.1.2自定义配置初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
//2.自定义配置初始化
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchImageAdConfiguration *imageAdconfiguration = [XHLaunchImageAdConfiguration new];
|
||||||
|
//广告停留时间
|
||||||
|
imageAdconfiguration.duration = 5;
|
||||||
|
//广告frame
|
||||||
|
imageAdconfiguration.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-150);
|
||||||
|
//广告图片URLString/或本地图片名(.jpg/.gif请带上后缀)
|
||||||
|
imageAdconfiguration.imageNameOrURLString = @"image0.jpg";
|
||||||
|
//设置GIF动图是否只循环播放一次(仅对动图设置有效)
|
||||||
|
imageAdconfiguration.GIFImageCycleOnce = NO;
|
||||||
|
//网络图片缓存机制(只对网络图片有效)
|
||||||
|
imageAdconfiguration.imageOption = XHLaunchAdImageRefreshCached;
|
||||||
|
//图片填充模式
|
||||||
|
imageAdconfiguration.contentMode = UIViewContentModeScaleToFill;
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
imageAdconfiguration.openModel = @"http://www.it7090.com";
|
||||||
|
//广告显示完成动画
|
||||||
|
imageAdconfiguration.showFinishAnimate =ShowFinishAnimateFadein;
|
||||||
|
//广告显示完成动画时间
|
||||||
|
imageAdconfiguration.showFinishAnimateTime = 0.8;
|
||||||
|
//跳过按钮类型
|
||||||
|
imageAdconfiguration.skipButtonType = SkipTypeTimeText;
|
||||||
|
//后台返回时,是否显示广告
|
||||||
|
imageAdconfiguration.showEnterForeground = NO;
|
||||||
|
|
||||||
|
//设置要添加的子视图(可选)
|
||||||
|
//imageAdconfiguration.subViews = ...
|
||||||
|
|
||||||
|
//显示图片开屏广告
|
||||||
|
[XHLaunchAd imageAdWithImageAdConfiguration:imageAdconfiguration delegate:self];
|
||||||
|
|
||||||
|
```
|
||||||
|
### -1.2 添加图片开屏广告-使用网络数据
|
||||||
|
#### -1.2.1 使用默认配置快速初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//1.因为数据请求是异步的,请在数据请求前,调用下面方法配置数据等待时间.
|
||||||
|
//2.设为2即表示:启动页将停留2s等待服务器返回广告数据,2s内等到广告数据,将正常显示广告,否则将不显示
|
||||||
|
//3.数据获取成功,配置广告数据后,自动结束等待,显示广告
|
||||||
|
//注意:请求广告数据前,必须设置此属性,否则会先进入window的的根控制器
|
||||||
|
[XHLaunchAd setWaitDataDuration:2];
|
||||||
|
|
||||||
|
//广告数据请求
|
||||||
|
[Network getLaunchAdImageDataSuccess:^(NSDictionary * response) {
|
||||||
|
|
||||||
|
NSLog(@"广告数据 = %@",response);
|
||||||
|
|
||||||
|
//广告数据转模型
|
||||||
|
LaunchAdModel *model = [[LaunchAdModel alloc] initWithDict:response[@"data"]];
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchImageAdConfiguration *imageAdconfiguration = [XHLaunchImageAdConfiguration defaultConfiguration];
|
||||||
|
//广告图片URLString/或本地图片名(.jpg/.gif请带上后缀)
|
||||||
|
imageAdconfiguration.imageNameOrURLString = model.content;
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
imageAdconfiguration.openModel = model.openUrl;
|
||||||
|
//显示开屏广告
|
||||||
|
[XHLaunchAd imageAdWithImageAdConfiguration:imageAdconfiguration delegate:self];
|
||||||
|
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
#### -1.2.2 自定义配置初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//1.因为数据请求是异步的,请在数据请求前,调用下面方法配置数据等待时间.
|
||||||
|
//2.设为2即表示:启动页将停留2s等待服务器返回广告数据,2s内等到广告数据,将正常显示广告,否则将不显示
|
||||||
|
//3.数据获取成功,配置广告数据后,自动结束等待,显示广告
|
||||||
|
//注意:请求广告数据前,必须设置此属性,否则会先进入window的的根控制器
|
||||||
|
[XHLaunchAd setWaitDataDuration:2];
|
||||||
|
|
||||||
|
//广告数据请求
|
||||||
|
[Network getLaunchAdImageDataSuccess:^(NSDictionary * response) {
|
||||||
|
|
||||||
|
NSLog(@"广告数据 = %@",response);
|
||||||
|
|
||||||
|
//广告数据转模型
|
||||||
|
LaunchAdModel *model = [[LaunchAdModel alloc] initWithDict:response[@"data"]];
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchImageAdConfiguration *imageAdconfiguration = [XHLaunchImageAdConfiguration new];
|
||||||
|
//广告停留时间
|
||||||
|
imageAdconfiguration.duration = model.duration;
|
||||||
|
//广告frame
|
||||||
|
imageAdconfiguration.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width/model.width*model.height);
|
||||||
|
//广告图片URLString/或本地图片名(.jpg/.gif请带上后缀)
|
||||||
|
imageAdconfiguration.imageNameOrURLString = model.content;
|
||||||
|
//设置GIF动图是否只循环播放一次(仅对动图设置有效)
|
||||||
|
imageAdconfiguration.GIFImageCycleOnce = NO;
|
||||||
|
//缓存机制(仅对网络图片有效)
|
||||||
|
//为告展示效果更好,可设置为XHLaunchAdImageCacheInBackground,先缓存,下次显示
|
||||||
|
imageAdconfiguration.imageOption = XHLaunchAdImageDefault;
|
||||||
|
//图片填充模式
|
||||||
|
imageAdconfiguration.contentMode = UIViewContentModeScaleToFill;
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
imageAdconfiguration.openModel = model.openUrl;
|
||||||
|
//广告显示完成动画
|
||||||
|
imageAdconfiguration.showFinishAnimate =ShowFinishAnimateLite;
|
||||||
|
//广告显示完成动画时间
|
||||||
|
imageAdconfiguration.showFinishAnimateTime = 0.8;
|
||||||
|
//跳过按钮类型
|
||||||
|
imageAdconfiguration.skipButtonType = SkipTypeTimeText;
|
||||||
|
//后台返回时,是否显示广告
|
||||||
|
imageAdconfiguration.showEnterForeground = NO;
|
||||||
|
|
||||||
|
//设置要添加的自定义视图(可选)
|
||||||
|
//imageAdconfiguration.subViews = ...
|
||||||
|
|
||||||
|
//显示开屏广告
|
||||||
|
[XHLaunchAd imageAdWithImageAdConfiguration:imageAdconfiguration delegate:self];
|
||||||
|
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
}];
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### -1.3添加视频开屏广告-使用本地数据
|
||||||
|
#### -1.3.1 使用默认配置快速初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//1.使用默认配置初始化
|
||||||
|
XHLaunchVideoAdConfiguration *videoAdconfiguration = [XHLaunchVideoAdConfiguration defaultConfiguration];
|
||||||
|
//广告视频URLString/或本地视频名(请带上后缀)
|
||||||
|
videoAdconfiguration.videoNameOrURLString = @"video0.mp4";
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
videoAdconfiguration.openModel = @"http://www.it7090.com";
|
||||||
|
//显示视频开屏广告
|
||||||
|
[XHLaunchAd videoAdWithVideoAdConfiguration:videoAdconfiguration delegate:self];
|
||||||
|
```
|
||||||
|
|
||||||
|
#### -1.3.2 自定义配置初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//2.自定义配置
|
||||||
|
XHLaunchVideoAdConfiguration *videoAdconfiguration = [XHLaunchVideoAdConfiguration new];
|
||||||
|
//广告停留时间
|
||||||
|
videoAdconfiguration.duration = 5;
|
||||||
|
//广告frame
|
||||||
|
videoAdconfiguration.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
|
||||||
|
//广告视频URLString/或本地视频名(请带上后缀)
|
||||||
|
videoAdconfiguration.videoNameOrURLString = @"video1.mp4";
|
||||||
|
//是否关闭音频
|
||||||
|
videoAdconfiguration.muted = NO;
|
||||||
|
//视频填充模式
|
||||||
|
videoAdconfiguration.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||||
|
//是否只循环播放一次
|
||||||
|
videoAdconfiguration.videoCycleOnce = NO;
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
videoAdconfiguration.openModel = @"http://www.it7090.com";
|
||||||
|
//广告显示完成动画
|
||||||
|
videoAdconfiguration.showFinishAnimate =ShowFinishAnimateFadein;
|
||||||
|
//广告显示完成动画时间
|
||||||
|
videoAdconfiguration.showFinishAnimateTime = 0.8;
|
||||||
|
//跳过按钮类型
|
||||||
|
videoAdconfiguration.skipButtonType = SkipTypeTimeText;
|
||||||
|
//后台返回时,是否显示广告
|
||||||
|
videoAdconfiguration.showEnterForeground = NO;
|
||||||
|
|
||||||
|
//设置要添加的子视图(可选)
|
||||||
|
//videoAdconfiguration.subViews = ...
|
||||||
|
|
||||||
|
//显示视频开屏广告
|
||||||
|
[XHLaunchAd videoAdWithVideoAdConfiguration:videoAdconfiguration delegate:self];
|
||||||
|
|
||||||
|
```
|
||||||
|
### -1.4添加视频开屏广告-使用网络数据
|
||||||
|
#### -1.4.1 使用默认配置快速初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//1.因为数据请求是异步的,请在数据请求前,调用下面方法配置数据等待时间.
|
||||||
|
//2.设为2即表示:启动页将停留2s等待服务器返回广告数据,2s内等到广告数据,将正常显示广告,否则将不显示
|
||||||
|
//3.数据获取成功,配置广告数据后,自动结束等待,显示广告
|
||||||
|
//注意:请求广告数据前,必须设置此属性,否则会先进入window的的根控制器
|
||||||
|
[XHLaunchAd setWaitDataDuration:2];
|
||||||
|
|
||||||
|
//广告数据请求
|
||||||
|
[Network getLaunchAdVideoDataSuccess:^(NSDictionary * response) {
|
||||||
|
|
||||||
|
NSLog(@"广告数据 = %@",response);
|
||||||
|
|
||||||
|
//广告数据转模型
|
||||||
|
LaunchAdModel *model = [[LaunchAdModel alloc] initWithDict:response[@"data"]];
|
||||||
|
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchVideoAdConfiguration *videoAdconfiguration = [XHLaunchVideoAdConfiguration defaultConfiguration];
|
||||||
|
//注意:视频广告只支持先缓存,下次显示(看效果请二次运行)
|
||||||
|
videoAdconfiguration.videoNameOrURLString = model.content;
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
videoAdconfiguration.openModel = model.openUrl;
|
||||||
|
[XHLaunchAd videoAdWithVideoAdConfiguration:videoAdconfiguration delegate:self];
|
||||||
|
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
#### -1.4.2 自定义配置初始化
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
//设置你工程的启动页使用的是:LaunchImage 还是 LaunchScreen.storyboard(不设置默认:LaunchImage)
|
||||||
|
[XHLaunchAd setLaunchSourceType:SourceTypeLaunchImage];
|
||||||
|
|
||||||
|
//1.因为数据请求是异步的,请在数据请求前,调用下面方法配置数据等待时间.
|
||||||
|
//2.设为2即表示:启动页将停留2s等待服务器返回广告数据,2s内等到广告数据,将正常显示广告,否则将不显示
|
||||||
|
//3.数据获取成功,配置广告数据后,自动结束等待,显示广告
|
||||||
|
//注意:请求广告数据前,必须设置此属性,否则会先进入window的的根控制器
|
||||||
|
[XHLaunchAd setWaitDataDuration:2];
|
||||||
|
|
||||||
|
//广告数据请求
|
||||||
|
[Network getLaunchAdVideoDataSuccess:^(NSDictionary * response) {
|
||||||
|
|
||||||
|
NSLog(@"广告数据 = %@",response);
|
||||||
|
|
||||||
|
//广告数据转模型
|
||||||
|
LaunchAdModel *model = [[LaunchAdModel alloc] initWithDict:response[@"data"]];
|
||||||
|
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchVideoAdConfiguration *videoAdconfiguration = [XHLaunchVideoAdConfiguration new];
|
||||||
|
//广告停留时间
|
||||||
|
videoAdconfiguration.duration = model.duration;
|
||||||
|
//广告frame
|
||||||
|
videoAdconfiguration.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width/model.width*model.height);
|
||||||
|
//广告视频URLString/或本地视频名(请带上后缀)
|
||||||
|
//注意:视频广告只支持先缓存,下次显示(看效果请二次运行)
|
||||||
|
videoAdconfiguration.videoNameOrURLString = model.content;
|
||||||
|
//是否关闭音频
|
||||||
|
videoAdconfiguration.muted = NO;
|
||||||
|
//视频填充模式
|
||||||
|
videoAdconfiguration.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||||
|
//是否只循环播放一次
|
||||||
|
videoAdconfiguration.videoCycleOnce = NO;
|
||||||
|
//广告点击打开页面参数(openModel可为NSString,模型,字典等任意类型)
|
||||||
|
videoAdconfiguration.openModel = model.openUrl;
|
||||||
|
//广告显示完成动画
|
||||||
|
videoAdconfiguration.showFinishAnimate =ShowFinishAnimateFadein;
|
||||||
|
//广告显示完成动画时间
|
||||||
|
videoAdconfiguration.showFinishAnimateTime = 0.8;
|
||||||
|
//后台返回时,是否显示广告
|
||||||
|
videoAdconfiguration.showEnterForeground = NO;
|
||||||
|
//跳过按钮类型
|
||||||
|
videoAdconfiguration.skipButtonType = SkipTypeTimeText;
|
||||||
|
|
||||||
|
//设置要添加的自定义视图(可选)
|
||||||
|
//videoAdconfiguration.subViews = ...
|
||||||
|
|
||||||
|
[XHLaunchAd videoAdWithVideoAdConfiguration:videoAdconfiguration delegate:self];
|
||||||
|
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### -1.5.0 显示完成动画支持以下效果
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
/** 显示完成动画类型 */
|
||||||
|
typedef NS_ENUM(NSInteger , ShowFinishAnimate) {
|
||||||
|
/** 无动画 */
|
||||||
|
ShowFinishAnimateNone = 1,
|
||||||
|
/** 普通淡入(default) */
|
||||||
|
ShowFinishAnimateFadein = 2,
|
||||||
|
/** 放大淡入 */
|
||||||
|
ShowFinishAnimateLite = 3,
|
||||||
|
/** 左右翻转(类似网易云音乐) */
|
||||||
|
ShowFinishAnimateFlipFromLeft = 4,
|
||||||
|
/** 下上翻转 */
|
||||||
|
ShowFinishAnimateFlipFromBottom = 5,
|
||||||
|
/** 向上翻页 */
|
||||||
|
ShowFinishAnimateCurlUp = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### -1.6.0 跳过按钮支持以下类型
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
/** 跳过按钮类型 */
|
||||||
|
typedef NS_ENUM(NSInteger,SkipType) {
|
||||||
|
SkipTypeNone = 1,//无
|
||||||
|
/** 方形 */
|
||||||
|
SkipTypeTime = 2,//方形:倒计时
|
||||||
|
SkipTypeText = 3,//方形:跳过
|
||||||
|
SkipTypeTimeText = 4,//方形:倒计时+跳过 (default)
|
||||||
|
/** 圆形 */
|
||||||
|
SkipTypeRoundTime = 5,//圆形:倒计时
|
||||||
|
SkipTypeRoundText = 6,//圆形:跳过
|
||||||
|
SkipTypeRoundProgressTime = 7,//圆形:进度圈+倒计时
|
||||||
|
SkipTypeRoundProgressText = 8,//圆形:进度圈+跳过
|
||||||
|
};
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 2.点击事件
|
||||||
|
```objc
|
||||||
|
/**
|
||||||
|
广告点击事件回调(return YES移除广告,NO不移除广告)
|
||||||
|
*/
|
||||||
|
-(BOOL)xhLaunchAd:(XHLaunchAd *)launchAd clickAtOpenModel:(id)openModel clickPoint:(CGPoint)clickPoint{
|
||||||
|
|
||||||
|
NSLog(@"广告点击事件");
|
||||||
|
|
||||||
|
//openModel即配置广告数据设置的点击广告时打开页面参数(configuration.openModel)
|
||||||
|
|
||||||
|
if(openModel == nil) return NO;
|
||||||
|
|
||||||
|
WebViewController *VC = [[WebViewController alloc] init];
|
||||||
|
NSString *urlString = (NSString *)openModel;
|
||||||
|
VC.URLString = urlString;
|
||||||
|
//此处不要直接取keyWindow
|
||||||
|
UIViewController* rootVC = [[UIApplication sharedApplication].delegate window].rootViewController;
|
||||||
|
[rootVC.myNavigationController pushViewController:VC animated:YES];
|
||||||
|
|
||||||
|
return YES;//YES移除广告,NO不移除广告
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
### 3.自定义跳过按钮
|
||||||
|
```objc
|
||||||
|
//1.XHLaunchImageAdConfiguration 和XHLaunchVideoAdConfiguration 均有一个configuration.customSkipView 属性
|
||||||
|
//2.自定义一个skipView 赋值给configuration.customSkipView属性 便可替换默认跳过按钮 如下:
|
||||||
|
configuration.customSkipView = [self customSkipView];
|
||||||
|
|
||||||
|
-(UIView *)customSkipView
|
||||||
|
{
|
||||||
|
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
|
button.backgroundColor =[UIColor orangeColor];
|
||||||
|
button.layer.cornerRadius = 5.0;
|
||||||
|
button.layer.borderWidth = 1.5;
|
||||||
|
button.layer.borderColor = [UIColor lightGrayColor].CGColor;
|
||||||
|
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||||
|
button.titleLabel.font = [UIFont systemFontOfSize:14];
|
||||||
|
CGFloat y = XH_IPHONEX ? 54 : 30;
|
||||||
|
button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-100,y, 85, 30);
|
||||||
|
[button addTarget:self action:@selector(skipAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)skipAction
|
||||||
|
{
|
||||||
|
//移除广告
|
||||||
|
[XHLaunchAd removeAndAnimated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代理方法 - 倒计时回调
|
||||||
|
*
|
||||||
|
* @param launchAd XHLaunchAd
|
||||||
|
* @param duration 倒计时时间
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd customSkipView:(UIView *)customSkipView duration:(NSInteger)duration
|
||||||
|
{
|
||||||
|
UIButton *button = (UIButton *)customSkipView;//此处转换为你之前的类型
|
||||||
|
//设置自定义跳过按钮倒计时
|
||||||
|
[button setTitle:[NSString stringWithFormat:@"自定义%lds",duration] forState:UIControlStateNormal];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.批量下载缓存接口(如果你需要提前批量下载并缓存广告图片或视频请调用下面方法)
|
||||||
|
```objc
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量下载并缓存image(异步) - 已缓存的image不会再次下载缓存
|
||||||
|
*
|
||||||
|
* @param urlArray image URL Array
|
||||||
|
*/
|
||||||
|
+(void)downLoadImageAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
批量下载并缓存image,并回调结果(异步)- 已缓存的image不会再次下载缓存
|
||||||
|
|
||||||
|
@param urlArray image URL Array
|
||||||
|
@param completedBlock 回调结果为一个字典数组,url:图片的url字符串,result:0表示该图片下载缓存失败,1表示该图片下载并缓存完成或本地缓存中已有该图片
|
||||||
|
*/
|
||||||
|
+(void)downLoadImageAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量下载并缓存视频(异步) - 已缓存的视频不会再次下载缓存
|
||||||
|
*
|
||||||
|
* @param urlArray 视频URL Array
|
||||||
|
*/
|
||||||
|
+(void)downLoadVideoAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
批量下载并缓存视频,并回调结果(异步) - 已缓存的视频不会再次下载缓存
|
||||||
|
|
||||||
|
@param urlArray 视频URL Array
|
||||||
|
@param completedBlock 回调结果为一个字典数组,url:视频的url字符串,result:0表示该视频下载缓存失败,1表示该视频下载并缓存完成或本地缓存中已有该视频
|
||||||
|
*/
|
||||||
|
+(void)downLoadVideoAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.检测是否已缓存
|
||||||
|
|
||||||
|
```objc
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已缓存在该图片
|
||||||
|
*
|
||||||
|
* @param url image url
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
+(BOOL)checkImageInCacheWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已缓存该视频
|
||||||
|
*
|
||||||
|
* @param url video url
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
+(BOOL)checkVideoInCacheWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.缓存/清理相关
|
||||||
|
```objc
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除XHLaunch本地所有缓存
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url的图片本地缓存(异步)
|
||||||
|
|
||||||
|
@param imageUrlArray 需要清除缓存的图片Url数组
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheWithImageUrlArray:(NSArray<NSURL *> *)imageUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url除外的图片本地缓存(异步)
|
||||||
|
|
||||||
|
@param exceptImageUrlArray 此url数组的图片缓存将被保留,不会被清理
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheExceptImageUrlArray:(NSArray<NSURL *> *)exceptImageUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url的视频本地缓存(异步)
|
||||||
|
|
||||||
|
@param videoUrlArray 需要清除缓存的视频url数组
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheWithVideoUrlArray:(NSArray<NSURL *> *)videoUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url除外的视频本地缓存(异步)
|
||||||
|
|
||||||
|
@param exceptVideoUrlArray 此url数组的视频缓存将被保留,不会被清理
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheExceptVideoUrlArray:(NSArray<NSURL *> *)exceptVideoUrlArray;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取XHLaunch本地缓存大小(M)
|
||||||
|
*/
|
||||||
|
+(float)diskCacheSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存路径
|
||||||
|
*/
|
||||||
|
+(NSString *)xhLaunchAdCachePath;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.其它代理方法
|
||||||
|
```objc
|
||||||
|
/**
|
||||||
|
* 图片本地读取/或下载完成回调
|
||||||
|
*
|
||||||
|
* @param launchAd XHLaunchAd
|
||||||
|
* @param image 读取/下载的image
|
||||||
|
* @param imageData 读取/下载的imageData
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd imageDownLoadFinish:(UIImage *)image imageData:(NSData *)imageData;
|
||||||
|
{
|
||||||
|
NSLog(@"图片下载完成/或本地图片读取完成回调");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 视频下载完成回调
|
||||||
|
*
|
||||||
|
* @param launchAd XHLaunchAd
|
||||||
|
* @param pathURL 视频保存在本地的path
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd videoDownLoadFinish:(NSURL *)pathURL
|
||||||
|
{
|
||||||
|
NSLog(@"video下载/加载完成/保存path = %@",pathURL.absoluteString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频下载进度回调
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd videoDownLoadProgress:(float)progress total:(unsigned long long)total current:(unsigned long long)current
|
||||||
|
{
|
||||||
|
NSLog(@"总大小=%lld,已下载大小=%lld,下载进度=%f",total,current,progress);
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 广告显示完成
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAdShowFinish:(XHLaunchAd *)launchAd
|
||||||
|
{
|
||||||
|
NSLog(@"广告显示完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
如果你想用SDWebImage等框架加载网络广告图片,请实现此代理(注意:实现此方法后,图片缓存将不受XHLaunchAd管理)
|
||||||
|
|
||||||
|
@param launchAd XHLaunchAd
|
||||||
|
@param launchAdImageView launchAdImageView
|
||||||
|
@param url 图片url
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd launchAdImageView:(UIImageView *)launchAdImageView URL:(NSURL *)url
|
||||||
|
{
|
||||||
|
[launchAdImageView sd_setImageWithURL:url];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
#### 1.本库依赖于:FLAnimatedImage
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
### 1.手动添加:<br>
|
||||||
|
* 1.将 XHLaunchAd 文件夹添加到工程目录中<br>
|
||||||
|
* 2.导入 XHLaunchAd.h
|
||||||
|
|
||||||
|
### 2.CocoaPods:<br>
|
||||||
|
* 1.在 Podfile 中添加 pod 'XHLaunchAd'<br>
|
||||||
|
* 2.执行 pod install 或 pod update<br>
|
||||||
|
* 3.导入 XHLaunchAd.h
|
||||||
|
|
||||||
|
### 3.Tips
|
||||||
|
* 1.如果发现pod search XHLaunchAd 搜索出来的不是最新版本,需要在终端执行pod repo update命令更新本地spec缓存(需要几分钟),然后再搜索就可以了
|
||||||
|
* 2.如果你发现你执行pod install后,导入的不是最新版本,请删除Podfile.lock文件,在执行一次 pod install
|
||||||
|
* 3.如果在使用过程中遇到BUG,希望你能Issues我,谢谢(或者尝试下载最新的代码看看BUG修复没有)
|
||||||
|
|
||||||
|
## 系统要求
|
||||||
|
* 该项目最低支持 iOS 8.0 和 Xcode 8.0
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
XHLaunchAd 使用 MIT 许可证,详情见 LICENSE 文件
|
||||||
291
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAd.h
generated
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAd.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2016/6/13.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
// 版本: 3.9.12
|
||||||
|
// 发布: 2020.05.06
|
||||||
|
|
||||||
|
// 如果你在使用过程中出现bug,请及时以下面任意一种方式联系我,我会及时修复bug并帮您解决问题。
|
||||||
|
// QQ交流群:537476189
|
||||||
|
// Email:it7090@163.com
|
||||||
|
// 新浪微博:朱晓辉Allen
|
||||||
|
// GitHub:https://github.com/CoderZhuXH
|
||||||
|
// 简书:https://www.jianshu.com/u/acf1a1f12e0f
|
||||||
|
// 掘金:https://juejin.im/user/59b50d3cf265da066d331a06
|
||||||
|
|
||||||
|
// 使用说明:https://github.com/CoderZhuXH/XHLaunchAd/blob/master/README.md
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "XHLaunchAdConfiguration.h"
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
#import "XHLaunchImageView.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
@class XHLaunchAd;
|
||||||
|
@protocol XHLaunchAdDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/**
|
||||||
|
广告点击回调
|
||||||
|
|
||||||
|
@param launchAd launchAd
|
||||||
|
@param openModel 打开页面参数(此参数即你配置广告数据设置的configuration.openModel)
|
||||||
|
@param clickPoint 点击位置
|
||||||
|
@param return YES移除广告,NO不移除
|
||||||
|
*/
|
||||||
|
- (BOOL)xhLaunchAd:(XHLaunchAd *)launchAd clickAtOpenModel:(id)openModel clickPoint:(CGPoint)clickPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
跳过按钮点击回调(注意:自定义跳过按钮不会走此回调)
|
||||||
|
|
||||||
|
@param launchAd launchAd
|
||||||
|
@param skipButton 跳过按钮
|
||||||
|
*/
|
||||||
|
- (void)xhLaunchAd:(XHLaunchAd *)launchAd clickSkipButton:(UIButton *)skipButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片本地读取/或下载完成回调
|
||||||
|
*
|
||||||
|
* @param launchAd XHLaunchAd
|
||||||
|
* @param image 读取/下载的image
|
||||||
|
* @param imageData 读取/下载的imageData
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd imageDownLoadFinish:(UIImage *)image imageData:(NSData *)imageData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video本地读取/或下载完成回调
|
||||||
|
*
|
||||||
|
* @param launchAd XHLaunchAd
|
||||||
|
* @param pathURL 本地保存路径
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd videoDownLoadFinish:(NSURL *)pathURL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
视频下载进度回调
|
||||||
|
|
||||||
|
@param launchAd XHLaunchAd
|
||||||
|
@param progress 下载进度
|
||||||
|
@param total 总大小
|
||||||
|
@param current 当前已下载大小
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd videoDownLoadProgress:(float)progress total:(unsigned long long)total current:(unsigned long long)current;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 倒计时回调
|
||||||
|
*
|
||||||
|
* @param launchAd XHLaunchAd
|
||||||
|
* @param duration 倒计时时间
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd customSkipView:(UIView *)customSkipView duration:(NSInteger)duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
广告显示完成
|
||||||
|
|
||||||
|
@param launchAd XHLaunchAd
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAdShowFinish:(XHLaunchAd *)launchAd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
如果你想用SDWebImage等框架加载网络广告图片,请实现此代理,注意:实现此方法后,图片缓存将不受XHLaunchAd管理
|
||||||
|
|
||||||
|
@param launchAd XHLaunchAd
|
||||||
|
@param launchAdImageView launchAdImageView
|
||||||
|
@param url 图片url
|
||||||
|
*/
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd launchAdImageView:(UIImageView *)launchAdImageView URL:(NSURL *)url;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - 过期-XHLaunchAdDelegate
|
||||||
|
- (void)xhLaunchAd:(XHLaunchAd *)launchAd clickAndOpenModel:(id)openModel clickPoint:(CGPoint)clickPoint XHLaunchAdDeprecated("请使用xhLaunchAd:clickAtOpenModel:clickPoint:");
|
||||||
|
- (void)xhLaunchAd:(XHLaunchAd *)launchAd clickAndOpenURLString:(NSString *)openURLString XHLaunchAdDeprecated("请使用xhLaunchAd:clickAtOpenModel:clickPoint:");
|
||||||
|
- (void)xhLaunchAd:(XHLaunchAd *)launchAd clickAndOpenURLString:(NSString *)openURLString clickPoint:(CGPoint)clickPoint XHLaunchAdDeprecated("请使用xhLaunchAd:clickAtOpenModel:clickPoint:");
|
||||||
|
-(void)xhLaunchAd:(XHLaunchAd *)launchAd imageDownLoadFinish:(UIImage *)image XHLaunchAdDeprecated("请使用xhLaunchAd:imageDownLoadFinish:imageData:");
|
||||||
|
-(void)xhLaunchShowFinish:(XHLaunchAd *)launchAd XHLaunchAdDeprecated("请使用xhLaunchAdShowFinish:");
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface XHLaunchAd : NSObject
|
||||||
|
|
||||||
|
@property(nonatomic,assign) id<XHLaunchAdDelegate> delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
设置你工程的启动页使用的是LaunchImage还是LaunchScreen(default:SourceTypeLaunchImage)
|
||||||
|
注意:请在设置等待数据及配置广告数据前调用此方法
|
||||||
|
@param sourceType sourceType
|
||||||
|
*/
|
||||||
|
+(void)setLaunchSourceType:(SourceType)sourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置等待数据源时间(建议值:2)
|
||||||
|
*
|
||||||
|
* @param waitDataDuration waitDataDuration
|
||||||
|
*/
|
||||||
|
+(void)setWaitDataDuration:(NSInteger )waitDataDuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片开屏广告数据配置
|
||||||
|
*
|
||||||
|
* @param imageAdconfiguration 数据配置
|
||||||
|
*
|
||||||
|
* @return XHLaunchAd
|
||||||
|
*/
|
||||||
|
+(XHLaunchAd *)imageAdWithImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdconfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片开屏广告数据配置
|
||||||
|
*
|
||||||
|
* @param imageAdconfiguration 数据配置
|
||||||
|
* @param delegate delegate
|
||||||
|
*
|
||||||
|
* @return XHLaunchAd
|
||||||
|
*/
|
||||||
|
+(XHLaunchAd *)imageAdWithImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdconfiguration delegate:(nullable id)delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频开屏广告数据配置
|
||||||
|
*
|
||||||
|
* @param videoAdconfiguration 数据配置
|
||||||
|
*
|
||||||
|
* @return XHLaunchAd
|
||||||
|
*/
|
||||||
|
+(XHLaunchAd *)videoAdWithVideoAdConfiguration:(XHLaunchVideoAdConfiguration *)videoAdconfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频开屏广告数据配置
|
||||||
|
*
|
||||||
|
* @param videoAdconfiguration 数据配置
|
||||||
|
* @param delegate delegate
|
||||||
|
*
|
||||||
|
* @return XHLaunchAd
|
||||||
|
*/
|
||||||
|
+(XHLaunchAd *)videoAdWithVideoAdConfiguration:(XHLaunchVideoAdConfiguration *)videoAdconfiguration delegate:(nullable id)delegate;
|
||||||
|
|
||||||
|
#pragma mark -批量下载并缓存
|
||||||
|
/**
|
||||||
|
* 批量下载并缓存image(异步) - 已缓存的image不会再次下载缓存
|
||||||
|
*
|
||||||
|
* @param urlArray image URL Array
|
||||||
|
*/
|
||||||
|
+(void)downLoadImageAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
批量下载并缓存image,并回调结果(异步)- 已缓存的image不会再次下载缓存
|
||||||
|
|
||||||
|
@param urlArray image URL Array
|
||||||
|
@param completedBlock 回调结果为一个字典数组,url:图片的url字符串,result:0表示该图片下载缓存失败,1表示该图片下载并缓存完成或本地缓存中已有该图片
|
||||||
|
*/
|
||||||
|
+(void)downLoadImageAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量下载并缓存视频(异步) - 已缓存的视频不会再次下载缓存
|
||||||
|
*
|
||||||
|
* @param urlArray 视频URL Array
|
||||||
|
*/
|
||||||
|
+(void)downLoadVideoAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
批量下载并缓存视频,并回调结果(异步) - 已缓存的视频不会再次下载缓存
|
||||||
|
|
||||||
|
@param urlArray 视频URL Array
|
||||||
|
@param completedBlock 回调结果为一个字典数组,url:视频的url字符串,result:0表示该视频下载缓存失败,1表示该视频下载并缓存完成或本地缓存中已有该视频
|
||||||
|
*/
|
||||||
|
+(void)downLoadVideoAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
|
||||||
|
/**
|
||||||
|
手动移除广告
|
||||||
|
|
||||||
|
@param animated 是否需要动画
|
||||||
|
*/
|
||||||
|
+(void)removeAndAnimated:(BOOL)animated;
|
||||||
|
|
||||||
|
#pragma mark - 是否已缓存
|
||||||
|
/**
|
||||||
|
* 是否已缓存在该图片
|
||||||
|
*
|
||||||
|
* @param url image url
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
+(BOOL)checkImageInCacheWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已缓存该视频
|
||||||
|
*
|
||||||
|
* @param url video url
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
+(BOOL)checkVideoInCacheWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
#pragma mark - 获取缓存url
|
||||||
|
/**
|
||||||
|
从缓存中获取上一次的ImageURLString(XHLaunchAd 会默认缓存imageURLString)
|
||||||
|
|
||||||
|
@return imageUrlString
|
||||||
|
*/
|
||||||
|
+(NSString *)cacheImageURLString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
从缓存中获取上一次的videoURLString(XHLaunchAd 会默认缓存VideoURLString)
|
||||||
|
|
||||||
|
@return videoUrlString
|
||||||
|
*/
|
||||||
|
+(NSString *)cacheVideoURLString;
|
||||||
|
|
||||||
|
#pragma mark - 缓存/清理相关
|
||||||
|
/**
|
||||||
|
* 清除XHLaunchAd本地所有缓存(异步)
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url的图片本地缓存(异步)
|
||||||
|
|
||||||
|
@param imageUrlArray 需要清除缓存的图片Url数组
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheWithImageUrlArray:(NSArray<NSURL *> *)imageUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url除外的图片本地缓存(异步)
|
||||||
|
|
||||||
|
@param exceptImageUrlArray 此url数组的图片缓存将被保留
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheExceptImageUrlArray:(NSArray<NSURL *> *)exceptImageUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url的视频本地缓存(异步)
|
||||||
|
|
||||||
|
@param videoUrlArray 需要清除缓存的视频url数组
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheWithVideoUrlArray:(NSArray<NSURL *> *)videoUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url除外的视频本地缓存(异步)
|
||||||
|
|
||||||
|
@param exceptVideoUrlArray 此url数组的视频缓存将被保留
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheExceptVideoUrlArray:(NSArray<NSURL *> *)exceptVideoUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取XHLaunch本地缓存大小(M)
|
||||||
|
*/
|
||||||
|
+(float)diskCacheSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存路径
|
||||||
|
*/
|
||||||
|
+(NSString *)xhLaunchAdCachePath;
|
||||||
|
|
||||||
|
#pragma mark - 过期
|
||||||
|
+(void)skipAction XHLaunchAdDeprecated("请使用removeAndAnimated:");
|
||||||
|
+(void)setLaunchImagesSource:(LaunchImagesSource)launchImagesSource XHLaunchAdDeprecated("请使用setLaunchSourceType:");
|
||||||
|
|
||||||
|
@end
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
648
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAd.m
generated
Normal file
@@ -0,0 +1,648 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAd.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2016/6/13.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAd.h"
|
||||||
|
#import "XHLaunchAdView.h"
|
||||||
|
#import "XHLaunchAdImageView+XHLaunchAdCache.h"
|
||||||
|
#import "XHLaunchAdDownloader.h"
|
||||||
|
#import "XHLaunchAdCache.h"
|
||||||
|
#import "XHLaunchAdController.h"
|
||||||
|
|
||||||
|
#if __has_include(<FLAnimatedImage/FLAnimatedImage.h>)
|
||||||
|
#import <FLAnimatedImage/FLAnimatedImage.h>
|
||||||
|
#else
|
||||||
|
#import "FLAnimatedImage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, XHLaunchAdType) {
|
||||||
|
XHLaunchAdTypeImage,
|
||||||
|
XHLaunchAdTypeVideo
|
||||||
|
};
|
||||||
|
|
||||||
|
static NSInteger defaultWaitDataDuration = 3;
|
||||||
|
static SourceType _sourceType = SourceTypeLaunchImage;
|
||||||
|
@interface XHLaunchAd()
|
||||||
|
|
||||||
|
@property(nonatomic,assign)XHLaunchAdType launchAdType;
|
||||||
|
@property(nonatomic,assign)NSInteger waitDataDuration;
|
||||||
|
@property(nonatomic,strong)XHLaunchImageAdConfiguration * imageAdConfiguration;
|
||||||
|
@property(nonatomic,strong)XHLaunchVideoAdConfiguration * videoAdConfiguration;
|
||||||
|
@property(nonatomic,strong)XHLaunchAdButton * skipButton;
|
||||||
|
@property(nonatomic,strong)XHLaunchAdVideoView * adVideoView;
|
||||||
|
@property(nonatomic,strong)UIWindow * window;
|
||||||
|
@property(nonatomic,copy)dispatch_source_t waitDataTimer;
|
||||||
|
@property(nonatomic,copy)dispatch_source_t skipTimer;
|
||||||
|
@property (nonatomic, assign) BOOL detailPageShowing;
|
||||||
|
@property(nonatomic,assign) CGPoint clickPoint;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation XHLaunchAd
|
||||||
|
+(void)setLaunchSourceType:(SourceType)sourceType{
|
||||||
|
_sourceType = sourceType;
|
||||||
|
}
|
||||||
|
+(void)setWaitDataDuration:(NSInteger )waitDataDuration{
|
||||||
|
XHLaunchAd *launchAd = [XHLaunchAd shareLaunchAd];
|
||||||
|
launchAd.waitDataDuration = waitDataDuration;
|
||||||
|
}
|
||||||
|
+(XHLaunchAd *)imageAdWithImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdconfiguration{
|
||||||
|
return [XHLaunchAd imageAdWithImageAdConfiguration:imageAdconfiguration delegate:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(XHLaunchAd *)imageAdWithImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdconfiguration delegate:(id)delegate{
|
||||||
|
XHLaunchAd *launchAd = [XHLaunchAd shareLaunchAd];
|
||||||
|
if(delegate) launchAd.delegate = delegate;
|
||||||
|
launchAd.imageAdConfiguration = imageAdconfiguration;
|
||||||
|
return launchAd;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(XHLaunchAd *)videoAdWithVideoAdConfiguration:(XHLaunchVideoAdConfiguration *)videoAdconfiguration{
|
||||||
|
return [XHLaunchAd videoAdWithVideoAdConfiguration:videoAdconfiguration delegate:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(XHLaunchAd *)videoAdWithVideoAdConfiguration:(XHLaunchVideoAdConfiguration *)videoAdconfiguration delegate:(nullable id)delegate{
|
||||||
|
XHLaunchAd *launchAd = [XHLaunchAd shareLaunchAd];
|
||||||
|
if(delegate) launchAd.delegate = delegate;
|
||||||
|
launchAd.videoAdConfiguration = videoAdconfiguration;
|
||||||
|
return launchAd;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)downLoadImageAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray{
|
||||||
|
[self downLoadImageAndCacheWithURLArray:urlArray completed:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)downLoadImageAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock{
|
||||||
|
if(urlArray.count==0) return;
|
||||||
|
[[XHLaunchAdDownloader sharedDownloader] downLoadImageAndCacheWithURLArray:urlArray completed:completedBlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)downLoadVideoAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray{
|
||||||
|
[self downLoadVideoAndCacheWithURLArray:urlArray completed:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)downLoadVideoAndCacheWithURLArray:(NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock{
|
||||||
|
if(urlArray.count==0) return;
|
||||||
|
[[XHLaunchAdDownloader sharedDownloader] downLoadVideoAndCacheWithURLArray:urlArray completed:completedBlock];
|
||||||
|
}
|
||||||
|
+(void)removeAndAnimated:(BOOL)animated{
|
||||||
|
[[XHLaunchAd shareLaunchAd] removeAndAnimated:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(BOOL)checkImageInCacheWithURL:(NSURL *)url{
|
||||||
|
return [XHLaunchAdCache checkImageInCacheWithURL:url];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(BOOL)checkVideoInCacheWithURL:(NSURL *)url{
|
||||||
|
return [XHLaunchAdCache checkVideoInCacheWithURL:url];
|
||||||
|
}
|
||||||
|
+(void)clearDiskCache{
|
||||||
|
[XHLaunchAdCache clearDiskCache];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheWithImageUrlArray:(NSArray<NSURL *> *)imageUrlArray{
|
||||||
|
[XHLaunchAdCache clearDiskCacheWithImageUrlArray:imageUrlArray];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheExceptImageUrlArray:(NSArray<NSURL *> *)exceptImageUrlArray{
|
||||||
|
[XHLaunchAdCache clearDiskCacheExceptImageUrlArray:exceptImageUrlArray];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheWithVideoUrlArray:(NSArray<NSURL *> *)videoUrlArray{
|
||||||
|
[XHLaunchAdCache clearDiskCacheWithVideoUrlArray:videoUrlArray];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheExceptVideoUrlArray:(NSArray<NSURL *> *)exceptVideoUrlArray{
|
||||||
|
[XHLaunchAdCache clearDiskCacheExceptVideoUrlArray:exceptVideoUrlArray];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(float)diskCacheSize{
|
||||||
|
return [XHLaunchAdCache diskCacheSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)xhLaunchAdCachePath{
|
||||||
|
return [XHLaunchAdCache xhLaunchAdCachePath];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)cacheImageURLString{
|
||||||
|
return [XHLaunchAdCache getCacheImageUrl];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)cacheVideoURLString{
|
||||||
|
return [XHLaunchAdCache getCacheVideoUrl];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - 过期
|
||||||
|
/** 请使用removeAndAnimated: */
|
||||||
|
+(void)skipAction{
|
||||||
|
[[XHLaunchAd shareLaunchAd] removeAndAnimated:YES];
|
||||||
|
}
|
||||||
|
/** 请使用setLaunchSourceType: */
|
||||||
|
+(void)setLaunchImagesSource:(LaunchImagesSource)launchImagesSource{
|
||||||
|
switch (launchImagesSource) {
|
||||||
|
case LaunchImagesSourceLaunchImage:
|
||||||
|
_sourceType = SourceTypeLaunchImage;
|
||||||
|
break;
|
||||||
|
case LaunchImagesSourceLaunchScreen:
|
||||||
|
_sourceType = SourceTypeLaunchScreen;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - private
|
||||||
|
+(XHLaunchAd *)shareLaunchAd{
|
||||||
|
static XHLaunchAd *instance = nil;
|
||||||
|
static dispatch_once_t oneToken;
|
||||||
|
dispatch_once(&oneToken,^{
|
||||||
|
instance = [[XHLaunchAd alloc] init];
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
XHWeakSelf
|
||||||
|
[self setupLaunchAd];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||||
|
[self setupLaunchAdEnterForeground];
|
||||||
|
}];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||||
|
[self removeOnly];
|
||||||
|
}];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:XHLaunchAdDetailPageWillShowNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||||
|
weakSelf.detailPageShowing = YES;
|
||||||
|
}];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:XHLaunchAdDetailPageShowFinishNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||||
|
weakSelf.detailPageShowing = NO;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setupLaunchAdEnterForeground{
|
||||||
|
switch (_launchAdType) {
|
||||||
|
case XHLaunchAdTypeImage:{
|
||||||
|
if(!_imageAdConfiguration.showEnterForeground || _detailPageShowing) return;
|
||||||
|
[self setupLaunchAd];
|
||||||
|
[self setupImageAdForConfiguration:_imageAdConfiguration];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XHLaunchAdTypeVideo:{
|
||||||
|
if(!_videoAdConfiguration.showEnterForeground || _detailPageShowing) return;
|
||||||
|
[self setupLaunchAd];
|
||||||
|
[self setupVideoAdForConfiguration:_videoAdConfiguration];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setupLaunchAd{
|
||||||
|
UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
window.rootViewController = [XHLaunchAdController new];
|
||||||
|
window.rootViewController.view.backgroundColor = [UIColor clearColor];
|
||||||
|
window.rootViewController.view.userInteractionEnabled = NO;
|
||||||
|
window.windowLevel = UIWindowLevelStatusBar + 1;
|
||||||
|
window.hidden = NO;
|
||||||
|
window.alpha = 1;
|
||||||
|
_window = window;
|
||||||
|
/** 添加launchImageView */
|
||||||
|
[_window addSubview:[[XHLaunchImageView alloc] initWithSourceType:_sourceType]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**图片*/
|
||||||
|
-(void)setupImageAdForConfiguration:(XHLaunchImageAdConfiguration *)configuration{
|
||||||
|
if(_window == nil) return;
|
||||||
|
[self removeSubViewsExceptLaunchAdImageView];
|
||||||
|
XHLaunchAdImageView *adImageView = [[XHLaunchAdImageView alloc] init];
|
||||||
|
[_window addSubview:adImageView];
|
||||||
|
/** frame */
|
||||||
|
if(configuration.frame.size.width>0 && configuration.frame.size.height>0) adImageView.frame = configuration.frame;
|
||||||
|
if(configuration.contentMode) adImageView.contentMode = configuration.contentMode;
|
||||||
|
/** webImage */
|
||||||
|
if(configuration.imageNameOrURLString.length && XHISURLString(configuration.imageNameOrURLString)){
|
||||||
|
[XHLaunchAdCache async_saveImageUrl:configuration.imageNameOrURLString];
|
||||||
|
/** 自设图片 */
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:launchAdImageView:URL:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self launchAdImageView:adImageView URL:[NSURL URLWithString:configuration.imageNameOrURLString]];
|
||||||
|
}else{
|
||||||
|
if(!configuration.imageOption) configuration.imageOption = XHLaunchAdImageDefault;
|
||||||
|
XHWeakSelf
|
||||||
|
[adImageView xh_setImageWithURL:[NSURL URLWithString:configuration.imageNameOrURLString] placeholderImage:nil GIFImageCycleOnce:configuration.GIFImageCycleOnce options:configuration.imageOption GIFImageCycleOnceFinish:^{
|
||||||
|
//GIF不循环,播放完成
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdGIFImageCycleOnceFinishNotification object:nil userInfo:@{@"imageNameOrURLString":configuration.imageNameOrURLString}];
|
||||||
|
|
||||||
|
} completed:^(UIImage *image,NSData *imageData,NSError *error,NSURL *url){
|
||||||
|
if(!error){
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||||
|
if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:)]) {
|
||||||
|
[weakSelf.delegate xhLaunchAd:self imageDownLoadFinish:image];
|
||||||
|
}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:imageData:)]) {
|
||||||
|
[weakSelf.delegate xhLaunchAd:self imageDownLoadFinish:image imageData:imageData];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
if(configuration.imageOption == XHLaunchAdImageCacheInBackground){
|
||||||
|
/** 缓存中未有 */
|
||||||
|
if(![XHLaunchAdCache checkImageInCacheWithURL:[NSURL URLWithString:configuration.imageNameOrURLString]]){
|
||||||
|
[self removeAndAnimateDefault]; return; /** 完成显示 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(configuration.imageNameOrURLString.length){
|
||||||
|
NSData *data = XHDataWithFileName(configuration.imageNameOrURLString);
|
||||||
|
if(XHISGIFTypeWithData(data)){
|
||||||
|
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
|
||||||
|
adImageView.animatedImage = image;
|
||||||
|
adImageView.image = nil;
|
||||||
|
__weak typeof(adImageView) w_adImageView = adImageView;
|
||||||
|
adImageView.loopCompletionBlock = ^(NSUInteger loopCountRemaining) {
|
||||||
|
if(configuration.GIFImageCycleOnce){
|
||||||
|
[w_adImageView stopAnimating];
|
||||||
|
XHLaunchAdLog(@"GIF不循环,播放完成");
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdGIFImageCycleOnceFinishNotification object:@{@"imageNameOrURLString":configuration.imageNameOrURLString}];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
adImageView.animatedImage = nil;
|
||||||
|
adImageView.image = [UIImage imageWithData:data];
|
||||||
|
}
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self imageDownLoadFinish:[UIImage imageWithData:data]];
|
||||||
|
}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}else{
|
||||||
|
XHLaunchAdLog(@"未设置广告图片");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** skipButton */
|
||||||
|
[self addSkipButtonForConfiguration:configuration];
|
||||||
|
[self startSkipDispathTimer];
|
||||||
|
/** customView */
|
||||||
|
if(configuration.subViews.count>0) [self addSubViews:configuration.subViews];
|
||||||
|
XHWeakSelf
|
||||||
|
adImageView.click = ^(CGPoint point) {
|
||||||
|
[weakSelf clickAndPoint:point];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)addSkipButtonForConfiguration:(XHLaunchAdConfiguration *)configuration{
|
||||||
|
if(!configuration.duration) configuration.duration = 5;
|
||||||
|
if(!configuration.skipButtonType) configuration.skipButtonType = SkipTypeTimeText;
|
||||||
|
if(configuration.customSkipView){
|
||||||
|
[_window addSubview:configuration.customSkipView];
|
||||||
|
}else{
|
||||||
|
if(_skipButton == nil){
|
||||||
|
_skipButton = [[XHLaunchAdButton alloc] initWithSkipType:configuration.skipButtonType];
|
||||||
|
_skipButton.hidden = YES;
|
||||||
|
[_skipButton addTarget:self action:@selector(skipButtonClick:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
[_window addSubview:_skipButton];
|
||||||
|
[_skipButton setTitleWithSkipType:configuration.skipButtonType duration:configuration.duration];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**视频*/
|
||||||
|
-(void)setupVideoAdForConfiguration:(XHLaunchVideoAdConfiguration *)configuration{
|
||||||
|
if(_window ==nil) return;
|
||||||
|
[self removeSubViewsExceptLaunchAdImageView];
|
||||||
|
if(!_adVideoView){
|
||||||
|
_adVideoView = [[XHLaunchAdVideoView alloc] init];
|
||||||
|
}
|
||||||
|
[_window addSubview:_adVideoView];
|
||||||
|
/** frame */
|
||||||
|
if(configuration.frame.size.width>0&&configuration.frame.size.height>0) _adVideoView.frame = configuration.frame;
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||||
|
if(configuration.scalingMode) _adVideoView.videoScalingMode = configuration.scalingMode;
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
if(configuration.videoGravity) _adVideoView.videoGravity = configuration.videoGravity;
|
||||||
|
_adVideoView.videoCycleOnce = configuration.videoCycleOnce;
|
||||||
|
if(configuration.videoCycleOnce){
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:AVPlayerItemDidPlayToEndTimeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
||||||
|
XHLaunchAdLog(@"video不循环,播放完成");
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdVideoCycleOnceFinishNotification object:nil userInfo:@{@"videoNameOrURLString":configuration.videoNameOrURLString}];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
/** video 数据源 */
|
||||||
|
if(configuration.videoNameOrURLString.length && XHISURLString(configuration.videoNameOrURLString)){
|
||||||
|
[XHLaunchAdCache async_saveVideoUrl:configuration.videoNameOrURLString];
|
||||||
|
NSURL *pathURL = [XHLaunchAdCache getCacheVideoWithURL:[NSURL URLWithString:configuration.videoNameOrURLString]];
|
||||||
|
if(pathURL){
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:videoDownLoadFinish:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self videoDownLoadFinish:pathURL];
|
||||||
|
}
|
||||||
|
_adVideoView.contentURL = pathURL;
|
||||||
|
_adVideoView.muted = configuration.muted;
|
||||||
|
[_adVideoView.videoPlayer.player play];
|
||||||
|
}else{
|
||||||
|
XHWeakSelf
|
||||||
|
[[XHLaunchAdDownloader sharedDownloader] downloadVideoWithURL:[NSURL URLWithString:configuration.videoNameOrURLString] progress:^(unsigned long long total, unsigned long long current) {
|
||||||
|
if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:videoDownLoadProgress:total:current:)]) {
|
||||||
|
[weakSelf.delegate xhLaunchAd:self videoDownLoadProgress:current/(float)total total:total current:current];
|
||||||
|
}
|
||||||
|
} completed:^(NSURL * _Nullable location, NSError * _Nullable error){
|
||||||
|
if(!error){
|
||||||
|
if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:videoDownLoadFinish:)]){
|
||||||
|
[weakSelf.delegate xhLaunchAd:self videoDownLoadFinish:location];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
/***视频缓存,提前显示完成 */
|
||||||
|
[self removeAndAnimateDefault]; return;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(configuration.videoNameOrURLString.length){
|
||||||
|
NSURL *pathURL = nil;
|
||||||
|
NSURL *cachePathURL = [[NSURL alloc] initFileURLWithPath:[XHLaunchAdCache videoPathWithFileName:configuration.videoNameOrURLString]];
|
||||||
|
//若本地视频未在沙盒缓存文件夹中
|
||||||
|
if (![XHLaunchAdCache checkVideoInCacheWithFileName:configuration.videoNameOrURLString]) {
|
||||||
|
/***如果不在沙盒文件夹中则将其复制一份到沙盒缓存文件夹中/下次直接取缓存文件夹文件,加快文件查找速度 */
|
||||||
|
NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:configuration.videoNameOrURLString withExtension:nil];
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[[NSFileManager defaultManager] copyItemAtURL:bundleURL toURL:cachePathURL error:nil];
|
||||||
|
});
|
||||||
|
pathURL = bundleURL;
|
||||||
|
}else{
|
||||||
|
pathURL = cachePathURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pathURL){
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:videoDownLoadFinish:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self videoDownLoadFinish:pathURL];
|
||||||
|
}
|
||||||
|
_adVideoView.contentURL = pathURL;
|
||||||
|
_adVideoView.muted = configuration.muted;
|
||||||
|
[_adVideoView.videoPlayer.player play];
|
||||||
|
|
||||||
|
}else{
|
||||||
|
XHLaunchAdLog(@"Error:广告视频未找到,请检查名称是否有误!");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
XHLaunchAdLog(@"未设置广告视频");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** skipButton */
|
||||||
|
[self addSkipButtonForConfiguration:configuration];
|
||||||
|
[self startSkipDispathTimer];
|
||||||
|
/** customView */
|
||||||
|
if(configuration.subViews.count>0) [self addSubViews:configuration.subViews];
|
||||||
|
XHWeakSelf
|
||||||
|
_adVideoView.click = ^(CGPoint point) {
|
||||||
|
[weakSelf clickAndPoint:point];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - add subViews
|
||||||
|
-(void)addSubViews:(NSArray *)subViews{
|
||||||
|
[subViews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
|
||||||
|
[_window addSubview:view];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - set
|
||||||
|
-(void)setImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdConfiguration{
|
||||||
|
_imageAdConfiguration = imageAdConfiguration;
|
||||||
|
_launchAdType = XHLaunchAdTypeImage;
|
||||||
|
[self setupImageAdForConfiguration:imageAdConfiguration];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setVideoAdConfiguration:(XHLaunchVideoAdConfiguration *)videoAdConfiguration{
|
||||||
|
_videoAdConfiguration = videoAdConfiguration;
|
||||||
|
_launchAdType = XHLaunchAdTypeVideo;
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(CGFLOAT_MIN * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
|
[self setupVideoAdForConfiguration:videoAdConfiguration];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setWaitDataDuration:(NSInteger)waitDataDuration{
|
||||||
|
_waitDataDuration = waitDataDuration;
|
||||||
|
/** 数据等待 */
|
||||||
|
[self startWaitDataDispathTiemr];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
-(void)skipButtonClick:(XHLaunchAdButton *)button{
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:clickSkipButton:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self clickSkipButton:button];
|
||||||
|
}
|
||||||
|
[self removeAndAnimated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)removeAndAnimated:(BOOL)animated{
|
||||||
|
if(animated){
|
||||||
|
[self removeAndAnimate];
|
||||||
|
}else{
|
||||||
|
[self remove];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)clickAndPoint:(CGPoint)point{
|
||||||
|
self.clickPoint = point;
|
||||||
|
XHLaunchAdConfiguration * configuration = [self commonConfiguration];
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:clickAndOpenURLString:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self clickAndOpenURLString:configuration.openURLString];
|
||||||
|
[self removeAndAnimateDefault];
|
||||||
|
}
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:clickAndOpenURLString:clickPoint:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self clickAndOpenURLString:configuration.openURLString clickPoint:point];
|
||||||
|
[self removeAndAnimateDefault];
|
||||||
|
}
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:clickAndOpenModel:clickPoint:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self clickAndOpenModel:configuration.openModel clickPoint:point];
|
||||||
|
[self removeAndAnimateDefault];
|
||||||
|
}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:clickAtOpenModel:clickPoint:)]) {
|
||||||
|
BOOL status = [self.delegate xhLaunchAd:self clickAtOpenModel:configuration.openModel clickPoint:point];
|
||||||
|
if(status) [self removeAndAnimateDefault];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(XHLaunchAdConfiguration *)commonConfiguration{
|
||||||
|
XHLaunchAdConfiguration *configuration = nil;
|
||||||
|
switch (_launchAdType) {
|
||||||
|
case XHLaunchAdTypeVideo:
|
||||||
|
configuration = _videoAdConfiguration;
|
||||||
|
break;
|
||||||
|
case XHLaunchAdTypeImage:
|
||||||
|
configuration = _imageAdConfiguration;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)startWaitDataDispathTiemr{
|
||||||
|
__block NSInteger duration = defaultWaitDataDuration;
|
||||||
|
if(_waitDataDuration) duration = _waitDataDuration;
|
||||||
|
_waitDataTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
|
||||||
|
NSTimeInterval period = 1.0;
|
||||||
|
dispatch_source_set_timer(_waitDataTimer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0);
|
||||||
|
dispatch_source_set_event_handler(_waitDataTimer, ^{
|
||||||
|
if(duration==0){
|
||||||
|
DISPATCH_SOURCE_CANCEL_SAFE(_waitDataTimer);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdWaitDataDurationArriveNotification object:nil];
|
||||||
|
[self remove];
|
||||||
|
return ;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
duration--;
|
||||||
|
});
|
||||||
|
dispatch_resume(_waitDataTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)startSkipDispathTimer{
|
||||||
|
XHLaunchAdConfiguration * configuration = [self commonConfiguration];
|
||||||
|
DISPATCH_SOURCE_CANCEL_SAFE(_waitDataTimer);
|
||||||
|
if(!configuration.skipButtonType) configuration.skipButtonType = SkipTypeTimeText;//默认
|
||||||
|
__block NSInteger duration = 5;//默认
|
||||||
|
if(configuration.duration) duration = configuration.duration;
|
||||||
|
if(configuration.skipButtonType == SkipTypeRoundProgressTime || configuration.skipButtonType == SkipTypeRoundProgressText){
|
||||||
|
[_skipButton startRoundDispathTimerWithDuration:duration];
|
||||||
|
}
|
||||||
|
NSTimeInterval period = 1.0;
|
||||||
|
_skipTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
|
||||||
|
dispatch_source_set_timer(_skipTimer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0);
|
||||||
|
dispatch_source_set_event_handler(_skipTimer, ^{
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAd:customSkipView:duration:)]) {
|
||||||
|
[self.delegate xhLaunchAd:self customSkipView:configuration.customSkipView duration:duration];
|
||||||
|
}
|
||||||
|
if(!configuration.customSkipView){
|
||||||
|
[_skipButton setTitleWithSkipType:configuration.skipButtonType duration:duration];
|
||||||
|
}
|
||||||
|
if(duration==0){
|
||||||
|
DISPATCH_SOURCE_CANCEL_SAFE(_skipTimer);
|
||||||
|
[self removeAndAnimate]; return ;
|
||||||
|
}
|
||||||
|
duration--;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
dispatch_resume(_skipTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)removeAndAnimate{
|
||||||
|
|
||||||
|
XHLaunchAdConfiguration * configuration = [self commonConfiguration];
|
||||||
|
CGFloat duration = showFinishAnimateTimeDefault;
|
||||||
|
if(configuration.showFinishAnimateTime>0) duration = configuration.showFinishAnimateTime;
|
||||||
|
switch (configuration.showFinishAnimate) {
|
||||||
|
case ShowFinishAnimateNone:{
|
||||||
|
[self remove];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShowFinishAnimateFadein:{
|
||||||
|
[self removeAndAnimateDefault];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShowFinishAnimateLite:{
|
||||||
|
[UIView transitionWithView:_window duration:duration options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||||
|
_window.transform = CGAffineTransformMakeScale(1.5, 1.5);
|
||||||
|
_window.alpha = 0;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[self remove];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShowFinishAnimateFlipFromLeft:{
|
||||||
|
[UIView transitionWithView:_window duration:duration options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
|
||||||
|
_window.alpha = 0;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[self remove];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShowFinishAnimateFlipFromBottom:{
|
||||||
|
[UIView transitionWithView:_window duration:duration options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
|
||||||
|
_window.alpha = 0;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[self remove];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShowFinishAnimateCurlUp:{
|
||||||
|
[UIView transitionWithView:_window duration:duration options:UIViewAnimationOptionTransitionCurlUp animations:^{
|
||||||
|
_window.alpha = 0;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[self remove];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:{
|
||||||
|
[self removeAndAnimateDefault];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)removeAndAnimateDefault{
|
||||||
|
XHLaunchAdConfiguration * configuration = [self commonConfiguration];
|
||||||
|
CGFloat duration = showFinishAnimateTimeDefault;
|
||||||
|
if(configuration.showFinishAnimateTime>0) duration = configuration.showFinishAnimateTime;
|
||||||
|
[UIView transitionWithView:_window duration:duration options:UIViewAnimationOptionTransitionNone animations:^{
|
||||||
|
_window.alpha = 0;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[self remove];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
-(void)removeOnly{
|
||||||
|
DISPATCH_SOURCE_CANCEL_SAFE(_waitDataTimer)
|
||||||
|
DISPATCH_SOURCE_CANCEL_SAFE(_skipTimer)
|
||||||
|
REMOVE_FROM_SUPERVIEW_SAFE(_skipButton)
|
||||||
|
if(_launchAdType==XHLaunchAdTypeVideo){
|
||||||
|
if(_adVideoView){
|
||||||
|
[_adVideoView stopVideoPlayer];
|
||||||
|
REMOVE_FROM_SUPERVIEW_SAFE(_adVideoView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(_window){
|
||||||
|
[_window.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
REMOVE_FROM_SUPERVIEW_SAFE(obj)
|
||||||
|
}];
|
||||||
|
_window.hidden = YES;
|
||||||
|
_window = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)remove{
|
||||||
|
[self removeOnly];
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchShowFinish:)]) {
|
||||||
|
[self.delegate xhLaunchShowFinish:self];
|
||||||
|
}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
if ([self.delegate respondsToSelector:@selector(xhLaunchAdShowFinish:)]) {
|
||||||
|
[self.delegate xhLaunchAdShowFinish:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)removeSubViewsExceptLaunchAdImageView{
|
||||||
|
[_window.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
if(![obj isKindOfClass:[XHLaunchImageView class]]){
|
||||||
|
REMOVE_FROM_SUPERVIEW_SAFE(obj)
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
-(void)dealloc{
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
@end
|
||||||
33
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdButton.h
generated
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdSkipButton.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2016/6/9.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 倒计时类型
|
||||||
|
*/
|
||||||
|
typedef NS_ENUM(NSInteger,SkipType) {
|
||||||
|
SkipTypeNone = 1,//无
|
||||||
|
/** 方形 */
|
||||||
|
SkipTypeTime = 2,//方形:倒计时
|
||||||
|
SkipTypeText = 3,//方形:跳过
|
||||||
|
SkipTypeTimeText = 4,//方形:倒计时+跳过 (default)
|
||||||
|
/** 圆形 */
|
||||||
|
SkipTypeRoundTime = 5,//圆形:倒计时
|
||||||
|
SkipTypeRoundText = 6,//圆形:跳过
|
||||||
|
SkipTypeRoundProgressTime = 7,//圆形:进度圈+倒计时
|
||||||
|
SkipTypeRoundProgressText = 8,//圆形:进度圈+跳过
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface XHLaunchAdButton : UIButton
|
||||||
|
|
||||||
|
- (instancetype)initWithSkipType:(SkipType)skipType;
|
||||||
|
- (void)startRoundDispathTimerWithDuration:(CGFloat )duration;
|
||||||
|
- (void)setTitleWithSkipType:(SkipType)skipType duration:(NSInteger)duration;
|
||||||
|
|
||||||
|
@end
|
||||||
223
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdButton.m
generated
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdSkipButton.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2016/6/9.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAdButton.h"
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
|
||||||
|
/** Progress颜色 */
|
||||||
|
#define RoundProgressColor [UIColor whiteColor]
|
||||||
|
/** 背景色 */
|
||||||
|
#define BackgroundColor [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]
|
||||||
|
/** 字体颜色 */
|
||||||
|
#define FontColor [UIColor whiteColor]
|
||||||
|
|
||||||
|
#define SkipTitle @"跳过"
|
||||||
|
/** 倒计时单位 */
|
||||||
|
#define DurationUnit @"S"
|
||||||
|
|
||||||
|
@interface XHLaunchAdButton()
|
||||||
|
@property(nonatomic,assign)SkipType skipType;
|
||||||
|
@property(nonatomic,assign)CGFloat leftRightSpace;
|
||||||
|
@property(nonatomic,assign)CGFloat topBottomSpace;
|
||||||
|
@property(nonatomic,strong)UILabel *timeLab;
|
||||||
|
@property (nonatomic,strong) CAShapeLayer *roundLayer;
|
||||||
|
@property(nonatomic,copy)dispatch_source_t roundTimer;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation XHLaunchAdButton
|
||||||
|
|
||||||
|
- (instancetype)initWithSkipType:(SkipType)skipType{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
|
||||||
|
_skipType = skipType;
|
||||||
|
CGFloat y = XH_FULLSCREEN ? 44 : 20;
|
||||||
|
self.frame = CGRectMake(XH_ScreenW-80,y, 70, 35);//方形
|
||||||
|
switch (skipType) {
|
||||||
|
case SkipTypeRoundTime:
|
||||||
|
case SkipTypeRoundText:
|
||||||
|
case SkipTypeRoundProgressTime:
|
||||||
|
case SkipTypeRoundProgressText:{//环形
|
||||||
|
self.frame = CGRectMake(XH_ScreenW-55,y, 42, 42);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (skipType) {
|
||||||
|
case SkipTypeNone:{
|
||||||
|
self.hidden = YES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeTime:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
self.leftRightSpace = 5;
|
||||||
|
self.topBottomSpace = 2.5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeText:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
self.leftRightSpace = 5;
|
||||||
|
self.topBottomSpace = 2.5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeTimeText:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
self.leftRightSpace = 5;
|
||||||
|
self.topBottomSpace = 2.5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundTime:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundText:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundProgressTime:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
[self.timeLab.layer addSublayer:self.roundLayer];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundProgressText:{
|
||||||
|
[self addSubview:self.timeLab];
|
||||||
|
[self.timeLab.layer addSublayer:self.roundLayer];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(UILabel *)timeLab{
|
||||||
|
if(_timeLab == nil){
|
||||||
|
_timeLab = [[UILabel alloc] initWithFrame:self.bounds];
|
||||||
|
_timeLab.textColor = FontColor;
|
||||||
|
_timeLab.backgroundColor = BackgroundColor;
|
||||||
|
_timeLab.layer.masksToBounds = YES;
|
||||||
|
_timeLab.textAlignment = NSTextAlignmentCenter;
|
||||||
|
_timeLab.font = [UIFont systemFontOfSize:13.5];
|
||||||
|
[self cornerRadiusWithView:_timeLab];
|
||||||
|
}
|
||||||
|
return _timeLab;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(CAShapeLayer *)roundLayer{
|
||||||
|
if(_roundLayer==nil){
|
||||||
|
_roundLayer = [CAShapeLayer layer];
|
||||||
|
_roundLayer.fillColor = BackgroundColor.CGColor;
|
||||||
|
_roundLayer.strokeColor = RoundProgressColor.CGColor;
|
||||||
|
_roundLayer.lineCap = kCALineCapRound;
|
||||||
|
_roundLayer.lineJoin = kCALineJoinRound;
|
||||||
|
_roundLayer.lineWidth = 2;
|
||||||
|
_roundLayer.frame = self.bounds;
|
||||||
|
_roundLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.timeLab.bounds.size.width/2.0, self.timeLab.bounds.size.width/2.0) radius:self.timeLab.bounds.size.width/2.0-1.0 startAngle:-0.5*M_PI endAngle:1.5*M_PI clockwise:YES].CGPath;
|
||||||
|
_roundLayer.strokeStart = 0;
|
||||||
|
}
|
||||||
|
return _roundLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setTitleWithSkipType:(SkipType)skipType duration:(NSInteger)duration{
|
||||||
|
|
||||||
|
switch (skipType) {
|
||||||
|
case SkipTypeNone:{
|
||||||
|
self.hidden = YES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeTime:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = [NSString stringWithFormat:@"%ld %@",duration,DurationUnit];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeText:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = SkipTitle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeTimeText:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = [NSString stringWithFormat:@"%ld %@",duration,SkipTitle];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundTime:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = [NSString stringWithFormat:@"%ld %@",duration,DurationUnit];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundText:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = SkipTitle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundProgressTime:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = [NSString stringWithFormat:@"%ld %@",duration,DurationUnit];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SkipTypeRoundProgressText:{
|
||||||
|
self.hidden = NO;
|
||||||
|
self.timeLab.text = SkipTitle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)startRoundDispathTimerWithDuration:(CGFloat )duration{
|
||||||
|
NSTimeInterval period = 0.05;
|
||||||
|
__block CGFloat roundDuration = duration;
|
||||||
|
_roundTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
|
||||||
|
dispatch_source_set_timer(_roundTimer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0);
|
||||||
|
dispatch_source_set_event_handler(_roundTimer, ^{
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if(roundDuration<=0){
|
||||||
|
self.roundLayer.strokeStart = 1;
|
||||||
|
DISPATCH_SOURCE_CANCEL_SAFE(self.roundTimer);
|
||||||
|
}
|
||||||
|
self.roundLayer.strokeStart += 1/(duration/period);
|
||||||
|
roundDuration -= period;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
dispatch_resume(_roundTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setLeftRightSpace:(CGFloat)leftRightSpace{
|
||||||
|
_leftRightSpace = leftRightSpace;
|
||||||
|
CGRect frame = self.timeLab.frame;
|
||||||
|
CGFloat width = frame.size.width;
|
||||||
|
if(leftRightSpace<=0 || leftRightSpace*2>= width) return;
|
||||||
|
frame = CGRectMake(leftRightSpace, frame.origin.y, width-2*leftRightSpace, frame.size.height);
|
||||||
|
self.timeLab.frame = frame;
|
||||||
|
[self cornerRadiusWithView:self.timeLab];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setTopBottomSpace:(CGFloat)topBottomSpace{
|
||||||
|
_topBottomSpace = topBottomSpace;
|
||||||
|
CGRect frame = self.timeLab.frame;
|
||||||
|
CGFloat height = frame.size.height;
|
||||||
|
if(topBottomSpace<=0 || topBottomSpace*2>= height) return;
|
||||||
|
frame = CGRectMake(frame.origin.x, topBottomSpace, frame.size.width, height-2*topBottomSpace);
|
||||||
|
self.timeLab.frame = frame;
|
||||||
|
[self cornerRadiusWithView:self.timeLab];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)cornerRadiusWithView:(UIView *)view{
|
||||||
|
CGFloat min = view.frame.size.height;
|
||||||
|
if(view.frame.size.height > view.frame.size.width) {
|
||||||
|
min = view.frame.size.width;
|
||||||
|
}
|
||||||
|
view.layer.cornerRadius = min/2.0;
|
||||||
|
view.layer.masksToBounds = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
199
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdCache.h
generated
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdCache.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 16/6/13.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
typedef void(^SaveCompletionBlock)(BOOL result , NSURL * URL);
|
||||||
|
|
||||||
|
@interface XHLaunchAdCache : NSObject
|
||||||
|
|
||||||
|
#pragma mark - 图片
|
||||||
|
/**
|
||||||
|
* 获取缓存图片
|
||||||
|
*
|
||||||
|
* @param url 图片url
|
||||||
|
*
|
||||||
|
* @return 图片
|
||||||
|
*/
|
||||||
|
+(UIImage *)getCacheImageWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
获取缓存图片
|
||||||
|
|
||||||
|
@param url 图片url
|
||||||
|
@return imageData
|
||||||
|
*/
|
||||||
|
+(NSData *)getCacheImageDataWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
缓存图片
|
||||||
|
|
||||||
|
@param data imageData
|
||||||
|
@param url 图片url
|
||||||
|
@return 缓存结果
|
||||||
|
*/
|
||||||
|
+(BOOL)saveImageData:(NSData *)data imageURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
缓存图片 - 异步
|
||||||
|
|
||||||
|
@param data imageData
|
||||||
|
@param url 图片url
|
||||||
|
@param completedBlock 结果回调
|
||||||
|
*/
|
||||||
|
+(void)async_saveImageData:(NSData *)data imageURL:(NSURL *)url completed:(nullable SaveCompletionBlock)completedBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否已缓存在该图片
|
||||||
|
*
|
||||||
|
* @param url image url
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma mark - 视频
|
||||||
|
+(BOOL)checkImageInCacheWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否已缓存该视频
|
||||||
|
*
|
||||||
|
* @param url video url
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
+(BOOL)checkVideoInCacheWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否已缓存该视频(仅限于本地视频读取使用)
|
||||||
|
*
|
||||||
|
* @param videoFileName 本地视频文件名称
|
||||||
|
*
|
||||||
|
* @return BOOL
|
||||||
|
*/
|
||||||
|
+(BOOL)checkVideoInCacheWithFileName:(NSString *)videoFileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存视频路径
|
||||||
|
*
|
||||||
|
* @param url 视频链接url
|
||||||
|
* @return 视频本地路径
|
||||||
|
*/
|
||||||
|
+(nullable NSURL *)getCacheVideoWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
保存视频到缓存目录
|
||||||
|
|
||||||
|
@param location 视频路径
|
||||||
|
@param url 视频url
|
||||||
|
|
||||||
|
@return 缓存结果
|
||||||
|
*/
|
||||||
|
+(BOOL)saveVideoAtLocation:(NSURL *)location URL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
保存视频到缓存目录 - 异步
|
||||||
|
|
||||||
|
@param location 视频路径
|
||||||
|
@param url 视频url
|
||||||
|
@param completedBlock 结果回调
|
||||||
|
*/
|
||||||
|
+(void)async_saveVideoAtLocation:(NSURL *)location URL:(NSURL *)url completed:(nullable SaveCompletionBlock)completedBlock;;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成视频路径 for url
|
||||||
|
*/
|
||||||
|
+(NSString *)videoPathWithURL:(NSURL *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成视频路径 for videoFileName(仅限于本地视频读取使用)
|
||||||
|
*/
|
||||||
|
+(NSString *)videoPathWithFileName:(NSString *)videoFileName;
|
||||||
|
|
||||||
|
#pragma mark - url缓存
|
||||||
|
/**
|
||||||
|
存储图片url - 异步
|
||||||
|
|
||||||
|
@param url 图片url
|
||||||
|
*/
|
||||||
|
+(void)async_saveImageUrl:(NSString *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
获取最后一次缓存的图片url
|
||||||
|
|
||||||
|
@return url string
|
||||||
|
*/
|
||||||
|
+(NSString *)getCacheImageUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
存储视频url - 异步
|
||||||
|
|
||||||
|
@param url 视频url
|
||||||
|
*/
|
||||||
|
+(void)async_saveVideoUrl:(NSString *)url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
获取最后一次缓存的视频url
|
||||||
|
|
||||||
|
@return url string
|
||||||
|
*/
|
||||||
|
+(NSString *)getCacheVideoUrl;
|
||||||
|
|
||||||
|
#pragma mark - 其他
|
||||||
|
/**
|
||||||
|
* 缓存路径
|
||||||
|
*/
|
||||||
|
+ (NSString *)xhLaunchAdCachePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除XHLaunchAd本地所有缓存(异步)
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url的图片本地缓存(异步)
|
||||||
|
|
||||||
|
@param imageUrlArray 图片Url数组
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheWithImageUrlArray:(NSArray<NSURL *> *)imageUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url除外的图片本地缓存(异步)
|
||||||
|
|
||||||
|
@param exceptImageUrlArray 不需要清除缓存的图片Url数组,此url数组图片缓存将被保留
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheExceptImageUrlArray:(NSArray<NSURL *> *)exceptImageUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url的视频本地缓存(异步)
|
||||||
|
|
||||||
|
@param videoUrlArray 视频url数组
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheWithVideoUrlArray:(NSArray<NSURL *> *)videoUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
清除指定Url除外的视频本地缓存(异步)
|
||||||
|
|
||||||
|
@param exceptVideoUrlArray 不需要清除缓存的视频Url数组,此url数组视频缓存将被保留
|
||||||
|
*/
|
||||||
|
+(void)clearDiskCacheExceptVideoUrlArray:(NSArray<NSURL *> *)exceptVideoUrlArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取XHLaunch本地缓存大小(M)
|
||||||
|
*/
|
||||||
|
+(float)diskCacheSize;
|
||||||
|
|
||||||
|
#pragma mark - other
|
||||||
|
|
||||||
|
+(NSString *)md5String:(NSString *)string;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
293
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdCache.m
generated
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdCache.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 16/6/13.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAdCache.h"
|
||||||
|
#import <CommonCrypto/CommonDigest.h>
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
|
||||||
|
@implementation XHLaunchAdCache
|
||||||
|
|
||||||
|
+(UIImage *)getCacheImageWithURL:(NSURL *)url{
|
||||||
|
if(url==nil) return nil;
|
||||||
|
NSData *data = [NSData dataWithContentsOfFile:[self imagePathWithURL:url]];
|
||||||
|
return [UIImage imageWithData:data];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSData *)getCacheImageDataWithURL:(NSURL *)url{
|
||||||
|
if(url==nil) return nil;
|
||||||
|
return [NSData dataWithContentsOfFile:[self imagePathWithURL:url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(BOOL)saveImageData:(NSData *)data imageURL:(NSURL *)url{
|
||||||
|
NSString *path = [NSString stringWithFormat:@"%@/%@",[self xhLaunchAdCachePath],[self keyWithURL:url]];
|
||||||
|
if (data) {
|
||||||
|
BOOL result = [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil];
|
||||||
|
if (!result) XHLaunchAdLog(@"cache file error for URL: %@", url);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)async_saveImageData:(NSData *)data imageURL:(NSURL *)url completed:(nullable SaveCompletionBlock)completedBlock{
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
BOOL result = [self saveImageData:data imageURL:url];
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if(completedBlock) completedBlock(result , url);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(BOOL)saveVideoAtLocation:(NSURL *)location URL:(NSURL *)url{
|
||||||
|
NSString *savePath = [[self xhLaunchAdCachePath] stringByAppendingPathComponent:[self videoNameWithURL:url]];
|
||||||
|
NSURL *savePathUrl = [NSURL fileURLWithPath:savePath];
|
||||||
|
BOOL result =[[NSFileManager defaultManager] moveItemAtURL:location toURL:savePathUrl error:nil];
|
||||||
|
if(!result) XHLaunchAdLog(@"cache file error for URL: %@", url);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)async_saveVideoAtLocation:(NSURL *)location URL:(NSURL *)url completed:(nullable SaveCompletionBlock)completedBlock{
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
BOOL result = [self saveVideoAtLocation:location URL:url];
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if(completedBlock) completedBlock(result , url);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(nullable NSURL *)getCacheVideoWithURL:(NSURL *)url{
|
||||||
|
NSString *savePath = [[self xhLaunchAdCachePath] stringByAppendingPathComponent:[self videoNameWithURL:url]];
|
||||||
|
//如果存在
|
||||||
|
if([[NSFileManager defaultManager] fileExistsAtPath:savePath]){
|
||||||
|
return [NSURL fileURLWithPath:savePath];
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)xhLaunchAdCachePath{
|
||||||
|
NSString *path =[NSHomeDirectory() stringByAppendingPathComponent:@"Library/XHLaunchAdCache"];
|
||||||
|
[self checkDirectory:path];
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)imagePathWithURL:(NSURL *)url{
|
||||||
|
if(url==nil) return nil;
|
||||||
|
return [[self xhLaunchAdCachePath] stringByAppendingPathComponent:[self keyWithURL:url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)videoPathWithURL:(NSURL *)url{
|
||||||
|
if(url==nil) return nil;
|
||||||
|
return [[self xhLaunchAdCachePath] stringByAppendingPathComponent:[self videoNameWithURL:url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)videoPathWithFileName:(NSString *)videoFileName{
|
||||||
|
if(videoFileName.length==0) return nil;
|
||||||
|
return [[self xhLaunchAdCachePath] stringByAppendingPathComponent:[self videoNameWithURL:[NSURL URLWithString:videoFileName]]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+(BOOL)checkImageInCacheWithURL:(NSURL *)url{
|
||||||
|
return [[NSFileManager defaultManager] fileExistsAtPath:[self imagePathWithURL:url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(BOOL)checkVideoInCacheWithURL:(NSURL *)url{
|
||||||
|
return [[NSFileManager defaultManager] fileExistsAtPath:[self videoPathWithURL:url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(BOOL)checkVideoInCacheWithFileName:(NSString *)videoFileName{
|
||||||
|
return [[NSFileManager defaultManager] fileExistsAtPath:[self videoPathWithFileName:videoFileName]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)checkDirectory:(NSString *)path {
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
BOOL isDir;
|
||||||
|
if (![fileManager fileExistsAtPath:path isDirectory:&isDir]) {
|
||||||
|
[self createBaseDirectoryAtPath:path];
|
||||||
|
} else {
|
||||||
|
if (!isDir) {
|
||||||
|
NSError *error = nil;
|
||||||
|
[fileManager removeItemAtPath:path error:&error];
|
||||||
|
[self createBaseDirectoryAtPath:path];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - url缓存
|
||||||
|
+(void)async_saveImageUrl:(NSString *)url{
|
||||||
|
if(url==nil) return;
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:url forKey:XHCacheImageUrlStringKey];
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)getCacheImageUrl{
|
||||||
|
return [[NSUserDefaults standardUserDefaults] objectForKey:XHCacheImageUrlStringKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)async_saveVideoUrl:(NSString *)url{
|
||||||
|
if(url==nil) return;
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:url forKey:XHCacheVideoUrlStringKey];
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)getCacheVideoUrl{
|
||||||
|
return [[NSUserDefaults standardUserDefaults] objectForKey:XHCacheVideoUrlStringKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - 其他
|
||||||
|
+(void)clearDiskCache{
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
NSString *path = [self xhLaunchAdCachePath];
|
||||||
|
[fileManager removeItemAtPath:path error:nil];
|
||||||
|
[self checkDirectory:[self xhLaunchAdCachePath]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheWithImageUrlArray:(NSArray<NSURL *> *)imageUrlArray{
|
||||||
|
if(imageUrlArray.count==0) return;
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[imageUrlArray enumerateObjectsUsingBlock:^(NSURL * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
if([self checkImageInCacheWithURL:obj]){
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:[self imagePathWithURL:obj] error:nil];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheExceptImageUrlArray:(NSArray<NSURL *> *)exceptImageUrlArray{
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSArray *allFilePaths = [self allFilePathWithDirectoryPath:[self xhLaunchAdCachePath]];
|
||||||
|
NSArray *exceptImagePaths = [self filePathsWithFileUrlArray:exceptImageUrlArray videoType:NO];
|
||||||
|
[allFilePaths enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
if(![exceptImagePaths containsObject:obj] && !XHISVideoTypeWithPath(obj)){
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:obj error:nil];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
XHLaunchAdLog(@"allFilePath = %@",allFilePaths);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheWithVideoUrlArray:(NSArray<NSURL *> *)videoUrlArray{
|
||||||
|
if(videoUrlArray.count==0) return;
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[videoUrlArray enumerateObjectsUsingBlock:^(NSURL * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
if([self checkVideoInCacheWithURL:obj]){
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:[self videoPathWithURL:obj] error:nil];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void)clearDiskCacheExceptVideoUrlArray:(NSArray<NSURL *> *)exceptVideoUrlArray{
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSArray *allFilePaths = [self allFilePathWithDirectoryPath:[self xhLaunchAdCachePath]];
|
||||||
|
NSArray *exceptVideoPaths = [self filePathsWithFileUrlArray:exceptVideoUrlArray videoType:YES];
|
||||||
|
[allFilePaths enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
if(![exceptVideoPaths containsObject:obj] && XHISVideoTypeWithPath(obj)){
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:obj error:nil];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
XHLaunchAdLog(@"allFilePath = %@",allFilePaths);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+(float)diskCacheSize{
|
||||||
|
NSString *directoryPath = [self xhLaunchAdCachePath];
|
||||||
|
BOOL isDir = NO;
|
||||||
|
unsigned long long total = 0;
|
||||||
|
if ([[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:&isDir]) {
|
||||||
|
if (isDir) {
|
||||||
|
NSError *error = nil;
|
||||||
|
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:&error];
|
||||||
|
if (error == nil) {
|
||||||
|
for (NSString *subpath in array) {
|
||||||
|
NSString *path = [directoryPath stringByAppendingPathComponent:subpath];
|
||||||
|
NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error];
|
||||||
|
if (!error) {
|
||||||
|
total += [dict[NSFileSize] unsignedIntegerValue];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total/(1024.0*1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSArray *)filePathsWithFileUrlArray:(NSArray <NSURL *> *)fileUrlArray videoType:(BOOL)videoType{
|
||||||
|
NSMutableArray *filePaths = [[NSMutableArray alloc] init];
|
||||||
|
[fileUrlArray enumerateObjectsUsingBlock:^(NSURL * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
NSString *path;
|
||||||
|
if(videoType){
|
||||||
|
path = [self videoPathWithURL:obj];
|
||||||
|
}else{
|
||||||
|
path = [self imagePathWithURL:obj];
|
||||||
|
}
|
||||||
|
[filePaths addObject:path];
|
||||||
|
}];
|
||||||
|
return filePaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSArray*)allFilePathWithDirectoryPath:(NSString*)directoryPath{
|
||||||
|
NSMutableArray* array = [[NSMutableArray alloc] init];
|
||||||
|
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||||
|
NSArray* tempArray = [fileManager contentsOfDirectoryAtPath:directoryPath error:nil];
|
||||||
|
for (NSString* fileName in tempArray) {
|
||||||
|
BOOL flag = YES;
|
||||||
|
NSString* fullPath = [directoryPath stringByAppendingPathComponent:fileName];
|
||||||
|
if ([fileManager fileExistsAtPath:fullPath isDirectory:&flag]) {
|
||||||
|
if (!flag) {
|
||||||
|
[array addObject:fullPath];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)createBaseDirectoryAtPath:(NSString *)path {
|
||||||
|
__autoreleasing NSError *error = nil;
|
||||||
|
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
|
||||||
|
if (error) {
|
||||||
|
XHLaunchAdLog(@"create cache directory failed, error = %@", error);
|
||||||
|
} else {
|
||||||
|
[self addDoNotBackupAttribute:path];
|
||||||
|
}
|
||||||
|
XHLaunchAdLog(@"XHLaunchAdCachePath = %@",path);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)addDoNotBackupAttribute:(NSString *)path {
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:path];
|
||||||
|
NSError *error = nil;
|
||||||
|
[url setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
|
||||||
|
if (error) {
|
||||||
|
XHLaunchAdLog(@"error to set do not backup attribute, error = %@", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)md5String:(NSString *)string{
|
||||||
|
const char *value = [string UTF8String];
|
||||||
|
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
|
||||||
|
CC_MD5(value, (CC_LONG)strlen(value), outputBuffer);
|
||||||
|
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
|
||||||
|
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
|
||||||
|
[outputString appendFormat:@"%02x",outputBuffer[count]];
|
||||||
|
}
|
||||||
|
return outputString;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)videoNameWithURL:(NSURL *)url{
|
||||||
|
return [[self md5String:url.absoluteString] stringByAppendingString:@".mp4"];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSString *)keyWithURL:(NSURL *)url{
|
||||||
|
return [self md5String:url.absoluteString];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
114
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdConfiguration.h
generated
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdConfiguration.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2016/6/28.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "XHLaunchAdButton.h"
|
||||||
|
#import <MediaPlayer/MediaPlayer.h>
|
||||||
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
#import "XHLaunchAdImageManager.h"
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/** 显示完成动画时间默认时间 */
|
||||||
|
static CGFloat const showFinishAnimateTimeDefault = 0.8;
|
||||||
|
|
||||||
|
/** 显示完成动画类型 */
|
||||||
|
typedef NS_ENUM(NSInteger , ShowFinishAnimate) {
|
||||||
|
/** 无动画 */
|
||||||
|
ShowFinishAnimateNone = 1,
|
||||||
|
/** 普通淡入(default) */
|
||||||
|
ShowFinishAnimateFadein = 2,
|
||||||
|
/** 放大淡入 */
|
||||||
|
ShowFinishAnimateLite = 3,
|
||||||
|
/** 左右翻转(类似网易云音乐) */
|
||||||
|
ShowFinishAnimateFlipFromLeft = 4,
|
||||||
|
/** 下上翻转 */
|
||||||
|
ShowFinishAnimateFlipFromBottom = 5,
|
||||||
|
/** 向上翻页 */
|
||||||
|
ShowFinishAnimateCurlUp = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mark - 公共属性
|
||||||
|
@interface XHLaunchAdConfiguration : NSObject
|
||||||
|
|
||||||
|
/** 停留时间(default 5 ,单位:秒) */
|
||||||
|
@property(nonatomic,assign)NSInteger duration;
|
||||||
|
|
||||||
|
/** 跳过按钮类型(default SkipTypeTimeText) */
|
||||||
|
@property(nonatomic,assign)SkipType skipButtonType;
|
||||||
|
|
||||||
|
/** 显示完成动画(default ShowFinishAnimateFadein) */
|
||||||
|
@property(nonatomic,assign)ShowFinishAnimate showFinishAnimate;
|
||||||
|
|
||||||
|
/** 显示完成动画时间(default 0.8 , 单位:秒) */
|
||||||
|
@property(nonatomic,assign)CGFloat showFinishAnimateTime;
|
||||||
|
|
||||||
|
/** 设置开屏广告的frame(default [UIScreen mainScreen].bounds) */
|
||||||
|
@property (nonatomic,assign) CGRect frame;
|
||||||
|
|
||||||
|
/** 程序从后台恢复时,是否需要展示广告(defailt NO) */
|
||||||
|
@property (nonatomic,assign) BOOL showEnterForeground;
|
||||||
|
|
||||||
|
/** 点击打开页面地址(请使用openModel,点击事件代理方法请对应使用xhLaunchAd:clickAndOpenModel:clickPoint:) */
|
||||||
|
@property(nonatomic,copy)NSString *openURLString XHLaunchAdDeprecated("请使用openModel,点击事件代理方法请对应使用xhLaunchAd:clickAndOpenModel:clickPoint:");
|
||||||
|
|
||||||
|
/** 点击打开页面参数 */
|
||||||
|
@property (nonatomic, strong) id openModel;
|
||||||
|
|
||||||
|
/** 自定义跳过按钮(若定义此视图,将会自定替换系统跳过按钮) */
|
||||||
|
@property(nonatomic,strong) UIView *customSkipView;
|
||||||
|
|
||||||
|
/** 子视图(若定义此属性,这些视图将会被自动添加在广告视图上,frame相对于window) */
|
||||||
|
@property(nonatomic,copy,nullable) NSArray<UIView *> *subViews;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - 图片广告相关
|
||||||
|
@interface XHLaunchImageAdConfiguration : XHLaunchAdConfiguration
|
||||||
|
|
||||||
|
/** image本地图片名(jpg/gif图片请带上扩展名)或网络图片URL string */
|
||||||
|
@property(nonatomic,copy)NSString *imageNameOrURLString;
|
||||||
|
|
||||||
|
/** 图片广告缩放模式(default UIViewContentModeScaleToFill) */
|
||||||
|
@property(nonatomic,assign)UIViewContentMode contentMode;
|
||||||
|
|
||||||
|
/** 缓存机制(default XHLaunchImageDefault) */
|
||||||
|
@property(nonatomic,assign)XHLaunchAdImageOptions imageOption;
|
||||||
|
|
||||||
|
/** 设置GIF动图是否只循环播放一次(YES:只播放一次,NO:循环播放,default NO,仅对动图设置有效) */
|
||||||
|
@property (nonatomic, assign) BOOL GIFImageCycleOnce;
|
||||||
|
|
||||||
|
+(XHLaunchImageAdConfiguration *)defaultConfiguration;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - 视频广告相关
|
||||||
|
@interface XHLaunchVideoAdConfiguration : XHLaunchAdConfiguration
|
||||||
|
|
||||||
|
/** video本地名或网络链接URL string */
|
||||||
|
@property(nonatomic,copy)NSString *videoNameOrURLString;
|
||||||
|
|
||||||
|
/** 视频缩放模式(default MPMovieScalingModeAspectFill) */
|
||||||
|
@property(nonatomic,assign)MPMovieScalingMode scalingMode XHLaunchAdDeprecated("请使用videoGravity");
|
||||||
|
|
||||||
|
/** 视频缩放模式(default AVLayerVideoGravityResizeAspectFill) */
|
||||||
|
@property (nonatomic, copy) AVLayerVideoGravity videoGravity;
|
||||||
|
|
||||||
|
/** 设置视频是否只循环播放一次(YES:只播放一次,NO循环播放,default NO) */
|
||||||
|
@property (nonatomic, assign) BOOL videoCycleOnce;
|
||||||
|
|
||||||
|
/** 是否关闭音频(default NO) */
|
||||||
|
@property (nonatomic, assign) BOOL muted;
|
||||||
|
|
||||||
|
+(XHLaunchVideoAdConfiguration *)defaultConfiguration;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
70
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdConfiguration.m
generated
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdConfiguration.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2016/6/28.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAdConfiguration.h"
|
||||||
|
|
||||||
|
#pragma mark - 公共
|
||||||
|
@implementation XHLaunchAdConfiguration
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - 图片广告相关
|
||||||
|
@implementation XHLaunchImageAdConfiguration
|
||||||
|
|
||||||
|
+(XHLaunchImageAdConfiguration *)defaultConfiguration{
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchImageAdConfiguration *configuration = [XHLaunchImageAdConfiguration new];
|
||||||
|
//广告停留时间
|
||||||
|
configuration.duration = 5;
|
||||||
|
//广告frame
|
||||||
|
configuration.frame = [UIScreen mainScreen].bounds;
|
||||||
|
//设置GIF动图是否只循环播放一次(仅对动图设置有效)
|
||||||
|
configuration.GIFImageCycleOnce = NO;
|
||||||
|
//缓存机制
|
||||||
|
configuration.imageOption = XHLaunchAdImageDefault;
|
||||||
|
//图片填充模式
|
||||||
|
configuration.contentMode = UIViewContentModeScaleToFill;
|
||||||
|
//广告显示完成动画
|
||||||
|
configuration.showFinishAnimate =ShowFinishAnimateFadein;
|
||||||
|
//显示完成动画时间
|
||||||
|
configuration.showFinishAnimateTime = showFinishAnimateTimeDefault;
|
||||||
|
//跳过按钮类型
|
||||||
|
configuration.skipButtonType = SkipTypeTimeText;
|
||||||
|
//后台返回时,是否显示广告
|
||||||
|
configuration.showEnterForeground = NO;
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - 视频广告相关
|
||||||
|
@implementation XHLaunchVideoAdConfiguration
|
||||||
|
+(XHLaunchVideoAdConfiguration *)defaultConfiguration{
|
||||||
|
//配置广告数据
|
||||||
|
XHLaunchVideoAdConfiguration *configuration = [XHLaunchVideoAdConfiguration new];
|
||||||
|
//广告停留时间
|
||||||
|
configuration.duration = 5;
|
||||||
|
//广告frame
|
||||||
|
configuration.frame = [UIScreen mainScreen].bounds;
|
||||||
|
//视频填充模式
|
||||||
|
configuration.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||||
|
//是否只循环播放一次
|
||||||
|
configuration.videoCycleOnce = NO;
|
||||||
|
//广告显示完成动画
|
||||||
|
configuration.showFinishAnimate =ShowFinishAnimateFadein;
|
||||||
|
//显示完成动画时间
|
||||||
|
configuration.showFinishAnimateTime = showFinishAnimateTimeDefault;
|
||||||
|
//跳过按钮类型
|
||||||
|
configuration.skipButtonType = SkipTypeTimeText;
|
||||||
|
//后台返回时,是否显示广告
|
||||||
|
configuration.showEnterForeground = NO;
|
||||||
|
//是否静音播放
|
||||||
|
configuration.muted = NO;
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
@end
|
||||||
87
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdConst.h
generated
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdConst.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2017/9/18.
|
||||||
|
// Copyright © 2017年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#define XHLaunchAdDeprecated(instead) __attribute__((deprecated(instead)))
|
||||||
|
|
||||||
|
#define XHWeakSelf __weak typeof(self) weakSelf = self;
|
||||||
|
|
||||||
|
#define XH_ScreenW [UIScreen mainScreen].bounds.size.width
|
||||||
|
#define XH_ScreenH [UIScreen mainScreen].bounds.size.height
|
||||||
|
|
||||||
|
#define XH_IPHONEX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
|
||||||
|
#define XH_IPHONEXR ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) : NO)
|
||||||
|
#define XH_IPHONEXSMAX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) : NO)
|
||||||
|
#define XH_FULLSCREEN ((XH_IPHONEX || XH_IPHONEXR || XH_IPHONEXSMAX) ? YES : NO)
|
||||||
|
|
||||||
|
|
||||||
|
#define XHISURLString(string) ([string hasPrefix:@"https://"] || [string hasPrefix:@"http://"]) ? YES:NO
|
||||||
|
#define XHStringContainsSubString(string,subString) ([string rangeOfString:subString].location == NSNotFound) ? NO:YES
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define XHLaunchAdLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
|
||||||
|
#else
|
||||||
|
#define XHLaunchAdLog(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XHISGIFTypeWithData(data)\
|
||||||
|
({\
|
||||||
|
BOOL result = NO;\
|
||||||
|
if(!data) result = NO;\
|
||||||
|
uint8_t c;\
|
||||||
|
[data getBytes:&c length:1];\
|
||||||
|
if(c == 0x47) result = YES;\
|
||||||
|
(result);\
|
||||||
|
})
|
||||||
|
|
||||||
|
#define XHISVideoTypeWithPath(path)\
|
||||||
|
({\
|
||||||
|
BOOL result = NO;\
|
||||||
|
if([path hasSuffix:@".mp4"]) result = YES;\
|
||||||
|
(result);\
|
||||||
|
})
|
||||||
|
|
||||||
|
#define XHDataWithFileName(name)\
|
||||||
|
({\
|
||||||
|
NSData *data = nil;\
|
||||||
|
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:nil];\
|
||||||
|
if([[NSFileManager defaultManager] fileExistsAtPath:path]){\
|
||||||
|
data = [NSData dataWithContentsOfFile:path];\
|
||||||
|
}\
|
||||||
|
(data);\
|
||||||
|
})
|
||||||
|
|
||||||
|
#define DISPATCH_SOURCE_CANCEL_SAFE(time) if(time)\
|
||||||
|
{\
|
||||||
|
dispatch_source_cancel(time);\
|
||||||
|
time = nil;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REMOVE_FROM_SUPERVIEW_SAFE(view) if(view)\
|
||||||
|
{\
|
||||||
|
[view removeFromSuperview];\
|
||||||
|
view = nil;\
|
||||||
|
}
|
||||||
|
|
||||||
|
UIKIT_EXTERN NSString *const XHCacheImageUrlStringKey;
|
||||||
|
UIKIT_EXTERN NSString *const XHCacheVideoUrlStringKey;
|
||||||
|
|
||||||
|
UIKIT_EXTERN NSString *const XHLaunchAdWaitDataDurationArriveNotification;
|
||||||
|
UIKIT_EXTERN NSString *const XHLaunchAdDetailPageWillShowNotification;
|
||||||
|
UIKIT_EXTERN NSString *const XHLaunchAdDetailPageShowFinishNotification;
|
||||||
|
/** GIFImageCycleOnce = YES(GIF不循环)时, GIF动图播放完成通知 */
|
||||||
|
UIKIT_EXTERN NSString *const XHLaunchAdGIFImageCycleOnceFinishNotification;
|
||||||
|
/** videoCycleOnce = YES(视频不循环时) ,video播放完成通知 */
|
||||||
|
UIKIT_EXTERN NSString *const XHLaunchAdVideoCycleOnceFinishNotification;
|
||||||
|
/** 视频播放失败通知 */
|
||||||
|
UIKIT_EXTERN NSString *const XHLaunchAdVideoPlayFailedNotification;
|
||||||
|
UIKIT_EXTERN BOOL XHLaunchAdPrefersHomeIndicatorAutoHidden;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
22
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdConst.m
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdConst.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2017/9/18.
|
||||||
|
// Copyright © 2017年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
|
||||||
|
NSString *const XHCacheImageUrlStringKey = @"XHCacheImageUrlStringKey";
|
||||||
|
NSString *const XHCacheVideoUrlStringKey = @"XHCacheVideoUrlStringKey";
|
||||||
|
|
||||||
|
NSString *const XHLaunchAdWaitDataDurationArriveNotification = @"XHLaunchAdWaitDataDurationArriveNotification";
|
||||||
|
NSString *const XHLaunchAdDetailPageWillShowNotification = @"XHLaunchAdDetailPageWillShowNotification";
|
||||||
|
NSString *const XHLaunchAdDetailPageShowFinishNotification = @"XHLaunchAdDetailPageShowFinishNotification";
|
||||||
|
NSString *const XHLaunchAdGIFImageCycleOnceFinishNotification = @"XHLaunchAdGIFImageCycleOnceFinishNotification";
|
||||||
|
NSString *const XHLaunchAdVideoCycleOnceFinishNotification = @"XHLaunchAdVideoCycleOnceFinishNotification";
|
||||||
|
NSString *const XHLaunchAdVideoPlayFailedNotification = @"XHLaunchAdVideoPlayFailedNotification";
|
||||||
|
|
||||||
|
BOOL XHLaunchAdPrefersHomeIndicatorAutoHidden = NO;
|
||||||
|
|
||||||
13
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdController.h
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdController.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2017/5/26.
|
||||||
|
// Copyright © 2017年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface XHLaunchAdController : UIViewController
|
||||||
|
|
||||||
|
@end
|
||||||
28
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdController.m
generated
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdController.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 2017/5/26.
|
||||||
|
// Copyright © 2017年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAdController.h"
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
|
||||||
|
@interface XHLaunchAdController ()
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation XHLaunchAdController
|
||||||
|
|
||||||
|
-(BOOL)shouldAutorotate{
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)prefersHomeIndicatorAutoHidden{
|
||||||
|
|
||||||
|
return XHLaunchAdPrefersHomeIndicatorAutoHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
56
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdDownloader.h
generated
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdDownloaderManager.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 16/12/1.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#pragma mark - XHLaunchAdDownload
|
||||||
|
|
||||||
|
typedef void(^XHLaunchAdDownloadProgressBlock)(unsigned long long total, unsigned long long current);
|
||||||
|
|
||||||
|
typedef void(^XHLaunchAdDownloadImageCompletedBlock)(UIImage *_Nullable image, NSData * _Nullable data, NSError * _Nullable error);
|
||||||
|
|
||||||
|
typedef void(^XHLaunchAdDownloadVideoCompletedBlock)(NSURL * _Nullable location, NSError * _Nullable error);
|
||||||
|
|
||||||
|
typedef void(^XHLaunchAdBatchDownLoadAndCacheCompletedBlock) (NSArray * _Nonnull completedArray);
|
||||||
|
|
||||||
|
@protocol XHLaunchAdDownloadDelegate <NSObject>
|
||||||
|
|
||||||
|
- (void)downloadFinishWithURL:(nonnull NSURL *)url;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface XHLaunchAdDownload : NSObject
|
||||||
|
@property (assign, nonatomic ,nonnull)id<XHLaunchAdDownloadDelegate> delegate;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface XHLaunchAdImageDownload : XHLaunchAdDownload
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface XHLaunchAdVideoDownload : XHLaunchAdDownload
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - XHLaunchAdDownloader
|
||||||
|
@interface XHLaunchAdDownloader : NSObject
|
||||||
|
|
||||||
|
+(nonnull instancetype )sharedDownloader;
|
||||||
|
|
||||||
|
- (void)downloadImageWithURL:(nonnull NSURL *)url progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHLaunchAdDownloadImageCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
- (void)downLoadImageAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray;
|
||||||
|
- (void)downLoadImageAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
- (void)downloadVideoWithURL:(nonnull NSURL *)url progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHLaunchAdDownloadVideoCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
- (void)downLoadVideoAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray;
|
||||||
|
- (void)downLoadVideoAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
331
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdDownloader.m
generated
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdDownloaderManager.m
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 16/12/1.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import "XHLaunchAdDownloader.h"
|
||||||
|
#import "XHLaunchAdCache.h"
|
||||||
|
#import "XHLaunchAdConst.h"
|
||||||
|
|
||||||
|
#if __has_include(<FLAnimatedImage/FLAnimatedImage.h>)
|
||||||
|
#import <FLAnimatedImage/FLAnimatedImage.h>
|
||||||
|
#else
|
||||||
|
#import "FLAnimatedImage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma mark - XHLaunchAdDownload
|
||||||
|
|
||||||
|
@interface XHLaunchAdDownload()
|
||||||
|
|
||||||
|
@property (strong, nonatomic) NSURLSession *session;
|
||||||
|
@property(strong,nonatomic)NSURLSessionDownloadTask *downloadTask;
|
||||||
|
@property (nonatomic, assign) unsigned long long totalLength;
|
||||||
|
@property (nonatomic, assign) unsigned long long currentLength;
|
||||||
|
@property (nonatomic, copy) XHLaunchAdDownloadProgressBlock progressBlock;
|
||||||
|
@property (strong, nonatomic) NSURL *url;
|
||||||
|
|
||||||
|
@end
|
||||||
|
@implementation XHLaunchAdDownload
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - XHLaunchAdImageDownload
|
||||||
|
@interface XHLaunchAdImageDownload()<NSURLSessionDownloadDelegate,NSURLSessionTaskDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, copy ) XHLaunchAdDownloadImageCompletedBlock completedBlock;
|
||||||
|
|
||||||
|
@end
|
||||||
|
@implementation XHLaunchAdImageDownload
|
||||||
|
|
||||||
|
-(nonnull instancetype)initWithURL:(nonnull NSURL *)url delegateQueue:(nonnull NSOperationQueue *)queue progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHLaunchAdDownloadImageCompletedBlock)completedBlock{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
self.url = url;
|
||||||
|
self.progressBlock = progressBlock;
|
||||||
|
self.completedBlock = completedBlock;
|
||||||
|
NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||||
|
sessionConfiguration.timeoutIntervalForRequest = 15.0;
|
||||||
|
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
|
||||||
|
delegate:self
|
||||||
|
delegateQueue:queue];
|
||||||
|
self.downloadTask = [self.session downloadTaskWithRequest:[NSURLRequest requestWithURL:url]];
|
||||||
|
[self.downloadTask resume];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSURLSessionDownloadDelegate
|
||||||
|
- (void)URLSession:(NSURLSession *)session
|
||||||
|
downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||||
|
didFinishDownloadingToURL:(NSURL *)location {
|
||||||
|
NSData *data = [NSData dataWithContentsOfURL:location];
|
||||||
|
UIImage *image = [UIImage imageWithData:data];
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (self.completedBlock) {
|
||||||
|
self.completedBlock(image,data, nil);
|
||||||
|
// 防止重复调用
|
||||||
|
self.completedBlock = nil;
|
||||||
|
}
|
||||||
|
//下载完成回调
|
||||||
|
if ([self.delegate respondsToSelector:@selector(downloadFinishWithURL:)]) {
|
||||||
|
[self.delegate downloadFinishWithURL:self.url];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//销毁
|
||||||
|
[self.session invalidateAndCancel];
|
||||||
|
self.session = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
|
||||||
|
self.currentLength = totalBytesWritten;
|
||||||
|
self.totalLength = totalBytesExpectedToWrite;
|
||||||
|
if (self.progressBlock) {
|
||||||
|
self.progressBlock(self.totalLength, self.currentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||||
|
if (error){
|
||||||
|
XHLaunchAdLog(@"error = %@",error);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (self.completedBlock) {
|
||||||
|
self.completedBlock(nil,nil, error);
|
||||||
|
}
|
||||||
|
self.completedBlock = nil;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理HTTPS请求的
|
||||||
|
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{
|
||||||
|
NSURLProtectionSpace *protectionSpace = challenge.protectionSpace;
|
||||||
|
if ([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
||||||
|
SecTrustRef serverTrust = protectionSpace.serverTrust;
|
||||||
|
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);
|
||||||
|
} else {
|
||||||
|
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma makr - XHLaunchAdVideoDownload
|
||||||
|
@interface XHLaunchAdVideoDownload()<NSURLSessionDownloadDelegate,NSURLSessionTaskDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, copy ) XHLaunchAdDownloadVideoCompletedBlock completedBlock;
|
||||||
|
@end
|
||||||
|
@implementation XHLaunchAdVideoDownload
|
||||||
|
|
||||||
|
-(nonnull instancetype)initWithURL:(nonnull NSURL *)url delegateQueue:(nonnull NSOperationQueue *)queue progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHLaunchAdDownloadVideoCompletedBlock)completedBlock{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
self.url = url;
|
||||||
|
self.progressBlock = progressBlock;
|
||||||
|
_completedBlock = completedBlock;
|
||||||
|
NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||||
|
sessionConfiguration.timeoutIntervalForRequest = 15.0;
|
||||||
|
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
|
||||||
|
delegate:self
|
||||||
|
delegateQueue:queue];
|
||||||
|
self.downloadTask = [self.session downloadTaskWithRequest:[NSURLRequest requestWithURL:url]];
|
||||||
|
[self.downloadTask resume];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSURLSessionDownloadDelegate
|
||||||
|
- (void)URLSession:(NSURLSession *)session
|
||||||
|
downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||||
|
didFinishDownloadingToURL:(NSURL *)location {
|
||||||
|
NSError *error=nil;
|
||||||
|
NSURL *toURL = [NSURL fileURLWithPath:[XHLaunchAdCache videoPathWithURL:self.url]];
|
||||||
|
|
||||||
|
[[NSFileManager defaultManager] copyItemAtURL:location toURL:toURL error:&error];//复制到缓存目录
|
||||||
|
|
||||||
|
if(error) XHLaunchAdLog(@"error = %@",error);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (self.completedBlock) {
|
||||||
|
if(!error){
|
||||||
|
self.completedBlock(toURL,nil);
|
||||||
|
}else{
|
||||||
|
self.completedBlock(nil,error);
|
||||||
|
}
|
||||||
|
// 防止重复调用
|
||||||
|
self.completedBlock = nil;
|
||||||
|
}
|
||||||
|
//下载完成回调
|
||||||
|
if ([self.delegate respondsToSelector:@selector(downloadFinishWithURL:)]) {
|
||||||
|
[self.delegate downloadFinishWithURL:self.url];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
[self.session invalidateAndCancel];
|
||||||
|
self.session = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
|
||||||
|
self.currentLength = totalBytesWritten;
|
||||||
|
self.totalLength = totalBytesExpectedToWrite;
|
||||||
|
if (self.progressBlock) {
|
||||||
|
self.progressBlock(self.totalLength, self.currentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||||
|
if (error){
|
||||||
|
XHLaunchAdLog(@"error = %@",error);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (self.completedBlock) {
|
||||||
|
self.completedBlock(nil, error);
|
||||||
|
}
|
||||||
|
self.completedBlock = nil;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - XHLaunchAdDownloader
|
||||||
|
@interface XHLaunchAdDownloader()<XHLaunchAdDownloadDelegate>
|
||||||
|
@property (strong, nonatomic, nonnull) NSOperationQueue *downloadImageQueue;
|
||||||
|
@property (strong, nonatomic, nonnull) NSOperationQueue *downloadVideoQueue;
|
||||||
|
@property (strong, nonatomic) NSMutableDictionary *allDownloadDict;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation XHLaunchAdDownloader
|
||||||
|
|
||||||
|
+(nonnull instancetype )sharedDownloader{
|
||||||
|
static XHLaunchAdDownloader *instance = nil;
|
||||||
|
static dispatch_once_t oneToken;
|
||||||
|
dispatch_once(&oneToken,^{
|
||||||
|
instance = [[XHLaunchAdDownloader alloc] init];
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_downloadImageQueue = [NSOperationQueue new];
|
||||||
|
_downloadImageQueue.maxConcurrentOperationCount = 6;
|
||||||
|
_downloadImageQueue.name = @"com.it7090.XHLaunchAdDownloadImageQueue";
|
||||||
|
_downloadVideoQueue = [NSOperationQueue new];
|
||||||
|
_downloadVideoQueue.maxConcurrentOperationCount = 3;
|
||||||
|
_downloadVideoQueue.name = @"com.it7090.XHLaunchAdDownloadVideoQueue";
|
||||||
|
XHLaunchAdLog(@"XHLaunchAdCachePath:%@",[XHLaunchAdCache xhLaunchAdCachePath]);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downloadImageWithURL:(nonnull NSURL *)url progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHLaunchAdDownloadImageCompletedBlock)completedBlock{
|
||||||
|
NSString *key = [self keyWithURL:url];
|
||||||
|
if(self.allDownloadDict[key]) return;
|
||||||
|
XHLaunchAdImageDownload * download = [[XHLaunchAdImageDownload alloc] initWithURL:url delegateQueue:_downloadImageQueue progress:progressBlock completed:completedBlock];
|
||||||
|
download.delegate = self;
|
||||||
|
[self.allDownloadDict setObject:download forKey:key];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downloadImageAndCacheWithURL:(nonnull NSURL *)url completed:(void(^)(BOOL result))completedBlock{
|
||||||
|
if(url == nil){
|
||||||
|
if(completedBlock) completedBlock(NO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[self downloadImageWithURL:url progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error) {
|
||||||
|
if(error){
|
||||||
|
if(completedBlock) completedBlock(NO);
|
||||||
|
}else{
|
||||||
|
[XHLaunchAdCache async_saveImageData:data imageURL:url completed:^(BOOL result, NSURL * _Nonnull URL) {
|
||||||
|
if(completedBlock) completedBlock(result);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)downLoadImageAndCacheWithURLArray:(NSArray<NSURL *> *)urlArray{
|
||||||
|
[self downLoadImageAndCacheWithURLArray:urlArray completed:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downLoadImageAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock{
|
||||||
|
if(urlArray.count==0) return;
|
||||||
|
__block NSMutableArray * resultArray = [[NSMutableArray alloc] init];
|
||||||
|
dispatch_group_t downLoadGroup = dispatch_group_create();
|
||||||
|
[urlArray enumerateObjectsUsingBlock:^(NSURL *url, NSUInteger idx, BOOL *stop) {
|
||||||
|
if(![XHLaunchAdCache checkImageInCacheWithURL:url]){
|
||||||
|
dispatch_group_enter(downLoadGroup);
|
||||||
|
[self downloadImageAndCacheWithURL:url completed:^(BOOL result) {
|
||||||
|
dispatch_group_leave(downLoadGroup);
|
||||||
|
[resultArray addObject:@{@"url":url.absoluteString,@"result":@(result)}];
|
||||||
|
}];
|
||||||
|
}else{
|
||||||
|
[resultArray addObject:@{@"url":url.absoluteString,@"result":@(YES)}];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
dispatch_group_notify(downLoadGroup, dispatch_get_main_queue(), ^{
|
||||||
|
if(completedBlock) completedBlock(resultArray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downloadVideoWithURL:(nonnull NSURL *)url progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHLaunchAdDownloadVideoCompletedBlock)completedBlock{
|
||||||
|
NSString *key = [self keyWithURL:url];
|
||||||
|
if(self.allDownloadDict[key]) return;
|
||||||
|
XHLaunchAdVideoDownload * download = [[XHLaunchAdVideoDownload alloc] initWithURL:url delegateQueue:_downloadVideoQueue progress:progressBlock completed:completedBlock];
|
||||||
|
download.delegate = self;
|
||||||
|
[self.allDownloadDict setObject:download forKey:key];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downloadVideoAndCacheWithURL:(nonnull NSURL *)url completed:(void(^)(BOOL result))completedBlock{
|
||||||
|
if(url == nil){
|
||||||
|
if(completedBlock) completedBlock(NO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[self downloadVideoWithURL:url progress:nil completed:^(NSURL * _Nullable location, NSError * _Nullable error) {
|
||||||
|
if(error){
|
||||||
|
if(completedBlock) completedBlock(NO);
|
||||||
|
}else{
|
||||||
|
if(completedBlock) completedBlock(YES);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downLoadVideoAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray{
|
||||||
|
[self downLoadVideoAndCacheWithURLArray:urlArray completed:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downLoadVideoAndCacheWithURLArray:(nonnull NSArray <NSURL *> * )urlArray completed:(nullable XHLaunchAdBatchDownLoadAndCacheCompletedBlock)completedBlock{
|
||||||
|
if(urlArray.count==0) return;
|
||||||
|
__block NSMutableArray * resultArray = [[NSMutableArray alloc] init];
|
||||||
|
dispatch_group_t downLoadGroup = dispatch_group_create();
|
||||||
|
[urlArray enumerateObjectsUsingBlock:^(NSURL *url, NSUInteger idx, BOOL *stop) {
|
||||||
|
if(![XHLaunchAdCache checkVideoInCacheWithURL:url]){
|
||||||
|
dispatch_group_enter(downLoadGroup);
|
||||||
|
[self downloadVideoAndCacheWithURL:url completed:^(BOOL result) {
|
||||||
|
dispatch_group_leave(downLoadGroup);
|
||||||
|
[resultArray addObject:@{@"url":url.absoluteString,@"result":@(result)}];
|
||||||
|
}];
|
||||||
|
}else{
|
||||||
|
[resultArray addObject:@{@"url":url.absoluteString,@"result":@(YES)}];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
dispatch_group_notify(downLoadGroup, dispatch_get_main_queue(), ^{
|
||||||
|
if(completedBlock) completedBlock(resultArray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableDictionary *)allDownloadDict {
|
||||||
|
if (!_allDownloadDict) {
|
||||||
|
_allDownloadDict = [[NSMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
return _allDownloadDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)downloadFinishWithURL:(NSURL *)url{
|
||||||
|
[self.allDownloadDict removeObjectForKey:[self keyWithURL:url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSString *)keyWithURL:(NSURL *)url{
|
||||||
|
return [XHLaunchAdCache md5String:url.absoluteString];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
31
Pods/XHLaunchAd/XHLaunchAd/XHLaunchAd/XHLaunchAdImageManager.h
generated
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// XHLaunchAdImageManager.h
|
||||||
|
// XHLaunchAdExample
|
||||||
|
//
|
||||||
|
// Created by zhuxiaohui on 16/12/2.
|
||||||
|
// Copyright © 2016年 it7090.com. All rights reserved.
|
||||||
|
// 代码地址:https://github.com/CoderZhuXH/XHLaunchAd
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "XHLaunchAdDownloader.h"
|
||||||
|
|
||||||
|
typedef NS_OPTIONS(NSUInteger, XHLaunchAdImageOptions) {
|
||||||
|
/** 有缓存,读取缓存,不重新下载,没缓存先下载,并缓存 */
|
||||||
|
XHLaunchAdImageDefault = 1 << 0,
|
||||||
|
/** 只下载,不缓存 */
|
||||||
|
XHLaunchAdImageOnlyLoad = 1 << 1,
|
||||||
|
/** 先读缓存,再下载刷新图片和缓存 */
|
||||||
|
XHLaunchAdImageRefreshCached = 1 << 2 ,
|
||||||
|
/** 后台缓存本次不显示,缓存OK后下次再显示(建议使用这种方式)*/
|
||||||
|
XHLaunchAdImageCacheInBackground = 1 << 3
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void(^XHExternalCompletionBlock)(UIImage * _Nullable image,NSData * _Nullable imageData, NSError * _Nullable error, NSURL * _Nullable imageURL);
|
||||||
|
|
||||||
|
@interface XHLaunchAdImageManager : NSObject
|
||||||
|
|
||||||
|
+(nonnull instancetype )sharedManager;
|
||||||
|
- (void)loadImageWithURL:(nullable NSURL *)url options:(XHLaunchAdImageOptions)options progress:(nullable XHLaunchAdDownloadProgressBlock)progressBlock completed:(nullable XHExternalCompletionBlock)completedBlock;
|
||||||
|
|
||||||
|
@end
|
||||||