Parcourir la source

Merge branch 'community'

* community: (39 commits)
  1.修改PQSingletoMemoryUtil属性commandVideoItem类型为BFVideoItemProtocol
  1.修改版本1.0.2
  1.修改播放起
  tag 1.0.1
  1.更新播放器版本
  1.修改素材选择页布局
  1.添加判断值
  1.修改bugs
  1.优化更新视频流程
  1.添加未读数获取地址
  1.更新意见反馈Appkey
  1.修改视频filter累加问题
  1.修改埋点上报
  1.修改filter方法
  1.修改参数
  增加topicinfo解析
  1.修改加载逻辑
  1.添加方法
  add url
  1.卡点视频发布页调整
  ...

# Conflicts:
#	BFFramework.podspec
#	BFFramework/Classes/BFModules/BFCategorys/BFColor+Ext.swift
#	BFFramework/Classes/BFModules/BFCategorys/BFUIButton+ext.swift
#	BFFramework/Classes/BFModules/BFCategorys/BFUIImage+Ext.swift
#	BFFramework/Classes/Base/Controller/PQBaseViewController.swift
#	BFFramework/Classes/Base/Controller/PQPhotoAlbumController.swift
#	BFFramework/Classes/Base/Controller/PQPhotoMaterialController.swift
#	BFFramework/Classes/Base/View/PQLoadingHUB.swift
#	BFFramework/Classes/Base/ViewModel/PQBaseViewModel.swift
#	BFFramework/Classes/Enums/Enums.swift
#	BFFramework/Classes/PQGPUImage/akfilters/PQImageFilter.swift
#	BFFramework/Classes/PQGPUImage/akfilters/PQMovieFilter.swift
#	BFFramework/Classes/Stuckpoint/Controller/PQStuckPointEditerController.swift
#	BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicController.swift
#	BFFramework/Classes/Stuckpoint/Controller/PQStuckPointPublicController.swift
#	BFFramework/Classes/Stuckpoint/View/PQSelectedMaterialListView.swift
#	BFFramework/Classes/Stuckpoint/View/PQStuckPointMusicContentCell.swift
#	BFFramework/Classes/Stuckpoint/ViewModel/PQGPUImagePlayerView.swift
#	BFFramework/Classes/Stuckpoint/ViewModel/PQStuckPointViewModel.swift
#	BFFramework/Classes/Utils/PQCommonMethodUtil.swift
huzhiqiang il y a 3 ans
Parent
commit
4eaf709a19
100 fichiers modifiés avec 544 ajouts et 6355 suppressions
  1. 10 14
      BFFramework.podspec
  2. 0 3
      BFFramework/Classes/BFFramework_custom_umbrella.h
  3. 0 22
      BFFramework/Classes/BFModules/BFCategorys/BFBundle+Ext.swift
  4. 0 109
      BFFramework/Classes/BFModules/BFCategorys/BFInt+Ext.swift
  5. 0 203
      BFFramework/Classes/BFModules/BFCategorys/BFString+Ext.swift
  6. 0 490
      BFFramework/Classes/BFModules/BFCategorys/BFUIView+Ext.swift
  7. 0 176
      BFFramework/Classes/BFModules/BFCategorys/NXFundation+Ext.swift
  8. 0 392
      BFFramework/Classes/BFModules/BFCategorys/NXUI+Ext.swift
  9. 0 77
      BFFramework/Classes/BFModules/BFCategorys/NXUIColor+Ext.swift
  10. 0 32
      BFFramework/Classes/BFModules/BFCategorys/UIControl+NXCategory.h
  11. 0 68
      BFFramework/Classes/BFModules/BFCategorys/UIControl+NXCategory.m
  12. 0 174
      BFFramework/Classes/BFModules/BFDebug/NXLogger.swift
  13. 0 68
      BFFramework/Classes/BFModules/BFDebug/NXLoggerManager.swift
  14. 0 188
      BFFramework/Classes/BFModules/BFDebug/NXLoggerVC.swift
  15. 0 13
      BFFramework/Classes/BFModules/BFMacro/NXConfig.swift
  16. 0 159
      BFFramework/Classes/BFModules/BFUtility/NXAudioRecorder.swift
  17. 0 113
      BFFramework/Classes/BFModules/BFUtility/NXDeviceManager.swift
  18. 0 43
      BFFramework/Classes/BFModules/BFUtility/NXFileManager.swift
  19. 35 34
      BFFramework/Classes/BFModules/BFUtility/PQAliOssUtil.swift
  20. 0 22
      BFFramework/Classes/BFModules/BFUtility/PQBridgeObject.h
  21. 0 56
      BFFramework/Classes/BFModules/BFUtility/PQBridgeObject.m
  22. 0 180
      BFFramework/Classes/BFModules/BFUtility/PQCreateEmptyWAV.swift
  23. 0 526
      BFFramework/Classes/BFModules/BFUtility/PQLZStringUtil.swift
  24. 0 778
      BFFramework/Classes/BFModules/BFUtility/PQPHAssetVideoParaseUtil.swift
  25. 1 0
      BFFramework/Classes/BFModules/BFUtility/PQSingletoRealmUtil.swift
  26. 1 0
      BFFramework/Classes/BFModules/BFUtility/PQSingletoSourcesFileUtil.swift
  27. 46 11
      BFFramework/Classes/BFModules/BFUtility/PQSingletoVideoPlayer.swift
  28. 0 95
      BFFramework/Classes/BFModules/BFUtility/PQVideoSnapshotUtil.swift
  29. 0 48
      BFFramework/Classes/BFModules/BFUtility/PQWeakTimer.swift
  30. 0 156
      BFFramework/Classes/BFModules/BFUtility/SWNetRequest.swift
  31. 0 184
      BFFramework/Classes/Base/Controller/PQBaseWebViewController.swift
  32. 0 46
      BFFramework/Classes/Base/Controller/PQNavigatinController.swift
  33. 0 189
      BFFramework/Classes/Base/Model/PQBaseModel.swift
  34. 2 1
      BFFramework/Classes/Base/View/PQActivityIndicatorView.swift
  35. 2 1
      BFFramework/Classes/Base/View/PQAssetCategoryCell.swift
  36. 4 3
      BFFramework/Classes/Base/View/PQBaseVideoInfoView.swift
  37. 0 254
      BFFramework/Classes/Base/View/PQChoseMaterialCell.swift
  38. 0 121
      BFFramework/Classes/Base/View/PQFollowButton.swift
  39. 0 41
      BFFramework/Classes/Base/View/PQGIFImageView.swift
  40. 0 53
      BFFramework/Classes/Base/View/PQHeartAnimation.swift
  41. 0 515
      BFFramework/Classes/Base/View/PQRemindView.swift
  42. 2 1
      BFFramework/Classes/Base/View/PQSectionHeadView.swift
  43. 1 0
      BFFramework/Classes/Base/View/PQSelectedOprationView.swift
  44. 0 27
      BFFramework/Classes/Base/View/PQTabBar.swift
  45. 0 106
      BFFramework/Classes/Base/View/PQTextView.swift
  46. 30 28
      BFFramework/Classes/Base/ViewModel/PQBaseViewModel.swift
  47. 1 0
      BFFramework/Classes/Base/ViewModel/PQDownloadFileManager.swift
  48. 2 0
      BFFramework/Classes/Base/ViewModel/PQDownloadManager.swift
  49. 2 0
      BFFramework/Classes/Base/ViewModel/PQSessionManager.swift
  50. 22 13
      BFFramework/Classes/Base/ViewModel/PQUploadViewModel.swift
  51. 1 0
      BFFramework/Classes/EventTrack/Model/PQVideoMakeEventTrackModel.swift
  52. 31 21
      BFFramework/Classes/EventTrack/ViewModel/PQEventTrackViewModel.swift
  53. 1 0
      BFFramework/Classes/PModels/PQDownloadModel.swift
  54. 1 0
      BFFramework/Classes/PModels/PQLoginUserInfo.swift
  55. 1 0
      BFFramework/Classes/PModels/PQReCreateModel.swift
  56. 1 0
      BFFramework/Classes/PModels/PQUploadModel.swift
  57. 1 0
      BFFramework/Classes/PModels/PQUserInfoModel.swift
  58. 130 18
      BFFramework/Classes/PModels/PQVideoListModel.swift
  59. 1 0
      BFFramework/Classes/PModels/editDarftModels/PQEditAudioTrackMaterialModel.swift
  60. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditAudioTrackModel.swift
  61. 1 0
      BFFramework/Classes/PModels/editDarftModels/PQEditBaseModel.swift
  62. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditFileMergeTable.swift
  63. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditProjectModel.swift
  64. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditSdataModel.swift
  65. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditSectionModel.swift
  66. 1 0
      BFFramework/Classes/PModels/editDarftModels/PQEditSectionTimelineModel.swift
  67. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditSubtitleInfoModel.swift
  68. 2 1
      BFFramework/Classes/PModels/editDarftModels/PQEditVisionTrackMaterialsModel.swift
  69. 2 0
      BFFramework/Classes/PModels/editDarftModels/PQEditVisionTrackModel.swift
  70. 2 0
      BFFramework/Classes/PQGPUImage/Source/iOS/MovieOutput.swift
  71. 1 0
      BFFramework/Classes/PQGPUImage/Source/iOS/SpeakerOutput.swift
  72. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/Extension/String+Video.swift
  73. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/PQBaseFilter.swift
  74. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/PQGPUImageDebugFilter.swift
  75. 1 1
      BFFramework/Classes/PQGPUImage/akfilters/PQGPUImageFilterGroup.swift
  76. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/PQGPUImageTools.swift
  77. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/PQGifFilter.swift
  78. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/PQMovieInput.swift
  79. 1 2
      BFFramework/Classes/PQGPUImage/akfilters/PQSubTitleFilter.swift
  80. 1 0
      BFFramework/Classes/PQGPUImage/akfilters/Tools/NXAVAssetExportSession.swift
  81. 1 1
      BFFramework/Classes/PQGPUImage/akfilters/Tools/PQCompositionExporter.swift
  82. 80 28
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointEditerController.swift
  83. 26 20
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMaterialController.swift
  84. 0 384
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMaterialDetailController.swift
  85. 12 5
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicContentController.swift
  86. 6 6
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicController.swift
  87. 1 0
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicSearchController.swift
  88. 26 16
      BFFramework/Classes/Stuckpoint/Controller/PQStuckPointPublicController.swift
  89. 1 0
      BFFramework/Classes/Stuckpoint/Model/PQStuckPointMusicTagsModel.swift
  90. 1 0
      BFFramework/Classes/Stuckpoint/Model/PQVoiceModel.swift
  91. 1 0
      BFFramework/Classes/Stuckpoint/View/PQCustomSwitchView.swift
  92. 2 1
      BFFramework/Classes/Stuckpoint/View/PQCuttingPointView.swift
  93. 4 3
      BFFramework/Classes/Stuckpoint/View/PQEditPublicCoverImageView.swift
  94. 4 2
      BFFramework/Classes/Stuckpoint/View/PQEditPublicTitleView.swift
  95. 1 0
      BFFramework/Classes/Stuckpoint/View/PQStuckPointCuttingView.swift
  96. 3 2
      BFFramework/Classes/Stuckpoint/View/PQStuckPointLoadingView.swift
  97. 3 1
      BFFramework/Classes/Stuckpoint/View/PQStuckPointMaterialHeadView.swift
  98. 10 9
      BFFramework/Classes/Stuckpoint/View/PQStuckPointMusicContentCell.swift
  99. 1 0
      BFFramework/Classes/Stuckpoint/View/PQStuckPointMusicTagsContentCell.swift
  100. 2 1
      BFFramework/Classes/Stuckpoint/View/PQStuckPointSearchEmptyCell.swift

+ 10 - 14
BFFramework.podspec

@@ -8,7 +8,7 @@
 
 Pod::Spec.new do |s|
   s.name             = 'BFFramework'
-  s.version          = '0.1.1'
+  s.version          = '1.0.2'
   s.summary          = 'Byte fllow 基础组件库'
   s.swift_version    = '5.0'
 # This description is used to generate tags and improve search results.
@@ -34,6 +34,7 @@ TODO: Add long description of the pod here.
 
    s.resource_bundles = {
      'BFFramework' => ['BFFramework/Assets/**/*.png','BFFramework/Assets/**/*.gif','BFFramework/Assets/**/*.mp3','BFFramework/Assets/**/*.mp4']
+
    }
    s.static_framework = true
 
@@ -41,28 +42,23 @@ TODO: Add long description of the pod here.
                   'OTHER_SWIFT_FLAGS' => "$(inherited) -DGLES",
                    'VALIDATE_WORKSPACE_SKIPPED_SDK_FRAMEWORKS' => "OpenGLES"
                  }
-   s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-all_load', 'VALID_ARCHS' => 'arm64 armv7' }
+#   s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-all_load', 'VALID_ARCHS' => 'arm64 armv7' }
+   s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-all_load'}
    s.public_header_files = 'BFFramework/Classes/**/*.h'
    # s.private_header_files = 'BFFramework/Classes/SupportFiles/AliyunOSSiOSAK_umbrella.h'
    # s.preserve_paths = ['BFFramework/Classes/BFFrameworkPodHeader.h']
    s.frameworks = 'UIKit', 'AVFoundation','OpenGLES', 'CoreMedia', 'QuartzCore'
     # 排除非 ios 平台的文件
     # s.ios.exclude_files = 'framework/Source/Mac', 'framework/Source/Linux', 'framework/Source/Operations/Shaders/ConvertedShaders_GL.swift'
-
-    s.dependency 'Alamofire','4.9.1' # 网络请求库
-    s.dependency 'SnapKit','4.2.0' # 布局库
-    s.dependency 'Kingfisher','6.3.0' # 图片加载库
-    s.dependency 'KingfisherWebP','1.3.0' # 加载WebP格式图片库 使用https://github.com/webmproject/libwebp.git地址可以不翻
-    s.dependency 'RealmSwift','10.7.2' # Realm数据库
+    s.dependency 'BFCommonKit'
+    s.dependency 'BFNetRequestKit'
+    s.dependency 'BFMaterialKit'
     s.dependency 'ObjectMapper','4.2.0' # json转model库
-    s.dependency 'KeychainAccess','4.2.2' # 钥匙串库
-    s.dependency 'Toast-Swift','5.0.1' # Toast提示组件
-    s.dependency 'AliyunOSSiOS','2.10.8' # 阿里云组件
+    s.dependency 'AliyunOSSiOS','2.10.10' # 阿里云组件
     s.dependency 'WechatOpenSDK-Swift','1.8.7.1' # 微信组件
-    s.dependency 'MJRefresh','3.6.1' # 刷新组件
-    s.dependency 'FDFullscreenPopGesture' ,'1.1'
+    s.dependency 'MJRefresh','3.7.2' # 刷新组件
     s.dependency 'LMJHorizontalScrollText' ,'2.0.2'
-    s.dependency 'TXLiteAVSDK_Player','8.7.10102' # 腾讯播放器组件
+    s.dependency 'TXLiteAVSDK_Player','9.1.10564' # 腾讯播放器组件
     s.dependency 'Bugly','2.5.90' #crash log 收集
 
 end

+ 0 - 3
BFFramework/Classes/BFFramework_custom_umbrella.h

@@ -10,13 +10,10 @@
 #define AliyunOSSiOSAK_Bridging_Header
 
 #import "AliyunOSSiOS/AliyunOSSiOS.h"
-#import "PQBridgeObject.h"
 #import "MJRefresh/MJRefresh.h"
-#import "FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.h"
 #import "DES3Util.h"
 #import "LMJHorizontalScrollText/LMJHorizontalScrollText.h"
 #import "FBShimmeringView.h"
-#import "UIControl+NXCategory.h"
 #import <TXLiteAVSDK_Player/TXLiteAVSDK.h>
 #import <Bugly/Bugly.h>
 #import "MemoryCoculation.h"

+ 0 - 22
BFFramework/Classes/BFModules/BFCategorys/BFBundle+Ext.swift

@@ -1,22 +0,0 @@
-//
-//  Bundle+Ext.swift
-//  BFFramework
-//
-//  Created by ak on 2021/6/2.
-//  取 BFFramework 资源目录
-
-import Foundation
-
-extension Bundle {
-    
-    // bf main bundle url
-   public func BF_mainbundle_URL() -> URL {
-        let bundle:Bundle = Bundle.init(for: PQBaseViewController.self)
-        return bundle.url(forResource: "BFFramework", withExtension: "bundle")!
-    }
-    // bf main bundle
-    public func BF_mainbundle() -> Bundle {
-        return  Bundle.init(url: BF_mainbundle_URL())!
-    }
- 
-}

+ 0 - 109
BFFramework/Classes/BFModules/BFCategorys/BFInt+Ext.swift

@@ -1,109 +0,0 @@
-//
-//  Int+Ext.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/7/20.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import Foundation
-
-extension Int {
-    /// 分数字格式化如413200->4,132.09
-
-    /// 是否保留2位小数
-    /// - Parameter isDecimal: <#isDecimal description#>
-    /// - Returns: <#description#>
-   public func paraseDecimalFormatterValue(isDecimal: Bool = false) -> String? {
-        let decimal = self % 100
-        let nonDecimal = self / 100
-        let formatter = NumberFormatter()
-        formatter.numberStyle = .decimal
-        if let title = formatter.string(from: NSNumber(value: nonDecimal)) {
-            if isDecimal {
-                return title + String(format: ".%02d", decimal)
-            } else {
-                return title
-            }
-        }
-        return nil
-    }
-
-    /// 改变单位为万
-    /// @param originUnit <#originUnit description#>
-    public func changeUnit() -> String {
-        var unitStr: String = ""
-        if self < 10000 {
-            unitStr = "\(self)"
-        } else if self <= 1_000_000 {
-            let divisor = pow(10.0, Double(1))
-            let decimal = ((Double(self) / 10000) * divisor).rounded() / divisor
-            unitStr = "\(decimal)万"
-        } else {
-            unitStr = "\(self / 10000)万"
-        }
-        BFLog(message: "转化单位:\(self) = \(unitStr)")
-        return unitStr
-    }
-}
-
-// MARK: - Float64 double类型扩展
-
-/// Float64 double类型扩展
-
-extension Float64 {
-    /// 时长转化为分秒 62'52"
-    /// - Returns: <#description#>
-    public func formatDurationToMS() -> String {
-        let duration = lround(self)
-        var text = ""
-        let min = duration / 60
-        let second = duration % 60
-        if min > 0, second > 0 {
-            text = "\(min)" + "\'" + "\(second)" + "\""
-        } else if min > 0 {
-            text = "\(min)" + "\'" + "0\""
-        } else {
-            text = "\(second)" + "\""
-        }
-        return text
-    }
-
-    /// 时长转化成时分秒 01:02:52
-    /// - Parameter value: <#value description#>
-    /// - Returns: <#description#>
-    public  func formatDurationToHMS() -> String {
-        var theTime = lround(self)
-        var theTime1 = 0 // 分
-        var theTime2 = 0 // 小时
-        if theTime < 60 {
-            if theTime < 10 {
-                return "00:0\(theTime)"
-            }
-            return "00:\(theTime)"
-        }
-        theTime1 = theTime / 60
-        theTime = theTime % 60
-        if theTime1 > 60 {
-            theTime2 = theTime1 / 60
-            theTime1 = theTime1 % 60
-        }
-        var result = "\(theTime)"
-        if theTime < 10 {
-            result = "0" + result
-        }
-        if theTime1 > 0 {
-            result = "\(theTime1):" + result
-            if theTime1 < 10 {
-                result = "0" + result
-            }
-        }
-        if theTime2 > 0 {
-            result = "\(theTime2):" + result
-            if theTime2 < 10 {
-                result = "0" + result
-            }
-        }
-        return result
-    }
-}

+ 0 - 203
BFFramework/Classes/BFModules/BFCategorys/BFString+Ext.swift

@@ -1,203 +0,0 @@
-//
-//  String+Ext.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/7/22.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import Foundation
-import MobileCoreServices
-
-extension String {
-    /// md5加密
-   public var md5: String {
-        let str = cString(using: String.Encoding.utf8)
-        let strLen = CUnsignedInt(lengthOfBytes(using: String.Encoding.utf8))
-        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
-        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
-        CC_MD5(str!, strLen, result)
-        let hash = NSMutableString()
-        for i in 0..<digestLen {
-            hash.appendFormat("%02x", result[i])
-        }
-        result.deallocate()
-        return hash as String
-    }
-    
-    // 文件后缀名
-    public  var pathExtension: String {
-        return (self as NSString).pathExtension
-    }
-
-    public func ga_widthForComment(font: UIFont, height: CGFloat = 15) -> CGFloat {
-
-        let rect = NSString(string: self).boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: height), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
-        return ceil(rect.width)
-    }
-//
-//    public  func ga_heightForComment(fontSize: CGFloat, width: CGFloat) -> CGFloat {
-//        let font = UIFont.systemFont(ofSize: fontSize)
-//        let rect = NSString(string: self).boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
-//        return ceil(rect.height)
-//    }
-//
-//    public  func ga_heightForComment(fontSize: CGFloat, width: CGFloat, maxHeight: CGFloat) -> CGFloat {
-//        let font = UIFont.systemFont(ofSize: fontSize)
-//        let rect = NSString(string: self).boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
-//        return ceil(rect.height)>maxHeight ? maxHeight : ceil(rect.height)
-//    }
- 
-
-    public  func enumerateSearchText(searchText: String?, complate: (_ idx: Int, _ range: NSRange) -> Void) {
-        if searchText == nil || (searchText?.count ?? 0) <= 0 || !contains(searchText!) {
-            return
-        }
-        let len: Int = searchText!.count
-        var loc: Int = 0
-        let subStrings: [String] = NSString(string: self).components(separatedBy: searchText!)
-        for (idx, subText) in subStrings.enumerated() {
-            loc = loc + subText.count
-            let range = NSRange(location: loc, length: len)
-            complate(idx, range)
-            loc = loc + len
-            if idx == subStrings.count - 2 {
-                break
-            }
-        }
-    }
-
-    public  func attributedTextWithSearchText(searchText: String?, textColor: UIColor, textFont: UIFont, searchTextColor: UIColor, searchTextFont: UIFont) -> NSMutableAttributedString {
-        let attbText = NSMutableAttributedString(string: self, attributes: [NSAttributedString.Key.font: textFont, NSAttributedString.Key.foregroundColor: textColor])
-        if count <= 0 || searchText == nil || (searchText?.count ?? 0) <= 0 {
-            return attbText
-        }
-        for tempStr in searchText! {
-            BFLog(message: "self = \(self),searchText = \(searchText ?? ""),tempStr = \(tempStr)")
-            enumerateSearchText(searchText: "\(tempStr)") { _, range in
-                attbText.setAttributes([NSAttributedString.Key.font: searchTextFont, NSAttributedString.Key.foregroundColor: searchTextColor], range: range)
-            }
-        }
-        return attbText
-    }
-
-    // 判断是否为空
-    public  var isSpace: Bool {
-        return allSatisfy { $0.isWhitespace }
-    }
-
-    /// 通过 文件路径/文件名/文件后缀 获取mimeType(文件媒体类型)
-    /// - Parameter pathExtension: <#pathExtension description#>
-    /// - Returns: <#description#>
-    public func mimeType() -> String {
-        if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (self as NSString).pathExtension as CFString, nil)?.takeRetainedValue() {
-            if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?
-                .takeRetainedValue()
-            {
-                return mimetype as String
-            }
-        }
-        return "application/octet-stream"
-    }
-
-    // 将原始的url编码为合法的url
-    public  func urlEncoded() -> String {
-        let encodeUrlString = addingPercentEncoding(withAllowedCharacters:
-            .urlQueryAllowed)
-        return encodeUrlString ?? ""
-    }
-
-    // 将编码后的url转换回原始的url
-    public func urlDecoded() -> String {
-        return removingPercentEncoding ?? ""
-    }
-
-    // 判断是否包含Emoji表情
-    public func isEmoji() -> Bool {
-        let numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
-        guard !numbers.contains(self) else {
-            return false
-        }
-        let tempEmoji: [Unicode.Scalar] = ["\u{26F8}", "\u{26F7}", "\u{263A}", "\u{2639}", "\u{2620}", "\u{270C}", "\u{261D}", "\u{0001F441}", "\u{0001F5E3}", "\u{0001F575}", "\u{0001F574}", "\u{26D1}", "\u{0001F576}", "\u{0001F577}", "\u{0001F54A}", "\u{0001F43F}", "\u{2618}", "\u{0001F32A}", "\u{2600}", "\u{0001F324}", "\u{0001F325}", "\u{2601}", "\u{0001F326}", "\u{0001F327}", "\u{26C8}", "\u{0001F329}", "\u{0001F328}", "\u{2744}", "\u{2603}", "\u{0001F32C}", "\u{2602}", "\u{0001F32B}", "\u{0001F336}", "\u{0001F37D}"]
-        let scalars = unicodeScalars.map { $0.value }
-        for element in scalars {
-            if let scalar = Unicode.Scalar(element) {
-                if #available(iOS 10.2, *) {
-                    if (scalar.properties.isEmoji && scalar.properties.isEmojiPresentation) || tempEmoji.contains(scalar) {
-                        return true
-                    } else {
-                        BFLog(message: "是表情==\(element),\(scalar)")
-                    }
-                }
-            }
-        }
-        return false
-    }
-
-    var isContainsEmoji: Bool {
-        for scalar in unicodeScalars {
-            switch scalar.value {
-            case 0x1F600...0x1F64F, // Emoticons
-                 0x1F300...0x1F5FF, // Misc Symbols and Pictographs
-                 0x1F680...0x1F6FF, // Transport and Map
-                 0x2600...0x26FF, // Misc symbols
-                 0x2700...0x27BF, // Dingbats
-                 0xFE00...0xFE0F: // Variation Selectors
-                return true
-            default:
-                continue
-            }
-        }
-        return false
-    }
-
-    // 是否包含表情
-    var containsEmoji: Bool {
-        for scalar in unicodeScalars {
-            switch scalar.value {
-            case
-                0x00A0...0x00AF,
-                0x2030...0x204F,
-                0x2120...0x213F,
-                0x2190...0x21AF,
-                0x2310...0x329F,
-                0x1F000...0x1F9CF:
-                return true
-            default:
-                continue
-            }
-        }
-        return false
-    }
-
-    /**
-     * 字母、数字、中文正则判断(不包括空格)
-     *注意: 因为考虑到输入习惯,许多人习惯使用九宫格,这里在正常选择全键盘输入错误的时候,进行九宫格判断,九宫格对应的是下面➋➌➍➎➏➐➑➒的字符
-     */
-    static func isInputRuleNotBlank(str: String) -> Bool {
-        let pattern = "^[a-zA-Z\\u4E00-\\u9FA5\\d]*$"
-        let pred = NSPredicate(format: "SELF MATCHES %@", pattern)
-        let isMatch = pred.evaluate(with: str)
-        if !isMatch {
-            let other = "➋➌➍➎➏➐➑➒"
-            let len = str.count
-            for i in 0..<len {
-                let tmpStr = str as NSString
-                let tmpOther = other as NSString
-                let c = tmpStr.character(at: i)
-
-                if !(isalpha(Int32(c)) > 0 || isalnum(Int32(c)) > 0 || (Int(c) == "_".hashValue) || (Int(c) == "-".hashValue) || (c >= 0x4E00 && c <= 0x9FA6) || (tmpOther.range(of: str).location != NSNotFound)) {
-                    return false
-                }
-                return true
-            }
-        }
-        return isMatch
-    }
-}
-
-extension Optional where Wrapped == String {
-    public var isSpace: Bool {
-        return self?.isSpace ?? true
-    }
-}

+ 0 - 490
BFFramework/Classes/BFModules/BFCategorys/BFUIView+Ext.swift

@@ -1,490 +0,0 @@
-//
-//  UICollectionView+Ext.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/6/6.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import KingfisherWebP
-import UIKit
-
-// MARK: - UIView的分类扩展
-
-/// UIView的分类扩展
-extension UIView {
-      public func addCorner(roundingCorners: UIRectCorner = .allCorners, corner: CGFloat = cDefaultMargin) {
-        if roundingCorners == .allCorners {
-            layer.cornerRadius = corner
-            layer.masksToBounds = true
-        } else {
-            let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: roundingCorners, cornerRadii: CGSize(width: corner, height: corner))
-            let cornerLayer = CAShapeLayer()
-            cornerLayer.frame = bounds
-            cornerLayer.path = path.cgPath
-            layer.mask = cornerLayer
-        }
-    }
-
-    /// 添加阴影
-    /// - Parameters:
-    ///   - color: <#color description#>
-    ///   - offset: <#offset description#>
-    /// - Returns: <#description#>
-     public func addShadowLayer(isAll: Bool = false, color: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5), offset: CGSize = CGSize(width: 1, height: 1)) {
-        layer.shadowColor = color.cgColor
-        layer.shadowOffset = offset
-        layer.shadowRadius = 0.5
-        layer.shadowOpacity = 1.0
-        if isAll {
-            layer.shadowColor = color.cgColor
-            layer.shadowOffset = CGSize.zero
-            // 设置偏移量为0,四周都有阴影
-            layer.shadowRadius = 0.5 // 阴影半径
-            layer.shadowOpacity = 0.3 // 阴影透明度
-            layer.masksToBounds = false
-            layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath
-        }
-    }
-
-    /// 添加虚线条
-     public func addBorderToLayer(frame: CGRect? = nil) {
-        // 线条颜色
-        let borderLayer: CAShapeLayer = CAShapeLayer()
-        borderLayer.strokeColor = UIColor.hexColor(hexadecimal: "#FFFFFF").cgColor
-        borderLayer.fillColor = nil
-        borderLayer.path = UIBezierPath(rect: frame == nil ? bounds : frame!).cgPath
-        borderLayer.frame = bounds
-        borderLayer.lineWidth = 2.0
-        borderLayer.lineCap = .round
-        // 第一位是 线条长度   第二位是间距 nil时为实线
-        borderLayer.lineDashPattern = [5, 5]
-        layer.addSublayer(borderLayer)
-    }
-
-     public func animateZoom() {
-        transform = CGAffineTransform(scaleX: 0.4, y: 0.4)
-        UIView.animate(withDuration: 0.5, animations: {
-            self.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
-        }) { _ in
-            UIView.animate(withDuration: 0.5, animations: {
-                self.transform = .identity
-            }) { _ in
-            }
-        }
-    }
-
-    /// 添加抖动功能
-    /// - Parameters:
-    ///   - fromValue: <#fromValue description#>
-    ///   - toValue: <#toValue description#>
-    ///   - duration: <#duration description#>
-    ///   - repeatCount: <#repeatCount description#>
-    /// - Returns: <#description#>
-     public func shakeAnimation(_ fromValue: Float, _ toValue: Float, _ duration: Float, _: Float) {
-        layer.removeAllAnimations()
-        let shake = CABasicAnimation(keyPath: "transform.rotation.z")
-        shake.fromValue = fromValue
-        shake.toValue = toValue
-        shake.duration = CFTimeInterval(duration)
-        shake.autoreverses = true
-        shake.repeatCount = Float(CGFloat.greatestFiniteMagnitude)
-        shake.isRemovedOnCompletion = false
-        layer.add(shake, forKey: "imageView")
-        // 增加锚点
-        layer.anchorPoint = CGPoint(x: 0.5, y: 1)
-    }
-
-    /// 添加心跳动画
-    /// - Parameters:
-    ///   - duration: <#duration description#>
-    ///   - isRepeat: <#isRepeat description#>
-    ///   - multiple: <#multiple description#>
-    /// - Returns: <#description#>
-     public func heartbeatAnimate(duration: TimeInterval, isRepeat: Bool, multiple: CGFloat) {
-        UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
-            self.transform = CGAffineTransform(scaleX: 1.0 + multiple, y: 1.0 + multiple)
-        }) { _ in
-            UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
-                self.transform = .identity
-            }) { _ in
-                UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
-                    self.transform = CGAffineTransform(scaleX: 1.0 + multiple * 2, y: 1.0 + multiple * 2)
-                }) { _ in
-                    UIView.animateKeyframes(withDuration: duration, delay: 0, options: .allowUserInteraction, animations: {
-                        self.transform = .identity
-                    }) { _ in
-                        if isRepeat {
-                            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.3) {
-                                self.heartbeatAnimate(duration: duration, isRepeat: isRepeat, multiple: multiple)
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /// 活动心跳动画
-    /// - Returns: <#description#>
-     public func activityHeartbeatAnimate() {
-        layer.removeAllAnimations()
-        UIView.animateKeyframes(withDuration: 0.45, delay: 0, options: .allowUserInteraction, animations: {
-            self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
-        }) { _ in
-            UIView.animateKeyframes(withDuration: 0.45, delay: 0, options: .allowUserInteraction, animations: {
-                self.transform = .identity
-            }) { _ in
-                self.activityHeartbeatAnimate()
-            }
-        }
-    }
-
-    /// 活动心跳动画
-    /// - Returns: <#description#>
-     public func heartbeatAnimate() {
-        layer.removeAllAnimations()
-        UIView.animateKeyframes(withDuration: 1, delay: 0, options: .allowUserInteraction, animations: {
-            self.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
-        }) { isFinished in
-            UIView.animateKeyframes(withDuration: 1, delay: 0, options: .allowUserInteraction, animations: {
-                self.transform = .identity
-            }) { isFinished in
-                if isFinished {
-                    self.heartbeatAnimate()
-                }
-            }
-        }
-    }
-
-     public func addScaleBasicAnimation() {
-        let animation = CABasicAnimation(keyPath: "transform.scale")
-        animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
-        animation.duration = 0.5
-        animation.repeatCount = 1000
-        animation.autoreverses = true
-        animation.fromValue = 0.8
-        animation.toValue = 1.1
-        layer.add(animation, forKey: nil)
-    }
-
-     public func addScaleYBasicAnimation() {
-        let animation = CAKeyframeAnimation(keyPath: "transform.translation.y")
-        animation.duration = 0.5
-        animation.repeatCount = 100
-        animation.isRemovedOnCompletion = true
-        //        animation.
-        animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
-        layer.add(animation, forKey: nil)
-        //            CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
-        //            CGFloat duration = 1.f;
-        //            CGFloat height = 7.f;
-        //            CGFloat currentY = self.animationView.transform.ty;
-        //            animation.duration = duration;
-        //            animation.values = @[@(currentY),@(currentY - height/4),@(currentY - height/4*2),@(currentY - height/4*3),@(currentY - height),@(currentY - height/ 4*3),@(currentY - height/4*2),@(currentY - height/4),@(currentY)];
-        //            animation.keyTimes = @[ @(0), @(0.025), @(0.085), @(0.2), @(0.5), @(0.8), @(0.915), @(0.975), @(1) ];
-        //            animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
-        //            animation.repeatCount = HUGE_VALF;
-        //            [self.animationView.layer addAnimation:animation forKey:@"kViewShakerAnimationKey"];
-        //        }
-    }
-
-    /// 将view生成一张图片
-    /// - Returns: <#description#>
-     public func graphicsGetImage() -> UIImage? {
-        UIGraphicsBeginImageContextWithOptions(frame.size, true, 0.0)
-        layer.render(in: UIGraphicsGetCurrentContext()!)
-        let newImage = UIGraphicsGetImageFromCurrentImageContext()
-        UIGraphicsEndImageContext()
-        return newImage
-    }
-
-    /// 动画显示View
-    /// - Returns: <#description#>
-     public func showViewAnimate(duration: TimeInterval = 0.3, completion: ((Bool) -> Void)? = nil) {
-        UIView.animate(withDuration: duration, animations: { [weak self] in
-            self?.frame = CGRect(x: 0, y: cScreenHeigth - self!.frame.height, width: self!.frame.width, height: self!.frame.height)
-        }) { isFinished in
-            if completion != nil {
-                completion!(isFinished)
-            }
-        }
-    }
-
-    /// 动画隐藏view
-    /// - Returns: <#description#>
-     public func dismissViewAnimate(duration: TimeInterval = 0.3, completion: ((Bool) -> Void)? = nil) {
-        UIView.animate(withDuration: duration, animations: { [weak self] in
-            self?.frame = CGRect(x: 0, y: cScreenHeigth, width: self!.frame.width, height: self!.frame.height)
-        }) { isFinished in
-            if completion != nil {
-                completion!(isFinished)
-            }
-        }
-    }
-
-    /// add  by ak 添加虚线框
-    /// - Parameter color: 框色
-    /// - Parameter lineWidth: 框宽
-     public func addBorderToLayer(color: CGColor, lineWidth: CGFloat) {
-        let border = CAShapeLayer()
-
-        //  线条颜色
-        border.strokeColor = color
-        border.fillColor = nil
-
-        border.path = UIBezierPath(rect: bounds).cgPath
-
-        border.frame = bounds
-        border.lineWidth = lineWidth
-        border.lineCap = .square
-
-        //  第一位是 线条长度   第二位是间距 nil时为实线
-        border.lineDashPattern = [9, 4]
-        layer.addSublayer(border)
-    }
-}
-
-// MARK: - UICollectionView的分类扩展
-
-/// UICollectionView的分类扩展
-extension UICollectionView {
-    /// 获取当前cell
-    /// - Returns: <#description#>
-     public func visibleCell() -> UICollectionViewCell? {
-        let visibleRect = CGRect(origin: contentOffset, size: bounds.size)
-        let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
-        guard let visibleIndexPath = indexPathForItem(at: visiblePoint) else { return nil }
-        return cellForItem(at: visibleIndexPath)
-    }
-
-    /// 添加刷新组件
-    /// - Parameters:
-    ///   - scroller: <#scroller description#>
-    ///   - type: 1-头部跟尾部 2-头部 3-尾部
-     public func addRefreshView(type: REFRESH_TYPE = .REFRESH_TYPE_ALL, refreshHandle: ((_ isHeader: Bool) -> Void)?) {
-        if type == .REFRESH_TYPE_ALL || type == .REFRESH_TYPE_HEADER {
-            let header = MJRefreshNormalHeader.init {
-                if refreshHandle != nil {
-                    refreshHandle!(true)
-                }
-            }
-            header.setTitle("下拉刷新", for: .willRefresh)
-            header.setTitle("正在刷新...", for: .refreshing)
-            header.setTitle("松开刷新", for: .pulling)
-            header.setTitle("下拉刷新", for: .idle)
-            header.lastUpdatedTimeLabel?.isHidden = true
-            mj_header = header
-        }
-        if type == .REFRESH_TYPE_ALL || type == .REFRESH_TYPE_FOOTER {
-            // MJRefreshBackNormalFooter 不会附在上面
-            // MJRefreshAutoFooter 不会便宜
-            let footer = MJRefreshBackNormalFooter.init {
-                if refreshHandle != nil {
-                    refreshHandle!(false)
-                }
-            }
-            footer.setTitle("暂时没有更多了", for: .noMoreData)
-            footer.setTitle("精彩内容正在加载中...", for: .refreshing)
-            mj_footer = footer
-        }
-    }
-
-     public func indexPathsForElements(in rect: CGRect) -> [IndexPath] {
-        let allLayoutAttributes = collectionViewLayout.layoutAttributesForElements(in: rect)!
-        return allLayoutAttributes.map { $0.indexPath }
-    }
-}
-
-// MARK: - UITabBar的分类扩展
-
-/// UITabBar的分类扩展
-extension UITabBar {
-    /// 展示小红点
-    /// - Parameter index: <#index description#>
-    /// - Returns: <#description#>
-     public func showPoint(index: Int) {
-        let pointW: CGFloat = 8
-        let pointView = UIView()
-        pointView.tag = 11111 + index
-        pointView.layer.cornerRadius = pointW / 2
-        pointView.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
-        let percentX: CGFloat = CGFloat(Double(index) + 0.7) / CGFloat(items?.count ?? 1)
-        let pointX = ceil(percentX * frame.width)
-        let pointY = ceil(0.1 * frame.height)
-        pointView.frame = CGRect(x: pointX, y: pointY, width: pointW, height: pointW)
-        addSubview(pointView)
-    }
-
-    /// 移除小红点
-    /// - Parameter index: <#index description#>
-    /// - Returns: <#description#>
-     public func removePoint(index: Int) {
-        for item in subviews {
-            if item.tag == 11111 + index {
-                item.removeFromSuperview()
-            }
-        }
-    }
-
-    /// 展示创作视频引导
-    /// - Parameter index: <#index description#>
-    /// - Returns: <#description#>
-     public func showVideoMakeRemindView() {
-        let isOldUploadClick: String? = getUserDefaults(key: cIsUploadClick) as? String
-        let isUploadClick: String? = getUserDefaultsForJson(key: cIsUploadClick) as? String
-        let isVerticalSlip: String? = getUserDefaults(key: cIsVerticalSlip) as? String
-        if isOldUploadClick == nil && isVerticalSlip != nil && isVerticalSlip == "1", isUploadClick == nil || isUploadClick?.count ?? 0 <= 0 || isUploadClick != "2" {
-            let width: CGFloat = 275 // 275
-            let height: CGFloat = 107 // 107
-            let videoMakeRemindBtn = UIButton(frame: CGRect(x: 0, y: -height + 5, width: width, height: height))
-            videoMakeRemindBtn.tag = cVideoMakeRemindTag
-            videoMakeRemindBtn.setBackgroundImage(UIImage(named: "videomk_guide"), for: .normal)
-            addSubview(videoMakeRemindBtn)
-            videoMakeRemindBtn.center.x = center.x
-            videoMakeRemindBtn.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
-            videoMakeRemindBtn.addScaleBasicAnimation()
-            if isUploadClick == "1" {
-                saveUserDefaultsToJson(key: cIsUploadClick, value: "2")
-            } else {
-                saveUserDefaultsToJson(key: cIsUploadClick, value: "1")
-            }
-            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) { [weak self] in
-                self?.removeVideoMakeRemindView()
-            }
-        }
-    }
-
-    @objc  public func dismiss() {
-  
-    }
-
-    /// 移除创作视频引导
-    /// - Returns: <#description#>
-     public func removeVideoMakeRemindView() {
-        viewWithTag(cVideoMakeRemindTag)?.removeFromSuperview()
-    }
-}
-
-// MARK: - UILabel的分类扩展
-
-/// UILabel的分类扩展
-extension UILabel {
-    var isTruncated: Bool {
-        guard let labelText = text else {
-            return false
-        }
-
-        // 计算理论上显示所有文字需要的尺寸
-        let rect = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude)
-        let labelTextSize = (labelText as NSString)
-            .boundingRect(with: rect, options: .usesLineFragmentOrigin,
-                          attributes: [NSAttributedString.Key.font: font as Any], context: nil)
-
-        // 计算理论上需要的行数
-        let labelTextLines = Int(ceil(CGFloat(labelTextSize.height) / font.lineHeight))
-
-        // 实际可显示的行数
-        var labelShowLines = Int(floor(CGFloat(bounds.size.height) / font.lineHeight))
-        if numberOfLines != 0 {
-            labelShowLines = min(labelShowLines, numberOfLines)
-        }
-
-        // 比较两个行数来判断是否需要截断
-        return labelTextLines > labelShowLines
-    }
-
-    /// 添加阴影
-    /// - Parameters:
-    ///   - color: <#color description#>
-    ///   - offset: <#offset description#>
-    /// - Returns: <#description#>
-     public func addShadow(color: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5), offset: CGSize = CGSize(width: 1, height: 1)) {
-        shadowColor = color
-        shadowOffset = offset
-    }
-}
-
-extension UIImageView {
-    /// imageView加载网络图片
-    /// - Parameters:
-    ///   - url: 网络url
-     public func setNetImage(url: String?, placeholder: UIImage = UIImage.init().BF_Image(named: "placehold_image")) {
-        if url == nil || (url?.count ?? 0) <= 0 {
-            BFLog(message: "设置按钮网络图片地址为空")
-            return
-        }
-        kf.setImage(with: URL(string: url!), placeholder: placeholder, options: url?.suffix(5) == ".webp" ? [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)] : nil, progressBlock: { _, _ in
-
-        }) {  _ in
-        }
-    }
-
-    /// 展示加载中动画
-    /// - Returns: <#description#>
-     public func showLoadingAnimation(duration: Double = 1) {
-        let rotationAnim = CABasicAnimation(keyPath: "transform.rotation.z")
-        rotationAnim.fromValue = 0
-        rotationAnim.toValue = Double.pi * 2
-        rotationAnim.repeatCount = MAXFLOAT
-        rotationAnim.duration = duration
-        rotationAnim.isRemovedOnCompletion = false
-        layer.add(rotationAnim, forKey: nil)
-    }
-
-    /// 播放GIF
-    /// - Parameters:
-    ///   - data : 图片二进制数据
-    ///   - images: 图片
-    ///   - repeatCount: 循环次数
-    ///   - duration: 时长
-    /// - Returns: <#description#>
-     public func displayGIF(data: Data? = nil, images: [UIImage]? = nil, repeatCount: Int = Int.max, duration: Double = 1) {
-        if images != nil, (images?.count ?? 0) > 0, !isAnimating {
-            layer.removeAllAnimations()
-            stopAnimating()
-            animationImages = images
-            animationDuration = duration
-            animationRepeatCount = repeatCount
-            startAnimating()
-        } else if images == nil && data != nil {
-            PQPHAssetVideoParaseUtil.parasGIFImage(data: data!) { [weak self] _, images, duration in
-                if images != nil, (images?.count ?? 0) > 0 {
-                    self?.displayGIF(images: images!, repeatCount: repeatCount, duration: duration ?? 1)
-                }
-            }
-        }
-    }
-    
-    /// 移除
-    public func removePlayGIF() {
-        layer.removeAllAnimations()
-        stopAnimating()
-    }
-}
-
-extension UIButton {
-    /// UIButton加载网络图片
-    /// - Parameters:
-    ///   - url: 网络url
-     public func setNetImage(url: String?, placeholder: UIImage = UIImage.init().BF_Image(named: "placehold_image")) {
-        if url == nil || (url?.count ?? 0) <= 0 {
-            BFLog(message: "设置按钮网络图片地址为空")
-            return
-        }
-        kf.setImage(with: URL(string: url!), for: .normal, placeholder: placeholder, options: url?.suffix(5) == ".webp" ? [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)] : nil, progressBlock: { _, _ in
-
-        }) { _ in
-        }
-    }
-
-    /// UIButton加载网络背景图片
-    /// - Parameters:
-    ///   - url: 网络url
-     public func setNetBackgroundImage(url: String, placeholder: UIImage = UIImage.init().BF_Image(named: "placehold_image")) {
-        kf.setBackgroundImage(with: URL(string: url), for: .normal, placeholder: placeholder, options: url.suffix(5) == ".webp" ? [.processor(WebPProcessor.default), .cacheSerializer(WebPSerializer.default)] : nil, progressBlock: { _, _ in
-
-        }) { _ in
-        }
-    }
-}

+ 0 - 176
BFFramework/Classes/BFModules/BFCategorys/NXFundation+Ext.swift

@@ -1,176 +0,0 @@
-//
-//  NXFundation+Ext.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import Foundation
-import UIKit
-
-
-public extension Date {
-    var millisecondsSince1970:Int {
-        return Int((self.timeIntervalSince1970 * 1000.0).rounded())
-    }
-    
-    var secondsSince1970:Int {
-        return Int((self.timeIntervalSince1970).rounded())
-    }
-    
-    init(milliseconds:Int) {
-        self = Date(timeIntervalSince1970: TimeInterval(milliseconds / 1000))
-    }
-    
-    func getCurrentTimeString(_ format: String = "yyyy-MM-dd HH:mm:ss") -> String {
-        let nowDate = Date()
-        let formatter = DateFormatter()
-        formatter.dateFormat = format
-        formatter.locale = Locale(identifier: "en_US_POSIX")
-        formatter.timeZone = Foundation.TimeZone(identifier: "UTC")
-        //formatter.dateStyle = .MediumStyle
-        //formatter.timeStyle = .MediumStyle
-        return formatter.string(from: nowDate)
-    }
-    
-    var iso8601: String {
-        return Formatter.iso8601.string(from: self)
-    }
-}
-
-
-public extension Formatter {
-    static let iso8601: DateFormatter = {
-        let formatter = DateFormatter()
-        formatter.calendar = Calendar(identifier: .chinese)
-        formatter.locale = Locale(identifier: "Asia/Shanghai")
-        formatter.timeZone = TimeZone(secondsFromGMT: 0)
-        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
-        return formatter
-    }()
-}
-
-public extension String {
-    var dateFromISO8601: Date? {
-        return Formatter.iso8601.date(from: self)
-    }
-    
-    func appendLineToURL(fileURL: URL) throws {
-        try (self + "\n").appendToURL(fileURL: fileURL)
-    }
-    
-    func appendToURL(fileURL: URL) throws {
-        let data = self.data(using: String.Encoding.utf8)!
-        try data.append2File(fileURL: fileURL)
-    }
-
-    ///
-    func substring(to index: Int) -> String {
-        guard let end_Index = validEndIndex(original: index) else {
-            return self
-        }
-        return String(self[startIndex..<end_Index])
-    }
-    ///
-    func substring(from index: Int) -> String {
-        guard let start_index = validStartIndex(original: index)  else {
-            return self
-        }
-        return String(self[start_index..<endIndex])
-    }
-    ///
-    func sliceString(_ range: CountableRange<Int>) -> String {
-        guard
-            let startIndex = validStartIndex(original: range.lowerBound),
-            let endIndex   = validEndIndex(original: range.upperBound),
-            startIndex <= endIndex
-            else {
-                return ""
-        }
-        return String(self[startIndex..<endIndex])
-    }
-    ///
-    func sliceString(_ range: CountableClosedRange<Int>) -> String {
-        guard
-            let start_Index = validStartIndex(original: range.lowerBound),
-            let end_Index   = validEndIndex(original: range.upperBound),
-            startIndex <= endIndex
-            else {
-                return ""
-        }
-        if endIndex.encodedOffset <= end_Index.encodedOffset {
-            return String(self[start_Index..<endIndex])
-        }
-        return String(self[start_Index...end_Index])
-    }
-    
-    private func validIndex(original: Int) -> String.Index {
-        switch original {
-        case ...startIndex.encodedOffset : return startIndex
-        case endIndex.encodedOffset...   : return endIndex
-        default                          : return index(startIndex, offsetBy: original)
-        }
-    }
-    
-    private func validStartIndex(original: Int) -> String.Index? {
-        guard original <= endIndex.encodedOffset else { return nil }
-        return validIndex(original: original)
-    }
-    
-    private func validEndIndex(original: Int) -> String.Index? {
-        guard original >= startIndex.encodedOffset else { return nil }
-        return validIndex(original: original)
-    }
-    
-    ///
-    func toDate(formatter: String) -> Date {
-        let dateFormatter = DateFormatter()
-        dateFormatter.locale = Locale.current
-        dateFormatter.dateFormat = formatter
-        let date = dateFormatter.date(from: self)
-        return date!
-    }
-    
-}
-
-extension Data {
-    func append2File(fileURL: URL) throws {
-        if let fileHandle = FileHandle(forWritingAtPath: fileURL.path) {
-            defer {
-                fileHandle.closeFile()
-            }
-            fileHandle.seekToEndOfFile()
-            fileHandle.write(self)
-        }
-        else {
-            try write(to: fileURL, options: .atomic)
-        }
-    }
-}
-
-public extension UInt32 {
-    
-    var double: Double {
-        return Double(self)
-    }
-    
-}
-
-public extension UIApplication {
-    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
-        if let navigationController = controller as? UINavigationController {
-            return topViewController(controller: navigationController.visibleViewController)
-        }
-        if let tabController = controller as? UITabBarController {
-            if let selected = tabController.selectedViewController {
-                return topViewController(controller: selected)
-            }
-        }
-        if let presented = controller?.presentedViewController {
-            return topViewController(controller: presented)
-        }
-        return controller
-    }
-}
-

+ 0 - 392
BFFramework/Classes/BFModules/BFCategorys/NXUI+Ext.swift

@@ -1,392 +0,0 @@
-//
-//  NXUI+Ext.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import UIKit
-
-public extension UIViewController {
-    func showAlert(withTitle title: String?, message: String?) {
-        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
-        let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
-        alert.addAction(action)
-        
-        present(alert, animated: true, completion: nil)
-    }
-    
-    var contentViewController: UIViewController {
-        if let navcon = self as? UINavigationController {
-            return navcon.visibleViewController ?? self
-        } else {
-            return self
-        }
-    }
-}
-
-// Shake oritention
-public enum ShakeDirection: Int {
-    case horizontal
-    case vertical
-}
-
-public extension UIView {
-    func shake(direction: ShakeDirection = .horizontal, times: Int = 5,
-                      interval: TimeInterval = 0.1, delta: CGFloat = 2,
-                      completion: (() -> Void)? = nil) {
-        UIView.animate(withDuration: interval, animations: { () -> Void in
-            switch direction {
-            case .horizontal:
-                self.layer.setAffineTransform( CGAffineTransform(translationX: delta, y: 0))
-                break
-            case .vertical:
-                self.layer.setAffineTransform( CGAffineTransform(translationX: 0, y: delta))
-                break
-            }
-        }) { (complete) -> Void in
-            if (times == 0) {
-                // last shaking finish, reset location, callback
-                UIView.animate(withDuration: interval, animations: { () -> Void in
-                    self.layer.setAffineTransform(CGAffineTransform.identity)
-                }, completion: { (complete) -> Void in
-                    completion?()
-                })
-            }
-            else {
-                // not last shaking, continue
-                self.shake(direction: direction, times: times - 1,  interval: interval,
-                           delta: delta * -1, completion:completion)
-            }
-        }
-    }
-}
-
-
-extension UIView {
-    var x: CGFloat {
-        set {
-            var frame = self.frame
-            frame.origin.x = newValue
-            self.frame = frame
-        }
-        get {
-            return self.frame.origin.x
-        }
-    }
-    
-    var y: CGFloat {
-        set {
-            var frame = self.frame
-            frame.origin.y = newValue
-            self.frame = frame
-        }
-        get {
-            return self.frame.origin.y
-        }
-    }
-    
-    var centerX: CGFloat {
-        set {
-            var center = self.center
-            center.x = newValue
-            self.center = center
-        }
-        get {
-            return self.center.x
-        }
-    }
-    
-    var centerY: CGFloat {
-        set {
-            var center = self.center
-            center.y = newValue
-            self.center = center
-        }
-        get {
-            return self.center.y
-        }
-    }
-    
-    var width: CGFloat {
-        set {
-            var frame = self.frame
-            frame.size.width = newValue
-            self.frame = frame
-        }
-        get {
-            return self.frame.size.width
-        }
-    }
-    
-    var height: CGFloat {
-        set {
-            var frame = self.frame
-            frame.size.height = newValue
-            self.frame = frame
-        }
-        get {
-            return self.frame.size.height
-        }
-    }
-    
-    var size: CGSize {
-        set {
-            var frame = self.frame
-            frame.size = newValue
-            self.frame = frame
-        }
-        get {
-            return self.frame.size
-        }
-    }
-    
-    var origin: CGPoint {
-        set {
-            var frame = self.frame
-            frame.origin = newValue
-            self.frame = frame
-        }
-        get {
-            return self.frame.origin
-        }
-    }
-    
-    var bottomY: CGFloat {
-        set {
-            var frame = self.frame
-            frame.origin.y = newValue - frame.size.height
-            self.frame = frame
-        }
-        get {
-            return self.height + self.y
-        }
-    }
-    
-    var rightX: CGFloat {
-        set {
-            var frame = self.frame
-            frame.origin.x = newValue - frame.size.width
-            self.frame = frame
-        }
-        get {
-            return self.width + self.x
-        }
-    }
-    
-    // MARK: - UIView round corner
-    ///
-    /// - Parameter cornerRadius: radius
-    func roundedCorners(cornerRadius: CGFloat) {
-        roundedCorners(cornerRadius: cornerRadius, borderWidth: 0, borderColor: nil)
-    }
-    
-    ///
-    /// - Parameters:
-    ///   - cornerRadius:
-    ///   - borderWidth:
-    ///   - borderColor:
-    func roundedCorners(cornerRadius: CGFloat?, borderWidth: CGFloat?, borderColor: UIColor?) {
-        self.layer.cornerRadius = cornerRadius!
-        self.layer.borderWidth = borderWidth!
-        self.layer.borderColor = borderColor?.cgColor
-        self.layer.masksToBounds = true
-    }
-    
-    ///
-    /// - Parameters:
-    ///   - cornerRadius:
-    ///   - rectCorner:
-    func roundedCorners(cornerRadius: CGFloat?, rectCorner: UIRectCorner?) {
-        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: rectCorner!, cornerRadii: CGSize(width: cornerRadius!, height: cornerRadius!))
-        let layer = CAShapeLayer()
-        layer.frame = self.bounds
-        layer.path = path.cgPath
-        self.layer.mask = layer
-    }
-    
-    ///
-    /// - Parameters:
-    ///   - colors:
-    ///   - locations:
-    ///   - startPoint: [0...1]
-    ///   - endPoint: [0...1]
-    func gradientColor(colors: [CGColor], locations: [NSNumber], startPoint: CGPoint, endPoint: CGPoint) {
-        let gradientLayer = CAGradientLayer()
-        gradientLayer.colors = colors
-        gradientLayer.locations = locations
-        /*
-         // vertical
-         gradientLayer.startPoint = CGPoint(x: 0, y: 0)
-         gradientLayer.endPoint = CGPoint(x: 0, y: 1)
-         */
-        gradientLayer.startPoint = startPoint
-        gradientLayer.endPoint = endPoint
-        gradientLayer.frame = self.frame
-        self.layer.insertSublayer(gradientLayer, at: 0)
-    }
-    
-    // MARK: - UIView blur
-    ///
-    /// - Parameter style: UIBlurEffectStyle
-    func addBlurEffect(style: UIBlurEffect.Style) {
-        let effect = UIBlurEffect(style: UIBlurEffect.Style.light)
-        let effectView = UIVisualEffectView(effect: effect)
-        effectView.frame = self.bounds
-        self.backgroundColor = .clear
-        self.addSubview(effectView)
-        self.sendSubviewToBack(effectView)
-    }
-}
-public extension UIView {
-    
-    /// 往当前视图添加一个子视图
-    /// - Parameters:
-    ///   - rect: 子视图大小
-    ///   - bgColor: 子视图背景色
-    /// - Returns: 子视图
-    func nx_addView(rect:CGRect = .zero,bgColor:UIColor = .white) ->UIView{
-        let view = UIView(frame: rect)
-        view.backgroundColor = bgColor
-        self.addSubview(view)
-        return view
-    }
-    
-    /// 往当前视图添加UIImageView
-    /// - Parameters:
-    ///   - image: 图片对象
-    ///   - rect: UIImageView
-    ///   - contentMode: 图片填充模式
-    /// - Returns: 图片
-     func nx_addImageView(image:UIImage?,rect:CGRect = .zero, contentMode:ContentMode = .scaleAspectFit)->UIImageView{
-        let imageView = UIImageView(frame: rect);
-        imageView.image = image
-        imageView.contentMode = contentMode
-        self.addSubview(imageView)
-        return imageView
-    }
-    
-    /// 添加文本控件
-    /// - Parameters:
-    ///   - fontSize: 文本大小
-    ///   - text: 文本
-    ///   - textColor: 文本颜色
-    ///   - bgColor: 背景颜色
-    /// - Returns: 文本控件
-    func nx_addLabel(fontSize: CGFloat, text: String, textColor: UIColor, bgColor: UIColor) -> UILabel {
-        return nx_addLabel(font: UIFont.systemFont(ofSize: fontSize),
-                        text: text,
-                        textColor: textColor,
-                        bgColor: bgColor)
-    }
-    
-    /// 添加文本控件
-    /// - Parameters:
-    ///   - font: 文本大小
-    ///   - text: 文本
-    ///   - textColor: 文本颜色
-    ///   - bgColor: 背景颜色
-    /// - Returns: 文本控件
-    func nx_addLabel(font: UIFont, text: String, textColor: UIColor, bgColor: UIColor) -> UILabel {
-        let label = UILabel(frame: .zero)
-        label.font = font
-        label.text = text
-        label.textColor = textColor
-        label.backgroundColor = bgColor
-        self.addSubview(label)
-        return label
-    }
-    
-    /// 添加按钮控件
-    /// - Parameters:
-    ///   - rect: 控件大小
-    ///   - title: 标题
-    ///   - titleColor: 标题颜色
-    ///   - font: 字体
-    ///   - image: 图片
-    ///   - bgImg: 背景图片
-    ///   - target: 事件响应者
-    ///   - action: 事件响应方法
-    ///   - event: 响应事件
-    /// - Returns: 按钮
-    func nx_addButton(rect: CGRect, title: String, titleColor: UIColor, font: UIFont, image: UIImage?, bgImg: UIImage?, target: Any?, action: Selector?, event: UIControl.Event?) -> UIButton {
-            let btn = UIButton(type: .custom)
-            btn.frame = rect
-            btn.setTitle(title, for: .normal)
-            btn.setTitle(title, for: .highlighted)
-            btn.setTitleColor(titleColor, for: .normal)
-            btn.setTitleColor(titleColor, for: .highlighted)
-            btn.setImage(image, for: .normal)
-            btn.setImage(image, for: .highlighted)
-            btn.setBackgroundImage(bgImg, for: .normal)
-            btn.setBackgroundImage(bgImg, for: .highlighted)
-            btn.titleLabel?.font = font
-            if let sel = action, let e = event {
-                btn.addTarget(target, action: sel, for: e)
-            }
-            addSubview(btn)
-            return btn
-        }
-    
-    /// 添加一个文本类型的按钮控件
-    /// - Parameters:
-    ///   - rect: 按钮大小
-    ///   - title: 文本
-    ///   - titleColor: 文本颜色
-    ///   - target: 事件响应者
-    ///   - action: 事件响应方法
-    ///   - event:响应事件
-    /// - Returns: 按钮控件
-        func nx_addButton(rect: CGRect, title: String, titleColor: UIColor, target: Any?, action: Selector?, event: UIControl.Event?) -> UIButton {
-            return nx_addButton(rect: rect,
-                             title: title,
-                             titleColor: titleColor,
-                             font: UIFont.systemFont(ofSize: 14),
-                             image: nil,
-                             bgImg: nil,
-                             target: target,
-                             action: action,
-                             event: event)
-        }
-    
-    /// 添加图片类型按钮
-    /// - Parameters:
-    ///   - rect: 按钮大小
-    ///   - image: 图片
-    ///   - target: 事件响应者
-    ///   - action: 事件响应方法
-    ///   - event: 响应事件
-    /// - Returns: 按钮控件
-        func nx_addButton(rect: CGRect, image: UIImage, target: Any?, action: Selector?, event: UIControl.Event?) -> UIButton {
-            return nx_addButton(rect: rect,
-                             title: "",
-                             titleColor: .white,
-                             font: UIFont.systemFont(ofSize: 14),
-                             image: image,
-                             bgImg: nil,
-                             target: target,
-                             action: action,
-                             event: event)
-        }
-    
-    /// 添加tableView
-    /// - Parameters:
-    ///   - rect: 大小
-    ///   - delegate: delegate对象
-    ///   - dataSource: dataSource 对象
-    /// - Returns: 表视图
-    func nx_addTableView(rect: CGRect, delegate: UITableViewDelegate?,dataSource:UITableViewDataSource?) -> UITableView {
-          let tableView = UITableView(frame: rect)
-          tableView.delegate = delegate
-          tableView.dataSource = dataSource
-          backgroundColor = .white
-          tableView.tableFooterView = UIView()
-          if #available(iOS 11.0, *) {
-              tableView.contentInsetAdjustmentBehavior = .never
-          }
-          return tableView
-      }
-
-}
- 

+ 0 - 77
BFFramework/Classes/BFModules/BFCategorys/NXUIColor+Ext.swift

@@ -1,77 +0,0 @@
-//
-//  NXUIColor+Ext.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import UIKit
-
-extension UIColor {
-    
-    // MARK: - hex (0x000000) -> UIColor
-    ///
-    /// - Parameter hex (0x000000)
-    /// - Returns: UIColor
-    class func hex(hex: Int) -> UIColor {
-        return UIColor.hex(hex: hex, alpha: 1.0)
-    }
-    ///
-    /// - Parameters:
-    /// - Returns: UIColor
-    class func hex(hex: Int, alpha: CGFloat) -> UIColor {
-        return UIColor(red: CGFloat((hex >> 16) & 0xFF)/255.0, green: CGFloat((hex >> 8) & 0xFF)/255.0, blue: CGFloat(hex & 0xFF)/255.0, alpha: alpha)
-    }
- 
-    private class func colorComponent(hex: String, start: Int, length: Int) -> CGFloat {
-        let subString = hex.sliceString(start..<(start + length))
-        let fullHex = length == 2 ? subString : (subString + subString)
-        var val: CUnsignedInt = 0
-        Scanner(string: fullHex).scanHexInt32(&val)
-        return CGFloat(val) / 255.0
-    }
-    
-    var hex: String {
-        var color = self
-        if color.cgColor.numberOfComponents < 4 {
-            let components = color.cgColor.components
-            
-            color = UIColor(red: components![0], green: components![0], blue: components![0], alpha: components![1])
-        }
-        if color.cgColor.colorSpace?.model != CGColorSpaceModel.rgb {
-            return "#FFFFFF"
-        }
-        return String(format: "#%02X%02X%02X", Int(color.cgColor.components![0]*255.0), Int(color.cgColor.components![1]*255.0), Int(color.cgColor.components![2]*255.0))
-    }
-    
-    // MARK: - RGB -> UIColor
-    class func rgba(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> UIColor {
-        return UIColor(red: red/255.0, green: green/255.0, blue: blue/255.0, alpha: alpha)
-    }
-    // MARK: - RGBA -> UIColor
-    class func rgb(red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor {
-        return rgba(red: red, green: green, blue: blue, alpha: 1.0)
-    }
-    
-    var rgba: [Int] {
-        var red: CGFloat = 0
-        var green: CGFloat = 0
-        var blue: CGFloat = 0
-        var alpha: CGFloat = 0
-        self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
-        return [Int(red*255.0), Int(green*255.0), Int(blue*255.0), Int(alpha)]
-    }
-    
-    class func randomColor() -> UIColor {
-        let red = CGFloat(arc4random()%255)
-        let green = CGFloat(arc4random()%255)
-        let blue = CGFloat(arc4random()%255)
-        let color = UIColor(red: red/255.0, green: green/255.0, blue: blue/255.0, alpha: 1.0)
-        return color
-    }
-    
-    
-    
-}
-

+ 0 - 32
BFFramework/Classes/BFModules/BFCategorys/UIControl+NXCategory.h

@@ -1,32 +0,0 @@
-//
-//  UIControl+acceptEventInterval.h
-//  NXlib
-//
-//  Created by AK on 15/9/15.
-//  Copyright (c) 2015年 AK. All rights reserved.
-//
-
-// 本类的作用
-// 防止多次连续点击事件,加一个两次点击的时间间隔,专治各种测试人员-_-!
-// 使用 addTarget:action:forControlEvents 给对象添加事件的都可以加时间间隔 如
-// UIButton、UISwitch、UITextField
-
-/*
- *	UIButton * testBtn;
- *  testBtn.uxy_acceptEventInterval = 2.5;
- */
-#import <UIKit/UIKit.h>
-
-@interface UIControl (NXCategory)
-
-/**
- *  设置重复点击加间隔。
- */
-@property(nonatomic, assign) NSTimeInterval uxy_acceptEventInterval;
-
-/**
- *  忽略本次点击。
- */
-@property(nonatomic) BOOL ignoreEvent;
-
-@end

+ 0 - 68
BFFramework/Classes/BFModules/BFCategorys/UIControl+NXCategory.m

@@ -1,68 +0,0 @@
-//
-//  UIControl+acceptEventInterval.m
-//  NXlib
-//
-//  Created by AK on 15/9/15.
-//  Copyright (c) 2015年 AK. All rights reserved.
-//
-
-#import "UIControl+NXCategory.h"
-
-#if TARGET_OS_IPHONE
-#import <objc/message.h>
-#import <objc/runtime.h>
-#else
-#import <objc/objc-class.h>
-#endif
-
-@implementation UIControl (NXCategory)
-
-static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";
-static const char *UIControl_ignoreEvent = "UIControl_ignoreEvent";
-
-//改变两个方法的实现。在类第一次使用的时候回调用这个方法
-+ (void)load
-{
-    Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
-    Method b = class_getInstanceMethod(self, @selector(__uxy_sendAction:to:forEvent:));
-    //改变两个方法的实现
-    method_exchangeImplementations(a, b);  // isnt
-}
-//通过关联对象重写get和set方法
-- (NSTimeInterval)uxy_acceptEventInterval
-{
-    return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];
-}
-
-- (void)setUxy_acceptEventInterval:(NSTimeInterval)uxy_acceptEventInterval
-{
-    objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(uxy_acceptEventInterval),
-                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-}
-#pragma mark 现在是否可点的get和set。通过关联对象。
-- (void)setIgnoreEvent:(BOOL)ignoreEvent
-{
-    objc_setAssociatedObject(self, UIControl_ignoreEvent, @(ignoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-}
-- (BOOL)ignoreEvent { return [objc_getAssociatedObject(self, UIControl_ignoreEvent) boolValue]; }
-- (void)__uxy_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
-{
-    if (self.ignoreEvent)
-    {
-        NSLog(@"无效点击!!!!!!!!!!");
-        return;
-    }
-    if (self.uxy_acceptEventInterval > 0)
-    {
-        self.ignoreEvent = YES;
-        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.uxy_acceptEventInterval * NSEC_PER_SEC)),
-                       dispatch_get_main_queue(), ^{
-                           self.ignoreEvent = NO;
-                       });
-    }
-
-    //调用系统实现
-    [self __uxy_sendAction:action to:target forEvent:event];
-}
-
-@end

+ 0 - 174
BFFramework/Classes/BFModules/BFDebug/NXLogger.swift

@@ -1,174 +0,0 @@
-//
-//  NXLogger.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import UIKit
-
-
-public enum NXLoggerLevel: Int {
-    case info = 1
-    case debug = 2
-    case warning = 3
-    case error = 4
-    case none = 5
-    
-    var name: String {
-        switch self {
-            case .info: return "i"
-            case .debug: return "d"
-            case .warning: return "w"
-            case .error: return "e"
-            case .none: return "N"
-        }
-    }
-}
-
-public enum LoggerOutput: String {
-    case debuggerConsole
-    case deviceConsole
-    case fileOnly
-    case debugerConsoleAndFile
-    case deviceConsoleAndFile
-}
-
-
-private let fileExtension = "txt"
-private let LOG_BUFFER_SIZE = 10
-
-public class NXLogger: NSObject {
-
-    // MARK: - Output
-    public var tag: String?
-    public var level: NXLoggerLevel = .none
-    public var ouput: LoggerOutput = .debuggerConsole
-    public var showThread: Bool = false
-    
-    // MARK: - Init
-    private let isolationQueue = DispatchQueue(label: "com.nxframework.isolation", qos: .background, attributes: .concurrent)
-    private let serialQueue = DispatchQueue(label: "com.nxframework.swiftylog")
-    private let logSubdiretory = NXFileManager.documentDirectoryURL.appendingPathComponent(fileExtension)
-
-    public static let shared = NXLogger()
-    
-    private var _data: [String] = []
-    private var data: [String] {
-        get { return isolationQueue.sync { return _data } }
-        set { isolationQueue.async(flags: .barrier) { self._data = newValue } }
-    }
-    
-    private var logUrl: URL? {
-        let fileName = "NSFrameworkSwiftyLog"
-        try? FileManager.default.createDirectory(at: logSubdiretory, withIntermediateDirectories: false)
-        let url = logSubdiretory.appendingPathComponent(fileName).appendingPathExtension(fileExtension)
-        return url
-    }
-    
-    private override init() {
-        super.init()
-     
-        NotificationCenter.default.addObserver(self, selector: #selector(appMovedToBackground), name:   UIApplication.willResignActiveNotification, object: nil)
-   
-    }
-    
-    // MARK: - Methods
-    @objc private func appMovedToBackground() {
-         self.saveAsync()
-    }
-    
-    func saveAsync() {
-        guard let url = logUrl else { return }
-        serialQueue.async { [weak self] in
-            guard let count = self?.data.count, count > 0 else { return }
-
-            var stringsData = Data()
-            
-            self?.data.forEach { (string) in
-                if let stringData = (string + "\n").data(using: String.Encoding.utf8) {
-                    stringsData.append(stringData)
-                } else {
-                    print("MutalbeData failed")
-                }
-            }
-
-            do {
-                try stringsData.append2File(fileURL: url)
-                self?.data.removeAll()
-            } catch let error as NSError {
-                print("wrote failed: \(url.absoluteString), \(error.localizedDescription)")
-            }
-        }
-    }
-    
-    func removeAllAsync() {
-        guard let url = logUrl else { return }
-        DispatchQueue.global(qos: .userInitiated).async {
-            try? FileManager.default.removeItem(at: url)
-        }
-    }
-    
-    func load() -> [String]? {
-        guard let url = logUrl else { return nil }
-        guard let strings = try? String(contentsOf: url, encoding: String.Encoding.utf8) else { return nil }
-
-        return strings.components(separatedBy: "\n")
-    }
-
-    private func log(_ level: NXLoggerLevel, message: String, currentTime: Date, fileName: String , functionName: String, lineNumber: Int, thread: Thread) {
-        
-        guard level.rawValue >= self.level.rawValue else { return }
-        
-        
-        let _fileName = fileName.split(separator: "/")
-        let text = "\(level.name)-\(showThread ? thread.description : "")[\(_fileName.last ?? "?")#\(functionName)#\(lineNumber)]\(tag ?? ""): \(message)"
-        
-        switch self.ouput {
-            case .fileOnly:
-                addToBuffer(text: "\(currentTime.iso8601) \(text)")
-            case .debuggerConsole:
-                print("\(currentTime.iso8601) \(text)")
-            case .deviceConsole:
-                NSLog(text)
-            case .debugerConsoleAndFile:
-                print("\(currentTime.iso8601) \(text)")
-                addToBuffer(text: "\(currentTime.iso8601) \(text)")
-            case .deviceConsoleAndFile:
-                NSLog(text)
-                addToBuffer(text: "\(currentTime.iso8601) \(text)")
-        }
-    }
-    
-    private func addToBuffer(text: String) {
-        isolationQueue.async(flags: .barrier) { self._data.append(text) }
-        if data.count > LOG_BUFFER_SIZE {
-            saveAsync()
-        }
-    }
-    
-}
-
-// MARK: - Output
-extension NXLogger {
-    public func i(_ message: String, currentTime: Date = Date(), fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, thread: Thread = Thread.current ) {
-        log(.info, message: message, currentTime: currentTime, fileName: fileName, functionName: functionName, lineNumber: lineNumber, thread: thread)
-    }
-    public func d(_ message: String, currentTime: Date = Date(), fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, thread: Thread = Thread.current ) {
-        log(.debug, message: message, currentTime: currentTime, fileName: fileName, functionName: functionName, lineNumber: lineNumber, thread: thread)
-    }
-    public func w(_ message: String, currentTime: Date = Date(), fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, thread: Thread = Thread.current ) {
-        log(.warning, message: message, currentTime: currentTime, fileName: fileName, functionName: functionName, lineNumber: lineNumber, thread: thread)
-    }
-    public func e(_ message: String, currentTime: Date = Date(), fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, thread: Thread = Thread.current ) {
-        log(.error, message: message, currentTime: currentTime, fileName: fileName, functionName: functionName, lineNumber: lineNumber, thread: thread)
-    }
-    
-    public func synchronize() {
-        saveAsync()
-    }
-}
-
-
-

+ 0 - 68
BFFramework/Classes/BFModules/BFDebug/NXLoggerManager.swift

@@ -1,68 +0,0 @@
-//
-//  NXLoggerManager.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import UIKit
-
-extension UIWindow {
-    open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
-        guard NXLogger.shared.level != .none else { return }
-        guard NXLogger.shared.ouput == .debugerConsoleAndFile
-            || NXLogger.shared.ouput == .deviceConsoleAndFile
-            || NXLogger.shared.ouput == .fileOnly else { return }
-        
-        NXLogger.shared.saveAsync()
-        let manager = LoggerManager()
-        manager.show()
-    }
-}
-
-protocol LoggerAction {
-    func removeAll()
-}
-
-class LoggerManager: NSObject {
-    let controller = NXLoggerVC()
-    public func show() {
-        guard let topViewController = UIApplication.topViewController() else { return }
-        guard topViewController .isKind(of: NXLoggerVC.self) == false else { return }
-        
-        controller.data = " \(loadLog())\(deviceInfo())"
-        controller.delegate = self
-        
-        topViewController.present(controller, animated: true, completion: nil)
-    }
-    
-    private func loadLog() -> String {
-        var texts: [String] = []
-        
-        guard let data = NXLogger.shared.load() else { return "" }
-        
-        data.forEach { (string) in
-            texts.append("<pre style=\"line-height:8px;\">\(string)</pre>")
-        }
-        
-        return texts.joined()
-    }
-    
-    private func deviceInfo() -> String {
-        var texts:[String] = []
-        
-        texts.append("<pre style=\"line-height:8px;\">==============================================</pre>")
-        NXDeviceManager.info().forEach { (string) in
-            texts.append("<pre style=\"line-height:8px;\">\(string)</pre>")
-        }
-        return texts.joined()
-    }
-}
-
-extension LoggerManager: LoggerAction {
-    func removeAll() {
-        NXLogger.shared.removeAllAsync()
-        controller.data = deviceInfo()
-    }
-}

+ 0 - 188
BFFramework/Classes/BFModules/BFDebug/NXLoggerVC.swift

@@ -1,188 +0,0 @@
-//
-//  NXLoggerVC.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
- 
-import UIKit
-import MessageUI
-import WebKit
-
-
-private let screenWidth = UIScreen.main.bounds.width
-private let screenHeight = UIScreen.main.bounds.height
-private let keyWindow = UIApplication.shared.keyWindow
-
-let themeColor: UIColor = UIColor.hex(hex: 0x00B3C4)
-
-class NXLoggerVC: UIViewController {
-
-    var delegate: LoggerAction?
-    
-    var data: String = "" {
-        didSet {
-            loadWebView()
-        }
-    }
-
-    var webView: WKWebView = {
-        
-        let source: String = "var meta = document.createElement('meta');" +
-            "meta.name = 'viewport';" +
-            "meta.content = 'width=device-width, initial-scale=0.6, maximum-scale=0.8, user-scalable=yes';" +
-            "var head = document.getElementsByTagName('head')[0];" + "head.appendChild(meta);";
-        let script: WKUserScript = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
-        let userContentController: WKUserContentController = WKUserContentController()
-        let conf = WKWebViewConfiguration()
-        conf.userContentController = userContentController
-        userContentController.addUserScript(script)
-        let view = WKWebView(frame: CGRect.zero, configuration: conf)
-        
-        /*
-        view.scrollView.isScrollEnabled = true               // Make sure our view is interactable
-        view.scrollView.bounces = true                    // Things like this should be handled in web code
-        view.allowsBackForwardNavigationGestures = false   // Disable swiping to navigate
-         */
-        return view
-    }()
-    
-    var textView: UITextView = {
-        let view = UITextView()
-        view.isEditable = false
-        view.backgroundColor = UIColor.lightGray
-        return view
-    }()
-    
-    var btnSend: UIButton = {
-        let button = UIButton(type: .system)
-        button.backgroundColor = themeColor
-        button.setTitleColor(.white, for: .normal)
-        button.roundedCorners(cornerRadius: 5)
-        button.setTitle("Send email", for: .normal)
-        button.addTarget(self, action: #selector(btnSendPressed(_:)), for: .touchUpInside)
-        
-        return button
-    }()
-    
-    var btnRemove: UIButton = {
-        let button = UIButton(type: .system)
-        button.backgroundColor = themeColor
-        button.setTitleColor(.white, for: .normal)
-        button.roundedCorners(cornerRadius: 5)
-        button.setTitle("Remove All", for: .normal)
-        button.addTarget(self, action: #selector(btnRemovePressed(_:)), for: .touchUpInside)
-        return button
-    }()
-    var btnCancel: UIButton = {
-        let button = UIButton(type: .system)
-        button.backgroundColor = themeColor
-        button.setTitleColor(.white, for: .normal)
-        button.roundedCorners(cornerRadius: 5)
-        button.setTitle("Cancel", for: .normal)
-        button.addTarget(self, action: #selector(btnCancelPressed(_:)), for: .touchUpInside)
-        return button
-    }()
-    
-    override func viewDidLoad() {
-        super.viewDidLoad()
-
-        addSubViews()
-        
-        loadWebView()
-
-    }
-    
-    private func addSubViews() {
-        self.view.backgroundColor = UIColor.white
-        
-        [webView, btnSend, btnRemove, btnCancel].forEach { (subView: UIView) in
-            subView.translatesAutoresizingMaskIntoConstraints = false
-            view.addSubview(subView)
-        }
-        
-        let views: [String:UIView] = ["webView": webView, "btnSend": btnSend, "btnRemove": btnRemove, "btnCancel": btnCancel]
-        
-        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[webView]|", options: [], metrics: nil, views: views))
-        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|-(16)-[btnSend]-(16)-|", options: [], metrics: nil, views: views))
-        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|-(16)-[btnRemove]-(16)-|", options: [], metrics: nil, views: views))
-        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|-(16)-[btnCancel]-(16)-|", options: [], metrics: nil, views: views))
-        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(20)-[webView]-[btnSend(==32)]-[btnRemove(==32)]-[btnCancel(==32)]-(8)-|", options: [], metrics: nil, views: views))
-    }
-    
-    @objc func btnCancelPressed(_ button: UIButton) {
-        self.dismiss(animated: true, completion: nil)
-    }
-    
-    @objc func btnSendPressed(_ button: UIButton) {
-        sendEmail()
-    }
-    
-    @objc func btnRemovePressed(_ button: UIButton) {
-        delegate?.removeAll()
-    }
-    
-    private func sendEmail() {
-        guard MFMailComposeViewController.canSendMail() == true else {
-            self.showAlert(withTitle: "No email client", message: "Please configure your email client first")
-            return
-        }
-
-        let mailComposer = MFMailComposeViewController()
-        mailComposer.mailComposeDelegate = self as! MFMailComposeViewControllerDelegate
-        
-        var body = "Host App: \(Bundle.main.bundleIdentifier ?? "")\n"
-        if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
-            let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
-            body += "Host App Version: \(version).\(buildNumber)\n"
-        }
-        if let venderId = UIDevice.current.identifierForVendor {
-            body += "identifierForVendor: \(venderId)\n"
-        }
-
-        mailComposer.setSubject("Log of \(Bundle.main.bundleIdentifier ?? "")")
-        mailComposer.setMessageBody(body, isHTML: false)
-
-
-        webView.evaluateJavaScript("document.documentElement.outerHTML.toString()") { (html, error) in
-            if let string = html as? String, let data = string.data(using: String.Encoding.utf16) {
-                
-                mailComposer.addAttachmentData(data, mimeType: "html", fileName: "\(Bundle.main.bundleIdentifier ?? "log").html" )
-            } else {
-                NXLogger.shared.e("get data from webview failed")
-            }
-        }
-        /*
-        if let data = try? Data(html) {
-            mailComposer.addAttachmentData(data, mimeType: "text/txt", fileName: "SwiftyLog.txt")
-        }
-        */
-        self.present(mailComposer, animated: true, completion: nil)
-    }
-    
-    private func loadWebView() {
-        webView.loadHTMLString(data, baseURL: nil)
-    }
-}
-    
-extension NXLoggerVC: MFMailComposeViewControllerDelegate {
-    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
-        controller.dismiss(animated: true, completion: nil)
-        switch result {
-            case .cancelled:
-                self.showAlert(withTitle: "Cancel", message: "Send email canceled")
-                break
-            case .sent:
-                break
-            case .failed:
-                self.showAlert(withTitle: "Failed", message: "Send email failed")
-                break
-            case .saved:
-                break
-        @unknown default:
-            fatalError("default ")
-        }
-        self.dismiss(animated: true, completion: nil)
-    }
-}

+ 0 - 13
BFFramework/Classes/BFModules/BFMacro/NXConfig.swift

@@ -1,13 +0,0 @@
-//
-//  NXConfig.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import UIKit
-
-class NXConfig: NSObject {
-
-}

+ 0 - 159
BFFramework/Classes/BFModules/BFUtility/NXAudioRecorder.swift

@@ -1,159 +0,0 @@
-//
-import AVFoundation
-import Foundation
-//  NXAudioRecorder.swift
-//  PQSpeed
-//
-//  Created by ak on 2021/1/23.
-//  Copyright © 2021 BytesFlow. All rights reserved.
-//  本类功能:录制声音,并转换成 MP3
-//  alse see https://www.jianshu.com/p/971fff236881
-import UIKit
-
-// 录制时长
-public typealias  RecorderProgross = (_ time: Float64) -> Void
-
-public class NXAudioRecorder {
-    public let recorder: AVAudioRecorder
-
-    public var finishClosure: ((_ isSuccess: Bool, _ url: String) -> Void)? {
-        return delegateHandler.finishClosure
-    }
-
-    /// 由于AVAudioRecorderDelegate继承NSObjectProtocol 所以引入这个类处理代理避免污染主类
-    public  var delegateHandler = EditAudioRecorderDelegateHandler()
-
-    public  var recorderProgross: RecorderProgross?
-    public  var session: AVAudioSession!
-    public  var recordFilePath: String!
-
-    public  var displayLink: CADisplayLink?
-
-    /// 初始化录音器
-    /// - Parameter path: 保存的文件全路径,注意文件后缀一定要是 caf
-    /// - Throws: description
-    public init(path: String) throws {
-        // 1,判断目录文件夹是否存在
-        recordFilePath = path
-        BFLog(message: "recorder file path is \(String(describing: recordFilePath))")
-
-        // 2,参数
-        let fileURL = URL(fileURLWithPath: recordFilePath)
-        // 注意设置参数 设置不对就无法录制
-        let settings: [String: Any] = [
-            AVFormatIDKey: kAudioFormatLinearPCM,
-            AVSampleRateKey: 16000.0,
-            AVNumberOfChannelsKey: 1,
-            AVEncoderBitDepthHintKey: 16,
-//            AVLinearPCMIsFloatKey:true, // 不要打开ios 13有杂音
-            AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue, // 录音质量
-        ]
-        recorder = try AVAudioRecorder(url: fileURL, settings: settings)
-        recorder.isMeteringEnabled = true
-        recorder.delegate = delegateHandler
-        recorder.prepareToRecord()
-    }
-
-    /// 开始录制
-    public func startRecord() {
-        if recorder.isRecording {
-            BFLog(message: "正在录制中。。")
-            return
-        }
-
-        startTimer()
-
-        if AVAudioSession.sharedInstance().category != .playAndRecord {
-            do {
-                try AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: .defaultToSpeaker)
-                try AVAudioSession.sharedInstance().setActive(true)
-            } catch {
-                BFLog(message: error)
-            }
-        }
-
-        session = AVAudioSession.sharedInstance()
-        session.requestRecordPermission { granted in
-            if granted {
-                DispatchQueue.global().async {
-                    DispatchQueue.main.async {}
-                }
-            } else {}
-        }
-
-        recorder.record()
-    }
-
-    // 暂停录制
-    public func pauseRecord() {
-        recorder.pause()
-    }
-
-    // 停止录制
-    public func stopRecord(_ closure: @escaping (_ isSuccess: Bool, _ url: String) -> Void) {
-        if !recorder.isRecording {
-            BFLog(message: "不是录制状态")
-        }
-
-        stopTimer()
-
-        delegateHandler.finishClosure = closure
-
-        recorder.stop()
-    }
-
-    @objc func displayLinkClick(_: CADisplayLink) {
-        recorder.updateMeters()
-
-        BFLog(message: "当前录制时间长 \(String(describing: recorder.currentTime)) 波值:\(String(describing: recorder.averagePower(forChannel: 0)))")
-        if recorderProgross != nil {
-            recorderProgross!(recorder.currentTime)
-        }
-    }
-
-    // 开始计时
-    public func startTimer() {
-        if displayLink == nil {
-            // 创建对象
-            displayLink = CADisplayLink(target: self, selector: #selector(displayLinkClick(_:)))
-            // 设置触发频率 这个周期可以通过frameInterval属性设置,CADisplayLink的selector每秒调用次数=60/frameInterval。比如当frameInterval设为2,每秒调用就变成30次
-//            if #available(iOS 10.0, *) {
-//                displayLink?.preferredFramesPerSecond = 1
-//            } else {
-            displayLink?.frameInterval = 1
-//            }
-            // 加入循环
-            displayLink?.add(to: RunLoop.main, forMode: RunLoop.Mode.default)
-        }
-    }
-
-    // 停止计时
-    public  func stopTimer() {
-        if displayLink != nil {
-            displayLink?.isPaused = true
-            // 将定时器移除主循环
-            displayLink?.remove(from: RunLoop.main, forMode: RunLoop.Mode.default)
-            // 停止定时器
-            displayLink?.invalidate()
-            displayLink = nil
-        }
-    }
-}
-
-public class EditAudioRecorderDelegateHandler: NSObject {
-    public var finishClosure: ((_ flag: Bool, _ url: String) -> Void)?
-}
-
-extension EditAudioRecorderDelegateHandler: AVAudioRecorderDelegate {
-    public  func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
-        BFLog(message: "完成录音结果 is \(flag) url is \(recorder.url)")
-        if flag {
-            finishClosure?(true, recorder.url.relativePath)
-        }
-    }
-
-    public  func audioRecorderEncodeErrorDidOccur(_: AVAudioRecorder, error: Error?) {
-        guard let error = error else { return }
-        BFLog(message: error)
-    }
-}

+ 0 - 113
BFFramework/Classes/BFModules/BFUtility/NXDeviceManager.swift

@@ -1,113 +0,0 @@
-//
-//  NXDeviceManager.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-
-import UIKit
-
-class NXDeviceManager: NSObject {
-    
-    class func info() -> [String] {
-        var data: [String] = []
-        
-        data.append("Device Name: \(deviceNameAlias())")
-        if let bundleId = Bundle.main.bundleIdentifier {
-            data.append("Bundle Identifier: \(bundleId)")
-        }
-        
-        if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
-            let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
-            data.append( "Host App Version: \(version).\(buildNumber)" )
-        }
-        
-        if let venderId = UIDevice.current.identifierForVendor {
-            data.append( "Identifier For Vendor: \(venderId)" )
-        }
-        
-        data.append("System Version: \(getSystemVersion())")
-        data.append("Model: \(platformModelString())")
-        
-//        data.append("Total Disk Space(MB): \(UIDevice.totalDiskSpaceInMB)")
-//        data.append("Free Disk Space(MB): \(UIDevice.freeDiskSpaceInMB)")
-        
-        let lastRestarted = Date(timeIntervalSince1970: TimeInterval(Date().timeIntervalSince1970 - Double(uptime())))
-        data.append("Uptime: \(uptime())/\(lastRestarted)")
-        
-        return data
-    }
-    
-    class var isIpad:Bool {
-        if #available(iOS 8.0, *) {
-            return UIScreen.main.traitCollection.userInterfaceIdiom == .pad
-        } else {
-            return UIDevice.current.userInterfaceIdiom == .pad
-        }
-    }
-    class var isIphone:Bool {
-        if #available(iOS 8.0, *) {
-            return UIScreen.main.traitCollection.userInterfaceIdiom == .phone
-        } else {
-            return UIDevice.current.userInterfaceIdiom == .phone
-        }
-    }
-    
-    ///Name of the devices, like Baudins's Iphone
-    class func deviceNameAlias() -> String {
-        return  UIDevice.current.name
-    }
-    
-    class func processorCount() -> Int {
-        return ProcessInfo.processInfo.activeProcessorCount
-    }
-    
-    //Verion of the OS, like 9.0.1
-    class func osVersion()-> String {
-        return UIDevice.current.systemVersion;
-    }
-    
-    class func platformModelString() -> String {
-        if let key = "hw.machine".cString(using: String.Encoding.utf8) {
-            var size: Int = 0
-            sysctlbyname(key, nil, &size, nil, 0)
-            var machine = [CChar](repeating: 0, count: Int(size))
-            sysctlbyname(key, &machine, &size, nil, 0)
-            return String(cString: machine)
-        }
-        return "Unknown"
-    }
-    
-    /** uptime in seconds **/
-    class func uptime()  -> Int {
-        var currentTime = time_t()
-        var bootTime    = timeval()
-        var mib         = [CTL_KERN, KERN_BOOTTIME]
-        
-        var size = MemoryLayout<timeval>.stride
-        
-        if sysctl(&mib, u_int(mib.count), &bootTime, &size, nil, 0) != -1 && bootTime.tv_sec != 0 {
-            time(&currentTime)
-            
-            if (currentTime < bootTime.tv_sec) {
-                return 0
-            }
-            
-            return  currentTime - bootTime.tv_sec
-        }
-        return 0
-    }
-    
-    class func getScreenBrightness() -> CGFloat {
-        return UIScreen.main.brightness
-    }
-    
-    class func getPhysicalMemory() -> UInt64 {
-        return ProcessInfo.processInfo.physicalMemory
-    }
-    
-    class func getSystemVersion() -> String {
-        return UIDevice.current.systemVersion
-    }
-}

+ 0 - 43
BFFramework/Classes/BFModules/BFUtility/NXFileManager.swift

@@ -1,43 +0,0 @@
-//
-//  NXFileManager.swift
-//  NXFramework-Swift-Demo
-//
-//  Created by ak on 2020/10/26.
-//  Copyright © 2020 NXFramework-Swift. All rights reserved.
-//
-/*
-
-本类功能, 文件操作.(ios, mac)
-
-一,iOS目录结构说明
-1,沙盒目录结构
-├── Documents - 存储用户数据或其它应该定期备份的
-├── Library
-│   ├── Caches -
-用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息
-│   │   └── Snapshots
-│   │       └── com.youyouxingyuan.re
-│   │           ├── A85B73F0-26A8-44E4-A761-446CAB8DAB38@2x.png
-│   │           └── BFAD5885-B767-4320-9A4B-555EC881C50D@2x.png
-│   └── Preferences - 偏好设置文件 NSUserDefaults 保存的数据
-└── tmp - 这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息
-
-2,在iOS8之后,应用每一次重启,沙盒路径都动态的发生了变化但不用担心数据问题,苹果会把你上一个路径中的数据转移到你新的路径中。你上一个路径也会被苹果毫无保留的删除,只保留最新的路径。
-
-@see  <Foundation/NSPathUtilities.h>
-
-*/
-import UIKit
-
-class NXFileManager: NSObject {
-    
-    static var documentDirectoryURL: URL {
-      return try! FileManager.default.url(
-        for: .documentDirectory,
-        in: .userDomainMask,
-        appropriateFor: nil,
-        create: false
-      )
-    }
-
-}

+ 35 - 34
BFFramework/Classes/BFModules/BFUtility/PQAliOssUtil.swift

@@ -7,6 +7,8 @@
 //
 
 import UIKit
+import BFCommonKit
+import BFNetRequestKit
 
 // MARK: - 阿里OSS工具类
 
@@ -25,7 +27,7 @@ public class PQAliOssUtil: NSObject {
     public  var allTasks: [String: OSSMultipartUploadRequest] = [:] // add by ak 保存当前所有任务 用于取消某个任务使用
     public  func startClient(accessKeyId: String, secretKeyId: String, securityToken: String, endpoint: String) -> PQAliOssUtil {
         if endpoint.count == 0 {
-            BFLog(message: "endpoint is nil xxxxxx \(endpoint)")
+            debugPrint("endpoint is nil xxxxxx \(endpoint)")
         }
 
         let credential = OSSStsTokenCredentialProvider(accessKeyId: accessKeyId, secretKeyId: secretKeyId, securityToken: securityToken)
@@ -49,7 +51,7 @@ public class PQAliOssUtil: NSObject {
         putRequest.objectKey = objectKey
         putRequest.uploadingData = data
         putRequest.uploadProgress = { [weak self] _, totalByteSent, totalBytesExpectedToSend in
-            BFLog(message: "文件上传进度:totalByteSent = \(totalByteSent),totalBytesExpectedToSend = \(totalBytesExpectedToSend)")
+            debugPrint("文件上传进度:totalByteSent = \(totalByteSent),totalBytesExpectedToSend = \(totalBytesExpectedToSend)")
             if totalBytesExpectedToSend > 0, totalByteSent == totalBytesExpectedToSend {
                 if isMatarialUpload, self?.aliOssHander != nil {
                     self?.aliOssHander!(isMatarialUpload, materialType, fileExtensions, 1, objectKey, contentMD5, width, height, 0, 0, nil, nil, data, "上传成功")
@@ -64,14 +66,14 @@ public class PQAliOssUtil: NSObject {
         putTask.continue(successBlock: { [weak self] (osstask) -> Any? in
             if osstask.error == nil {
                 let task = self?.client?.presignPublicURL(withBucketName: putRequest.bucketName, withObjectKey: putRequest.objectKey)
-                BFLog(message: "图片原方法上传完成=\(objectKey)")
-                BFLog(message: "url == \(task?.result ?? "" as AnyObject)")
+                debugPrint("图片原方法上传完成=\(objectKey)")
+                debugPrint("url == \(task?.result ?? "" as AnyObject)")
                 imageUploadBlock(osstask, 1, objectKey, fileExtensions)
             } else {
                 if self?.aliOssHander != nil {
                     self?.aliOssHander!(isMatarialUpload, materialType, fileExtensions, 0, objectKey, contentMD5, width, height, 0, 0, nil, nil, data, "上传失败")
                 }
-                BFLog(message: "图片原方法上传失败=\(objectKey),osstask.error = \(osstask.error ?? PQError(msg: "失败"))")
+                debugPrint("图片原方法上传失败=\(objectKey),osstask.error = \(osstask.error ?? PQError(msg: "失败"))")
                 imageUploadBlock(osstask, 0, objectKey, fileExtensions)
             }
 
@@ -124,7 +126,7 @@ public class PQAliOssUtil: NSObject {
             endpoints = response?["Hosts"] as! [String]
             endpoints.append(endpoint)
         }
-        BFLog(message: "取我方服务器STS 返回数据 \(String(describing: response))")
+        debugPrint("取我方服务器STS 返回数据 \(String(describing: response))")
         PQAliOssUtil.shared.PQOSSMultipartUpload(accessKeyId: accessKeyId, secretKeyId: secretKeyId, securityToken: securityToken, bucketName: bucketName, endpoints: endpoints, FileName: FileName, fileURL: URL(fileURLWithPath: (localPath ?? "").replacingOccurrences(of: "file:///", with: "")), ossUploadID: uploadID)
     }
 
@@ -146,9 +148,9 @@ public class PQAliOssUtil: NSObject {
     ///   - height: 视频高 isMatarialUpload = true时传
     /// - Returns: <#description#>
     public  func PQOSSMultipartUpload(accessKeyId: String, secretKeyId: String, securityToken: String, bucketName: String, endpoints: [String], FileName: String, fileURL: URL, ossUploadID: String, materialType: StickerType = .VIDEO, isMatarialUpload: Bool = false, contentMD5: String = "", width: CGFloat = 0, height: CGFloat = 0) -> PQAliOssUtil {
-        BFLog(message: "上传数据 参数\n accessKeyId:\(accessKeyId)\n secretKeyId:\(secretKeyId)\n  securityToken:\(securityToken) \n bucketName:\(bucketName)\n endpoint:\(endpoints)\n FileName:\(FileName)")
+        debugPrint("上传数据 参数\n accessKeyId:\(accessKeyId)\n secretKeyId:\(secretKeyId)\n  securityToken:\(securityToken) \n bucketName:\(bucketName)\n endpoint:\(endpoints)\n FileName:\(FileName)")
         if endpoints.count <= 0 || (endpoints.first?.count ?? 0) <= 0 {
-            BFLog(message: "endpoints 为空")
+            debugPrint("endpoints 为空")
             return .shared
         }
         #if DEBUG
@@ -160,13 +162,12 @@ public class PQAliOssUtil: NSObject {
         let url = PQENVUtil.shared.longvideoapi + (isMatarialUpload ? materialUploadStsTokenUrl : getStsTokenUrl)
         
         let authServerUrl = url + "?appType=\(commonParams()["appType"] as? String ?? "")" + "&machineCode=" + getMachineCode()
-            + "&token=" + BFLoginUserInfo.shared.accessToken + "&loginUid" + BFLoginUserInfo.shared.uid + "&fileType=2" + "&uploadId=\(ossUploadID)"
-
-        BFLog(message: "authServerUrl is: \(authServerUrl)")
-        BFLog(message: "当前上传authServerUrl线程:\(Thread.isMainThread) ")
+            + "&token=" + (PQBFConfig.shared.token ?? "") + "&loginUid" + (PQBFConfig.shared.uid ?? "") + "&fileType=2" + "&uploadId=\(ossUploadID)"
+        debugPrint("authServerUrl is: \(authServerUrl)")
+        debugPrint("当前上传authServerUrl线程:\(Thread.isMainThread) ")
 
         let provider = OSSAuthCredentialProvider(authServerUrl: authServerUrl) { (data) -> Data? in
-            BFLog(message: "当前上传provider线程:\(Thread.isMainThread) ")
+            debugPrint("当前上传provider线程:\(Thread.isMainThread) ")
             // 在 OSSModel 代码中解析有自己的格式 所以接收到我方服务器后的数据要进行二次处理 AccessKeyId 等信息
             let str = String(data: data, encoding: .utf8)
             let jsonDic = jsonStringToDictionary(str!)
@@ -181,7 +182,7 @@ public class PQAliOssUtil: NSObject {
                 ]
             }
             let proStr = dictionaryToJsonString(respDic as [String: Any])
-            BFLog(message: "处理后准备给 OSS SDK数据 \(String(describing: proStr))")
+            debugPrint("处理后准备给 OSS SDK数据 \(String(describing: proStr))")
             let decodedData = proStr?.data(using: .utf8)
             if decodedData != nil {
                 return decodedData
@@ -203,14 +204,14 @@ public class PQAliOssUtil: NSObject {
             fileSize = attr[FileAttributeKey.size] as! UInt64
 
         } catch {
-            BFLog(message: "取文件大小 Error: \(error)")
+            debugPrint("取文件大小 Error: \(error)")
             if aliOssHander != nil {
                 DispatchQueue.main.async { [weak self] in
                     self?.aliOssHander!(isMatarialUpload, materialType, fileURL.absoluteString.pathExtension, 260, FileName, contentMD5, width, height, 0, 0, nil, fileURL, nil, "文件已丢失")
                 }
             }
         }
-        BFLog(message: "文件已经存在  \(fileURL) 文件大小 \(fileSize)")
+        debugPrint("文件已经存在  \(fileURL) 文件大小 \(fileSize)")
         var partSize: Int = 0
         // sdk中规定kClientMaximumOfChunks = 5000;
         let defaultChunkSize: UInt64 = 1024 * 1024
@@ -221,12 +222,12 @@ public class PQAliOssUtil: NSObject {
         } else {
             partSize = Int(ceil(Float(fileSize / 5000)))
         }
-        BFLog(message: "partSize \(partSize)")
+        debugPrint("partSize \(partSize)")
         // 除最后一片外 不能小于 102400(100kb)
         request.partSize = UInt(partSize)
         request.uploadId = ossUploadID
         request.uploadProgress = { [weak self] (bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) -> Void in
-            BFLog(message: "当前上传uploadProgress线程:\(Thread.isMainThread) ")
+            debugPrint("当前上传uploadProgress线程:\(Thread.isMainThread) ")
             self?.paraseSpeedAndRestTime(bytesSent: bytesSent, totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend) { uploadSpeed, resttime in
                 if self?.aliOssProgressHander != nil {
                     DispatchQueue.main.async { [weak self] in
@@ -255,11 +256,11 @@ public class PQAliOssUtil: NSObject {
         let task = client.multipartUpload(request)
 
         task.continue ({ [weak self] (osstask) -> Any? in
-            BFLog(message: "当前上传线程:\(Thread.isMainThread) ")
+            debugPrint("当前上传线程:\(Thread.isMainThread) ")
             if osstask.error == nil {
-                BFLog(message: "上传成功")
+                debugPrint("上传成功")
                 // 文件URL的格式为:BucketName.Endpoint/ObjectName。
-                BFLog(message: " 上传成功注意使用时拼接域名 url == \(FileName)")
+                debugPrint(" 上传成功注意使用时拼接域名 url == \(FileName)")
                 request.callbackParam = ["code": 1, "objectKey": FileName, "msg": "上传成功"]
                 DispatchQueue.main.async { [weak self] in
                     if self?.aliOssHander != nil {
@@ -278,7 +279,7 @@ public class PQAliOssUtil: NSObject {
                 // 上传完成
                 PQEventTrackViewModel.baseReportUpload(businessType: .bt_up_process, objectType: .ot_up_success, pageSource: nil, remindmsg: "上传相关")
             } else {
-                BFLog(message: "上传失败 \(osstask.error!)")
+                debugPrint("上传失败 \(osstask.error!)")
 
                 request.callbackParam = ["code": (osstask.error! as NSError).code, "objectKey": FileName, "msg": osstask.error?.localizedDescription ?? ""]
                 if self?.aliOssHander != nil {
@@ -329,9 +330,9 @@ public class PQAliOssUtil: NSObject {
         #if DEBUG
             OSSLog.enable()
         #endif
-        BFLog(message: "普通上传数据 参数 accessKeyId:\(accessKeyId) secretKeyId:\(secretKeyId) securityToken:\(securityToken) bucketName:\(bucketName) endpoint:\(endpoint) objectKey:\(objectKey) enableBackground:\(enableBackground) fileURL : \(fileURL!)")
+        debugPrint("普通上传数据 参数 accessKeyId:\(accessKeyId) secretKeyId:\(secretKeyId) securityToken:\(securityToken) bucketName:\(bucketName) endpoint:\(endpoint) objectKey:\(objectKey) enableBackground:\(enableBackground) fileURL : \(fileURL!)")
         if endpoint.count <= 0 || (endpoint.first?.count ?? 0) <= 0 {
-            BFLog(message: "endpoints 为空")
+            debugPrint("endpoints 为空")
             return .shared
         }
         let provider = OSSStsTokenCredentialProvider(accessKeyId: accessKeyId, secretKeyId: secretKeyId, securityToken: securityToken)
@@ -376,7 +377,7 @@ public class PQAliOssUtil: NSObject {
                         speed = speed / 1024
                         units = "M/s"
                     }
-                    BFLog(message: "上传速度: \(speed)\(units)   还剩时间 \(resttime)")
+                    debugPrint("上传速度: \(speed)\(units)   还剩时间 \(resttime)")
                 }
             }
             // 多个界面都要处理上传进度 所以使用通知 ? 通知有回到主线?
@@ -385,11 +386,11 @@ public class PQAliOssUtil: NSObject {
         let task = client?.putObject(request)
         if fileURL?.absoluteString.contains("_noise_") ?? false {
             task?.continue ({ [weak self] (osstask) -> Any? in
-                BFLog(message: "当前上传线程:\(Thread.isMainThread) ")
+                debugPrint("当前上传线程:\(Thread.isMainThread) ")
                 if osstask.error == nil {
-                    BFLog(message: "上传成功")
+                    debugPrint("上传成功")
                     // 文件URL的格式为:BucketName.Endpoint/ObjectName。
-                    BFLog(message: " 上传成功注意使用时拼接域名 url == \(objectKey)")
+                    debugPrint(" 上传成功注意使用时拼接域名 url == \(objectKey)")
                     request.callbackParam = ["code": 1, "objectKey": objectKey, "msg": "上传成功"]
                     DispatchQueue.main.async { [weak self] in
                         if self?.aliOssHander != nil {
@@ -408,7 +409,7 @@ public class PQAliOssUtil: NSObject {
                     // 上传完成
                     PQEventTrackViewModel.baseReportUpload(businessType: .bt_up_process, objectType: .ot_up_success, pageSource: nil, remindmsg: "上传相关")
                 } else {
-                    BFLog(message: "上传失败 \(osstask.error!)")
+                    debugPrint("上传失败 \(osstask.error!)")
                     request.callbackParam = ["code": (osstask.error! as NSError).code, "objectKey": objectKey, "msg": osstask.error?.localizedDescription ?? ""]
                     if self?.aliOssHander != nil {
                         DispatchQueue.main.async { [weak self] in
@@ -430,11 +431,11 @@ public class PQAliOssUtil: NSObject {
             }).waitUntilFinished()
         } else {
             task?.continue ({ [weak self] (osstask) -> Any? in
-                BFLog(message: "当前上传线程:\(Thread.isMainThread) ")
+                debugPrint("当前上传线程:\(Thread.isMainThread) ")
                 if osstask.error == nil {
-                    BFLog(message: "上传成功")
+                    debugPrint("上传成功")
                     // 文件URL的格式为:BucketName.Endpoint/ObjectName。
-                    BFLog(message: " 上传成功注意使用时拼接域名 url == \(objectKey)")
+                    debugPrint(" 上传成功注意使用时拼接域名 url == \(objectKey)")
                     request.callbackParam = ["code": 1, "objectKey": objectKey, "msg": "上传成功"]
                     DispatchQueue.main.async { [weak self] in
                         if self?.aliOssHander != nil {
@@ -453,7 +454,7 @@ public class PQAliOssUtil: NSObject {
                     // 上传完成
                     PQEventTrackViewModel.baseReportUpload(businessType: .bt_up_process, objectType: .ot_up_success, pageSource: nil, remindmsg: "上传相关")
                 } else {
-                    BFLog(message: "上传失败 \(osstask.error!)")
+                    debugPrint("上传失败 \(osstask.error!)")
                     request.callbackParam = ["code": (osstask.error! as NSError).code, "objectKey": objectKey, "msg": osstask.error?.localizedDescription ?? ""]
                     if self?.aliOssHander != nil {
                         DispatchQueue.main.async { [weak self] in
@@ -503,7 +504,7 @@ public class PQAliOssUtil: NSObject {
         }
         lastInterfaceBytes = newInterfaceBytes
         let resttime = (totalBytesExpectedToSend - totalBytesSent) / interfaceBytes
-        BFLog(message: "interfaceBytes = \(interfaceBytes),totalBytesExpectedToSend = \(totalBytesExpectedToSend),totalBytesSent = \(totalBytesSent),")
+        debugPrint("interfaceBytes = \(interfaceBytes),totalBytesExpectedToSend = \(totalBytesExpectedToSend),totalBytesSent = \(totalBytesSent),")
         complateHandle("\(PQBridgeObject.formatNetWork(interfaceBytes))", resttime)
     }
 

+ 0 - 22
BFFramework/Classes/BFModules/BFUtility/PQBridgeObject.h

@@ -1,22 +0,0 @@
-//
-//  PQBridgeObject.h
-//  PQSpeed
-//
-//  Created by SanW on 2020/8/20.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#include <ifaddrs.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface PQBridgeObject : NSObject
-+ (NSString *)getByteRate;
-+ (long long) getInterfaceBytes;
-+ (NSString *)formatNetWork:(long long int)rate;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 56
BFFramework/Classes/BFModules/BFUtility/PQBridgeObject.m

@@ -1,56 +0,0 @@
-//
-//  PQBridgeObject.m
-//  PQSpeed
-//
-//  Created by SanW on 2020/8/20.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-#import "PQBridgeObject.h"
-
-@implementation PQBridgeObject
-+ (NSString *)getByteRate {
-    long long intcurrentBytes = [PQBridgeObject getInterfaceBytes];
-    NSString *rateStr = [PQBridgeObject formatNetWork:intcurrentBytes];
-    return rateStr;
-}
-
-+ (long long) getInterfaceBytes {
-    struct ifaddrs *ifa_list = 0, *ifa;
-    if (getifaddrs(&ifa_list) == -1) {
-        return 0;
-    }
-    uint32_t iBytes = 0;
-    uint32_t oBytes = 0;
-    for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
-        if (AF_LINK != ifa->ifa_addr->sa_family)
-            continue;
-        if (!(ifa->ifa_flags & IFF_UP) && !(ifa->ifa_flags & IFF_RUNNING))
-            continue;
-        if (ifa->ifa_data == 0)
-            continue;
-        /* Not a loopback device. */
-        if (strncmp(ifa->ifa_name, "lo", 2)){
-            struct if_data *if_data = (struct if_data *)ifa->ifa_data;
-            iBytes += if_data->ifi_ibytes;
-            
-            oBytes += if_data->ifi_obytes;
-        }
-    }
-    freeifaddrs(ifa_list);
-    NSLog(@"\n[getInterfaceBytes-Total]%d,%d",iBytes,oBytes);
-    return (iBytes + oBytes);
-}
-
-+ (NSString *)formatNetWork:(long long int)rate {
-    if (rate < 1024) {
-        return [NSString stringWithFormat:@"%lldB/s", rate];
-    } else if (rate >= 1024 && rate < 1024 * 1024) {
-        return [NSString stringWithFormat:@"%.1fK/s", (double)rate /1024];
-    } else if (rate >= 1024 * 1024 && rate < 1024 * 1024 * 1024) {
-        return [NSString stringWithFormat:@"%.1fM/s", (double)rate / (1024*1024)];
-    } else {
-        return @"0B/s";
-    };
-}
-@end

+ 0 - 180
BFFramework/Classes/BFModules/BFUtility/PQCreateEmptyWAV.swift

@@ -1,180 +0,0 @@
-//
-//  PQCreateEmptyWAV.swift
-//  PQSpeed
-//
-//  Created by ak on 2020/9/16.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//  功能: 生成指定长度的空 WAV 文件
-/*
-    e.g.
-    let tool = LYEmptyWAV(sampleRate: 44100,
-                                channel: 1,
-                                duration: 20,
-                                bit: 16);
-
-          var documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String
-          documentPath.append("/test.wav")
-          tool.createEmptyWAVFile(url: URL(fileURLWithPath: documentPath))
-
-     600 s  622028807.468433  622028844.650877
- */
-
-import UIKit
-
-import AudioToolbox
-import Foundation
-public class PQCreateEmptyWAV {
-    // 采样率
-    private var mSampleRate: Double = 44100
-
-    // 声道
-    private var mChannel: Double = 1
-    // 时长
-    private var mduration: Double = 5.0
-    // 采样位数
-    private var mbit: Double = 16
-    public init(sampleRate: Double = 44100, channel: Double = 1, duration: Double, bit: Double = 16) {
-        mSampleRate = sampleRate
-        mChannel = channel
-        mduration = duration
-        mbit = bit
-        if mduration == 0 {
-            BFLog(message: "时长为0??")
-        }
-        BFLog(message: "mSampleRate is\(mSampleRate) mChannel is \(mChannel) mduration is:\(mduration) mbit is \(mbit)")
-    }
-
-    public  func createEmptyWAVFile(url: URL, completeHander: @escaping (_ fileURL: URL?) -> Void) {
-        DispatchQueue.global().async {
-            // 数字音频文件大小(Byte) = 采样频率(Hz)× 采样时长(S)×(采样位数 / 8)× 声道数(单声道为1,立体声为2)
-//        BFLog(message: "createEmptyWAVFile 1")
-            let size = Int64(self.mSampleRate * self.mduration * (self.mbit / 8) * self.mChannel)
-
-            let bufer = Array(repeating: 0, count: Int(size))
-//        BFLog(message: "createEmptyWAVFile 2 \(size)")
-            let data = Data(bytes: bufer, count: Int(size))
-            let totalAudioLen = size
-            let totalDataLen = totalAudioLen + 44
-//        BFLog(message: "createEmptyWAVFile 3")
-            self.writewaveFileHeader(output: url,
-                                     totalAudioLen: totalAudioLen,
-                                     totalDataLen: totalDataLen,
-                                     longSampleRate: Int64(self.mSampleRate),
-                                     channels: Int(self.mChannel),
-                                     byteRate: size,
-                                     audioData: data)
-
-            DispatchQueue.main.async {
-                completeHander(url)
-            }
-        }
-    }
-    
-    public  func createEmptyWAVFile(url: URL) {
- 
-            // 数字音频文件大小(Byte) = 采样频率(Hz)× 采样时长(S)×(采样位数 / 8)× 声道数(单声道为1,立体声为2)
-//        BFLog(message: "createEmptyWAVFile 1")
-            let size = Int64(self.mSampleRate * self.mduration * (self.mbit / 8) * self.mChannel)
-
-            let bufer = Array(repeating: 0, count: Int(size))
-//        BFLog(message: "createEmptyWAVFile 2 \(size)")
-            let data = Data(bytes: bufer, count: Int(size))
-            let totalAudioLen = size
-            let totalDataLen = totalAudioLen + 44
-//        BFLog(message: "createEmptyWAVFile 3")
-            self.writewaveFileHeader(output: url,
-                                     totalAudioLen: totalAudioLen,
-                                     totalDataLen: totalDataLen,
-                                     longSampleRate: Int64(self.mSampleRate),
-                                     channels: Int(self.mChannel),
-                                     byteRate: size,
-                                     audioData: data)
-
-        
-    }
-
-
-    public  func writewaveFileHeader(output: URL, totalAudioLen: Int64,
-                             totalDataLen: Int64,
-                             longSampleRate: Int64,
-                             channels: Int,
-                             byteRate: Int64,
-                             audioData: Data)
-    {
-        BFLog(message: "createEmptyWAVFile 4")
-        var header: [UInt8] = Array(repeating: 0, count: 44)
-
-        // RIFF/WAVE header
-        header[0] = UInt8(ascii: "R")
-        header[1] = UInt8(ascii: "I")
-        header[2] = UInt8(ascii: "F")
-        header[3] = UInt8(ascii: "F")
-        header[4] = (UInt8)(totalDataLen & 0xFF)
-        header[5] = (UInt8)((totalDataLen >> 8) & 0xFF)
-        header[6] = (UInt8)((totalDataLen >> 16) & 0xFF)
-        header[7] = (UInt8)((totalDataLen >> 24) & 0xFF)
-
-        // WAVE
-        header[8] = UInt8(ascii: "W")
-        header[9] = UInt8(ascii: "A")
-        header[10] = UInt8(ascii: "V")
-        header[11] = UInt8(ascii: "E")
-
-        // 'fmt' chunk
-        header[12] = UInt8(ascii: "f")
-        header[13] = UInt8(ascii: "m")
-        header[14] = UInt8(ascii: "t")
-        header[15] = UInt8(ascii: " ")
-
-        // 4 bytes: size of 'fmt ' chunk
-        header[16] = 16
-        header[17] = 0
-        header[18] = 0
-        header[19] = 0
-
-        // format = 1
-        header[20] = 1
-        header[21] = 0
-        header[22] = UInt8(channels)
-        header[23] = 0
-
-        header[24] = (UInt8)(longSampleRate & 0xFF)
-        header[25] = (UInt8)((longSampleRate >> 8) & 0xFF)
-        header[26] = (UInt8)((longSampleRate >> 16) & 0xFF)
-        header[27] = (UInt8)((longSampleRate >> 24) & 0xFF)
-
-        header[28] = (UInt8)(byteRate & 0xFF)
-        header[29] = (UInt8)((byteRate >> 8) & 0xFF)
-        header[30] = (UInt8)((byteRate >> 16) & 0xFF)
-        header[31] = (UInt8)((byteRate >> 24) & 0xFF)
-
-        // block align
-        header[32] = UInt8(2 * 16 / 8)
-        header[33] = 0
-
-        // bits per sample
-        header[34] = 16
-        header[35] = 0
-
-        // data
-        header[36] = UInt8(ascii: "d")
-        header[37] = UInt8(ascii: "a")
-        header[38] = UInt8(ascii: "t")
-        header[39] = UInt8(ascii: "a")
-        header[40] = UInt8(totalAudioLen & 0xFF)
-        header[41] = UInt8((totalAudioLen >> 8) & 0xFF)
-        header[42] = UInt8((totalAudioLen >> 16) & 0xFF)
-        header[43] = UInt8((totalAudioLen >> 24) & 0xFF)
-
-//        guard let writeHandler = try? FileHandle(forWritingTo: output) else { return }
-        var data = Data(header)
-        data.append(audioData)
-        BFLog(message: "createEmptyWAVFile 5")
-        do {
-            try data.write(to: output, options: .atomicWrite)
-            BFLog(message: "createEmptyWAVFile 6 \(data.count)")
-        } catch {
-            BFLog(message: " write file error \(error)")
-        }
-    }
-}

+ 0 - 526
BFFramework/Classes/BFModules/BFUtility/PQLZStringUtil.swift

@@ -1,526 +0,0 @@
-import Foundation
-
-private let keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
-private let keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$"
-
-private let getCharFromInt: (Int) -> Character = { a in
-    if let scalar = Unicode.Scalar(a) {
-        return Character(scalar)
-    } else {
-        return Character(" ")
-    }
-}
-
-private var baseReserveDict = [String: [Character: Int]]()
-
-private typealias GetCharFromInt<T> = (Int) -> T
-private typealias GetNextValue = (Int) -> Int
-
-private typealias DecompressData = (value: Int, position: Int, index: Int)
-private typealias CompressContext<T> = (dict: [String: Int], dictCreate: [String: Bool], data: T, val: Int, position: Int) where T: RangeReplaceableCollection
-
-private func getBaseValue(alphabet: String, char: Character) -> Int {
-    if let charcter = baseReserveDict[alphabet]?[char] {
-        return charcter
-    } else {
-        baseReserveDict[alphabet] = [Character: Int]()
-        for (index, char) in alphabet.enumerated() {
-            baseReserveDict[alphabet]![char] = index
-        }
-
-        return baseReserveDict[alphabet]![char]!
-    }
-}
-
-public func compressToBase64(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    let result = _compress(input: input, bitPerChar: 6, charFromInt: { a in String(keyStrBase64[a]) })
-    switch result.count % 4 {
-    case 0:
-        return result
-    case 1:
-        return result + "==="
-    case 2:
-        return result + "=="
-    case 3:
-        return result + "="
-    default:
-        return ""
-    }
-}
-
-public func decompressFromBase64(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _decompress(length: input.count, resetValue: 32, nextValue: { a in getBaseValue(alphabet: keyStrBase64, char: input[a]) })
-}
-
-public func compressToUTF16(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _compress(input: input, bitPerChar: 15, charFromInt: { a in String(getCharFromInt(a + 32)) }) + " "
-}
-
-public func decompressFromUTF16(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _decompress(length: input.utf16.count, resetValue: 16384, nextValue: { i in Int(input.utf16[i]) - 32 })
-}
-
-public func compressToUInt8Array(input: String) -> [UInt8] {
-    let compressed: Data = compress(input: input)
-    var buffer = [UInt8](repeating: 0, count: compressed.count)
-
-    for i in 0..<(compressed.count / 2) {
-        buffer[i * 2] = compressed[i * 2 + 1]
-        buffer[i * 2 + 1] = compressed[i * 2]
-    }
-
-    return buffer
-}
-
-public func decompressFromUInt8Array(input: [UInt8]) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _decompress(length: input.count / 2, resetValue: 32768, nextValue: { i in
-        let lower = Int(input[i * 2]) * 256
-        let upper = Int(input[i * 2 + 1])
-        return upper + lower
-    })
-}
-
-public func compressToEncodedURIComponent(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _compress(input: input, bitPerChar: 6, charFromInt: { i in String(keyStrUriSafe[i]) })
-}
-
-public func decompressFromEncodedURIComponent(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    let replaced = input.replacingOccurrences(of: " ", with: "+")
-
-    return _decompress(length: replaced.count, resetValue: 32, nextValue: { a in getBaseValue(alphabet: keyStrUriSafe, char: input[a]) })
-}
-
-public func compress(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _compress(input: input, bitPerChar: 16, charFromInt: { a in String(getCharFromInt(a)) })
-}
-
-public func compress(input: String) -> Data {
-    guard !input.isEmpty else {
-        return Data()
-    }
-
-    return _compress(input: input, bitPerChar: 16, charFromInt: { a in
-        Data(bytes: [UInt8(a % 256), UInt8(a >> 8)])
-    })
-}
-
-// TODO: Change Generics
-private func _compress<T: RangeReplaceableCollection>(input: String, bitPerChar: Int, charFromInt: GetCharFromInt<T>) -> T {
-    guard !input.isEmpty else {
-        return T()
-    }
-
-    var value = 0
-    var wc = ""
-    var w = ""
-    var enlargeIn = 2
-    var dictSize = 3
-    var numBits = 2
-    var context = (dict: [String: Int](), dictCreate: [String: Bool](), data: T(), val: 0, position: 0)
-
-    for c in input {
-        let s = String(c)
-
-        if context.dict.index(forKey: s) == nil {
-            context.dict[s] = dictSize
-            context.dictCreate[s] = true
-            dictSize += 1
-        }
-
-        wc = w + s
-
-        if context.dict[wc] != nil {
-            w = wc
-        } else {
-            if context.dictCreate.index(forKey: w) != nil {
-                if let scalar = w.unicodeScalars.first, scalar.value < 256 {
-                    for _ in 0..<numBits {
-                        context.val <<= 1
-
-                        if context.position == bitPerChar - 1 {
-                            context.position = 0
-                            context.data += charFromInt(context.val)
-                            context.val = 0
-                        } else {
-                            context.position += 1
-                        }
-                    }
-
-                    value = Int(w.unicodeScalars.first!.value)
-
-                    for _ in 0..<8 {
-                        context.val = (context.val << 1) | (value & 1)
-
-                        if context.position == bitPerChar - 1 {
-                            context.position = 0
-                            context.data += charFromInt(context.val)
-                            context.val = 0
-                        } else {
-                            context.position += 1
-                        }
-
-                        value >>= 1
-                    }
-                } else {
-                    value = 1
-
-                    for _ in 0..<numBits {
-                        context.val = (context.val << 1) | value
-
-                        if context.position == bitPerChar - 1 {
-                            context.position = 0
-                            context.data += charFromInt(context.val)
-                            context.val = 0
-                        } else {
-                            context.position += 1
-                        }
-                        value = 0
-                    }
-
-                    value = Int(w.unicodeScalars.first!.value)
-
-                    for _ in 0..<16 {
-                        context.val = (context.val << 1) | (value & 1)
-
-                        if context.position == bitPerChar - 1 {
-                            context.position = 0
-                            context.data += charFromInt(context.val)
-                            context.val = 0
-                        } else {
-                            context.position += 1
-                        }
-
-                        value >>= 1
-                    }
-                }
-
-                enlargeIn -= 1
-
-                if enlargeIn == 0 {
-                    enlargeIn = 2 << (numBits - 1)
-                    numBits += 1
-                }
-
-                context.dictCreate.removeValue(forKey: w)
-            } else {
-                value = context.dict[w]!
-
-                for _ in 0..<numBits {
-                    context.val = (context.val << 1) | (value & 1)
-
-                    if context.position == bitPerChar - 1 {
-                        context.position = 0
-                        context.data += charFromInt(context.val)
-                        context.val = 0
-                    } else {
-                        context.position += 1
-                    }
-
-                    value >>= 1
-                }
-            }
-            enlargeIn -= 1
-
-            if enlargeIn == 0 {
-                enlargeIn = 2 << (numBits - 1)
-                numBits += 1
-            }
-            context.dict[wc] = dictSize
-            dictSize += 1
-            w = s
-        }
-    }
-
-    if w != "" {
-        if context.dictCreate.index(forKey: w) != nil {
-            if let scalar = w.unicodeScalars.first, scalar.value < 256 {
-                for _ in 0..<numBits {
-                    context.val <<= 1
-
-                    if context.position == bitPerChar - 1 {
-                        context.position = 0
-                        context.data += charFromInt(context.val)
-                        context.val = 0
-                    } else {
-                        context.position += 1
-                    }
-                }
-
-                value = Int(w.unicodeScalars.first!.value)
-
-                for _ in 0..<8 {
-                    context.val = (context.val << 1) | (value & 1)
-
-                    if context.position == bitPerChar - 1 {
-                        context.position = 0
-                        context.data += charFromInt(context.val)
-                        context.val = 0
-                    } else {
-                        context.position += 1
-                    }
-
-                    value >>= 1
-                }
-            } else {
-                value = 1
-
-                for _ in 0..<numBits {
-                    context.val = (context.val << 1) | value
-
-                    if context.position == bitPerChar - 1 {
-                        context.position = 0
-                        context.data += charFromInt(context.val)
-                        context.val = 0
-                    } else {
-                        context.position += 1
-                    }
-
-                    value = 0
-                }
-
-                value = Int(w.unicodeScalars.first!.value)
-
-                for _ in 0..<16 {
-                    context.val = (context.val << 1) | (value & 1)
-
-                    if context.position == bitPerChar - 1 {
-                        context.position = 0
-                        context.data += charFromInt(context.val)
-                        context.val = 0
-                    } else {
-                        context.position += 1
-                    }
-
-                    value >>= 1
-                }
-            }
-
-            enlargeIn -= 1
-
-            if enlargeIn == 0 {
-                enlargeIn = 2 << (numBits - 1)
-                numBits += 1
-            }
-
-            context.dictCreate.removeValue(forKey: w)
-        } else {
-            value = context.dict[w]!
-
-            for _ in 0..<numBits {
-                context.val = (context.val << 1) | (value & 1)
-
-                if context.position == bitPerChar - 1 {
-                    context.position = 0
-                    context.data += charFromInt(context.val)
-                    context.val = 0
-                } else {
-                    context.position += 1
-                }
-
-                value >>= 1
-            }
-        }
-
-        enlargeIn -= 1
-
-        if enlargeIn == 0 {
-            enlargeIn = 2 << (numBits - 1)
-            numBits += 1
-        }
-    }
-    value = 2
-
-    for _ in 0..<numBits {
-        context.val = (context.val << 1) | (value & 1)
-
-        if context.position == bitPerChar - 1 {
-            context.position = 0
-            context.data += charFromInt(context.val)
-            context.val = 0
-        } else {
-            context.position += 1
-        }
-
-        value >>= 1
-    }
-
-    while true {
-        context.val <<= 1
-
-        if context.position == bitPerChar - 1 {
-            context.data += charFromInt(context.val)
-            break
-        } else {
-            context.position += 1
-        }
-    }
-
-    return context.data
-}
-
-public func decompress(input: String) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _decompress(length: input.utf16.count, resetValue: 32768, nextValue: { i in Int(input.utf16[i]) })
-}
-
-public func decompress(input: Data) -> String {
-    guard !input.isEmpty else {
-        return ""
-    }
-
-    return _decompress(length: input.count / 2, resetValue: 32768, nextValue: { i in
-        let lower = Int(input[i * 2])
-        let upper = Int(input[i * 2 + 1]) * 256
-        return upper + lower
-    })
-}
-
-private func _decompress(length: Int, resetValue: Int, nextValue: @escaping GetNextValue) -> String {
-    var dict: [Int: String] = [0: "\u{0}", 1: "\u{1}", 2: "\u{2}"]
-    var next = 0
-    var enlargeIn = 4
-    var dictSize = 4
-    var numBits = 3
-    var bits = 0
-    var c = 0
-    var entry = ""
-    var w = ""
-    var result = ""
-    var data = (value: nextValue(0), position: resetValue, index: 1)
-
-    func _slide(data: inout DecompressData, maxpower: Int) -> Int {
-        var bits = 0
-        var power = 1
-
-        while power != maxpower {
-            let resb = data.value & data.position
-            data.position >>= 1
-
-            if data.position == 0 {
-                data.position = resetValue
-                data.value = nextValue(data.index)
-                data.index += 1
-            }
-
-            bits |= (resb > 0 ? 1 : 0) * power
-            power <<= 1
-        }
-
-        return bits
-    }
-
-    bits = _slide(data: &data, maxpower: 2 << 1)
-    next = bits
-
-    if next == 0 {
-        bits = _slide(data: &data, maxpower: 2 << 7)
-        c = bits
-    } else if next == 1 {
-        bits = _slide(data: &data, maxpower: 2 << 15)
-        c = bits
-    } else if next == 2 {
-        return ""
-    }
-
-    w = String(Unicode.Scalar(c)!)
-    dict[3] = w
-    result += w
-
-    while true {
-        guard data.index <= length else {
-            return ""
-        }
-
-        bits = _slide(data: &data, maxpower: 2 << (numBits - 1))
-        c = bits
-
-        if c == 0 {
-            bits = _slide(data: &data, maxpower: 2 << 7)
-            dict[dictSize] = String(getCharFromInt(bits))
-            dictSize += 1
-            c = dictSize - 1
-            enlargeIn -= 1
-        } else if c == 1 {
-            bits = _slide(data: &data, maxpower: 2 << 15)
-            dict[dictSize] = String(getCharFromInt(bits))
-            dictSize += 1
-            c = dictSize - 1
-            enlargeIn -= 1
-        } else if c == 2 {
-            return result
-        }
-
-        if enlargeIn == 0 {
-            enlargeIn = 2 << (numBits - 1)
-            numBits += 1
-        }
-
-        if let e = dict[c] {
-            entry = e
-        } else {
-            if c == dictSize {
-                entry = w + String(w[0])
-            } else {
-                return ""
-            }
-        }
-
-        result += entry
-        dict[dictSize] = w + String(entry[0])
-        dictSize += 1
-        enlargeIn -= 1
-        w = entry
-
-        if enlargeIn == 0 {
-            enlargeIn = 2 << (numBits - 1)
-            numBits += 1
-        }
-    }
-}
-
-extension String {
-    subscript(pos: Int) -> Character {
-        return self[String.Index(encodedOffset: pos)]
-    }
-}
-
-extension String.UTF16View {
-    subscript(pos: Int) -> Unicode.UTF16.CodeUnit {
-        return self[String.UTF16View.Index(encodedOffset: pos)]
-    }
-}

+ 0 - 778
BFFramework/Classes/BFModules/BFUtility/PQPHAssetVideoParaseUtil.swift

@@ -1,778 +0,0 @@
-//
-//  PQPHAssetVideoParaseUtil.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/8/3.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import CoreServices
-import Photos
-import UIKit
-
-var currentExportSession: AVAssetExportSession?
-open class PQPHAssetVideoParaseUtil: NSObject {
-    static var imagesOptions: PHImageRequestOptions = {
-        let imagesOptions = PHImageRequestOptions()
-        imagesOptions.isSynchronous = false
-        imagesOptions.deliveryMode = .fastFormat
-        imagesOptions.resizeMode = .fast
-        imagesOptions.version = .current
-        return imagesOptions
-    }()
-
-    static var singleImageOptions: PHImageRequestOptions = {
-        let singleImageOptions = PHImageRequestOptions()
-        singleImageOptions.isSynchronous = true
-        singleImageOptions.isNetworkAccessAllowed = true
-        singleImageOptions.deliveryMode = .highQualityFormat
-        singleImageOptions.resizeMode = .none
-        singleImageOptions.version = .current
-        return singleImageOptions
-    }()
-
-    static var videoRequestOptions: PHVideoRequestOptions = {
-        let videoRequestOptions = PHVideoRequestOptions()
-        // 解决慢动作视频返回AVComposition而不是AVURLAsset
-//        videoRequestOptions.version = .original
-        videoRequestOptions.version = .current
-        // 下载iCloud视频
-        videoRequestOptions.isNetworkAccessAllowed = true
-        videoRequestOptions.deliveryMode = .mediumQualityFormat
-        return videoRequestOptions
-    }()
-
-    /// PHAsset解析为AVPlayerItem
-    /// - Parameters:
-    ///   - asset: <#asset description#>
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func parasToAVPlayerItem(phAsset: PHAsset, isHighQuality: Bool = false, resultHandler: @escaping (AVPlayerItem?, Float64, [AnyHashable: Any]?) -> Void) {
-        PHImageManager().requestPlayerItem(forVideo: phAsset, options: videoRequestOptions) { playerItem, info in
-            if isHighQuality, (playerItem?.asset as? AVURLAsset)?.url.absoluteString.components(separatedBy: "/").last?.contains(".medium.") ?? false {
-                let tempVideoOptions = PHVideoRequestOptions()
-                tempVideoOptions.version = .original
-                // 下载iCloud视频
-                tempVideoOptions.isNetworkAccessAllowed = true
-                tempVideoOptions.deliveryMode = .highQualityFormat
-                tempVideoOptions.progressHandler = { progress, error, pointer, info in
-                    BFLog(message: "导出playerItem-progress = \(progress),error = \(String(describing: error)),pointer = \(pointer),info = \(String(describing: info))")
-                }
-                PHImageManager().requestPlayerItem(forVideo: phAsset, options: tempVideoOptions) { playerItem, info in
-                    let size = try! (playerItem?.asset as? AVURLAsset)?.url.resourceValues(forKeys: [.fileSizeKey])
-                    BFLog(message: "size = \(String(describing: size))")
-                    resultHandler(playerItem, Float64(size?.fileSize ?? 0), info)
-                }
-            } else {
-                let size = try! (playerItem?.asset as? AVURLAsset)?.url.resourceValues(forKeys: [.fileSizeKey])
-                BFLog(message: "size = \(String(describing: size))")
-                resultHandler(playerItem, Float64(size?.fileSize ?? 0), info)
-            }
-        }
-    }
-
-    /// PHAsset解析为AVAsset
-    /// - Parameters:
-    ///   - asset: <#asset description#>
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func parasToAVAsset(phAsset: PHAsset, isHighQuality: Bool = true, resultHandler: @escaping (AVAsset?, Int, AVAudioMix?, [AnyHashable: Any]?) -> Void) {
-        PHImageManager.default().requestAVAsset(forVideo: phAsset, options: videoRequestOptions) { avAsset, audioMix, info in
-            if isHighQuality, (avAsset as? AVURLAsset)?.url.absoluteString.components(separatedBy: "/").last?.contains(".medium.") ?? false {
-                let tempVideoOptions = PHVideoRequestOptions()
-                tempVideoOptions.version = .original
-                // 下载iCloud视频
-                tempVideoOptions.isNetworkAccessAllowed = true
-                tempVideoOptions.deliveryMode = .highQualityFormat
-                tempVideoOptions.progressHandler = { progress, error, pointer, info in
-                    BFLog(message: "导出playerItem-progress = \(progress),error = \(String(describing: error)),pointer = \(pointer),info = \(String(describing: info))")
-                }
-                PHImageManager.default().requestAVAsset(forVideo: phAsset, options: tempVideoOptions) { tempAvAsset, tempAudioMix, tempInfo in
-                    let size = try! (tempAvAsset as? AVURLAsset)?.url.resourceValues(forKeys: [.fileSizeKey])
-                    BFLog(message: "size = \(String(describing: size))")
-                    resultHandler(tempAvAsset, size?.fileSize ?? 0, tempAudioMix, tempInfo)
-                }
-            } else {
-                let size = try! (avAsset as? AVURLAsset)?.url.resourceValues(forKeys: [.fileSizeKey])
-                resultHandler(avAsset, size?.fileSize ?? 0, audioMix, info)
-                BFLog(message: "size = \(String(describing: size))")
-            }
-        }
-    }
-
-    /// PHAsset 转码为.mp4保存本地
-    /// - Parameters:
-    ///   - phAsset: <#phAsset description#>
-    ///   - isAdjustRotationAngle: 是否调整旋转角度
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func exportPHAssetToMP4(phAsset: PHAsset, isAdjustRotationAngle: Bool = true, isCancelCurrentExport: Bool = false, deliveryMode: PHVideoRequestOptionsDeliveryMode? = .automatic, resultHandler: @escaping (_ phAsset: PHAsset, _ aVAsset: AVAsset?, _ filePath: String?, _ errorMsg: String?) -> Void) {
-        BFLog(message: "导出相册视频-开始导出:phAsset = \(phAsset)")
-        if isCancelCurrentExport {
-            currentExportSession?.cancelExport()
-        }
-        PQPHAssetVideoParaseUtil.parasToAVAsset(phAsset: phAsset) { avAsset, fileSize, _, _ in
-            if avAsset is AVURLAsset {
-                // 创建目录
-                createDirectory(path: photoLibraryDirectory)
-                let fileName = (avAsset as! AVURLAsset).url.absoluteString
-                let filePath = photoLibraryDirectory + fileName.md5.md5 + ".mp4"
-                let data = try? Data(contentsOf: NSURL.fileURL(withPath: filePath))
-                if FileManager.default.fileExists(atPath: filePath) && (data?.count ?? 0) > fileSize / 40 {
-                    BFLog(message: "导出相册视频-已经导出完成:\(filePath)")
-                    DispatchQueue.main.async {
-                        resultHandler(phAsset, avAsset, filePath, nil)
-                    }
-                } else {
-                    let tempExportSession = PQSingletoMemoryUtil.shared.allExportSession[phAsset]
-                    if tempExportSession != nil {
-                        BFLog(message: "导出相册视频-正在导出")
-                        return
-                    }
-                    BFLog(message: "导出相册视频-未导出视频过,开始导出:phAsset = \(phAsset)")
-                    // 删除以创建地址
-                    if FileManager.default.fileExists(atPath: filePath) {
-                        do {
-                            try FileManager.default.removeItem(at: NSURL.fileURL(withPath: filePath))
-                        } catch {
-                            BFLog(message: "导出相册视频-error == \(error)")
-                        }
-                    }
-                    let requestOptions = PHVideoRequestOptions()
-                    // 解决慢动作视频返回AVComposition而不是AVURLAsset
-                    //        videoRequestOptions.version = .original
-                    requestOptions.version = .current
-                    // 下载iCloud视频
-                    requestOptions.isNetworkAccessAllowed = false
-                    requestOptions.progressHandler = { progress, error, pointer, info in
-                        BFLog(message: "导出相册视频-progress = \(progress),error = \(String(describing: error)),pointer = \(pointer),info = \(String(describing: info))")
-                    }
-                    requestOptions.deliveryMode = deliveryMode ?? .automatic
-                    PHImageManager.default().requestExportSession(forVideo: phAsset, options: requestOptions, exportPreset: (deliveryMode == .automatic || deliveryMode == .mediumQualityFormat) ? AVAssetExportPresetMediumQuality : (deliveryMode == .highQualityFormat ? AVAssetExportPresetHighestQuality : AVAssetExportPresetLowQuality), resultHandler: { avAssetExportSession, _ in
-                        BFLog(message: "导出相册视频-请求到导出 avAssetExportSession = \(String(describing: avAssetExportSession))")
-                        currentExportSession = avAssetExportSession
-                        if avAssetExportSession != nil {
-                            PQSingletoMemoryUtil.shared.allExportSession[phAsset] = avAssetExportSession!
-                        }
-                        avAssetExportSession?.outputURL = NSURL(fileURLWithPath: filePath) as URL
-                        avAssetExportSession?.shouldOptimizeForNetworkUse = true
-                        avAssetExportSession?.outputFileType = .mp4
-                        if isAdjustRotationAngle {
-                            let rotationAngle = PQPHAssetVideoParaseUtil.videoRotationAngle(assert: avAsset!)
-                            // mdf by ak 统一导出的视频为30FPS
-                            var centerTranslate: CGAffineTransform = CGAffineTransform(translationX: 0, y: 0)
-                            var mixedTransform: CGAffineTransform = CGAffineTransform()
-                            let videoComposition = AVMutableVideoComposition()
-                            videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
-                            let tracks = avAsset?.tracks(withMediaType: .video)
-                            let firstTrack = tracks?.first
-
-                            videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.width ?? 0, height: firstTrack?.naturalSize.height ?? 0)
-
-                            mixedTransform = centerTranslate.rotated(by: 0)
-
-                            if rotationAngle == 90 {
-                                centerTranslate = CGAffineTransform(translationX: firstTrack?.naturalSize.height ?? 0, y: 0)
-                                mixedTransform = centerTranslate.rotated(by: .pi / 2)
-                                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.height ?? 0, height: firstTrack?.naturalSize.width ?? 0)
-                            } else if rotationAngle == 180 {
-                                centerTranslate = CGAffineTransform(translationX: firstTrack?.naturalSize.width ?? 0, y: firstTrack?.naturalSize.height ?? 0)
-                                mixedTransform = centerTranslate.rotated(by: .pi)
-                                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.width ?? 0, height: firstTrack?.naturalSize.height ?? 0)
-                            } else if rotationAngle == 270 {
-                                centerTranslate = CGAffineTransform(translationX: 0, y: firstTrack?.naturalSize.width ?? 0)
-                                mixedTransform = centerTranslate.rotated(by: .pi / 2 * 3)
-                                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.height ?? 0, height: firstTrack?.naturalSize.width ?? 0)
-                            }
-                            let roateInstruction = AVMutableVideoCompositionInstruction()
-                            roateInstruction.timeRange = CMTimeRange(start: CMTime.zero, end: avAsset?.duration ?? CMTime.zero)
-                            if firstTrack != nil {
-                                let layRoateInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)
-                                layRoateInstruction.setTransform(mixedTransform, at: CMTime.zero)
-                                roateInstruction.layerInstructions = [layRoateInstruction]
-                                videoComposition.instructions = [roateInstruction]
-                                avAssetExportSession?.videoComposition = videoComposition
-                            } else {
-                                BFLog(message: "firstTrack is error !!!")
-                            }
-                        }
-                        avAssetExportSession?.exportAsynchronously(completionHandler: {
-                            BFLog(message: "导出相册视频-progress = \(avAssetExportSession?.progress ?? 0),status = \(String(describing: avAssetExportSession?.status))")
-                            switch avAssetExportSession?.status {
-                            case .unknown:
-                                DispatchQueue.main.async {
-                                    resultHandler(phAsset, avAsset, nil, avAssetExportSession?.error?.localizedDescription)
-                                }
-                                avAssetExportSession?.cancelExport()
-                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-                                BFLog(message: "导出相册视频-发生未知错误:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-                            case .waiting:
-                                BFLog(message: "导出相册视频-等待导出mp4:\(filePath)")
-                            case .exporting:
-                                BFLog(message: "导出相册视频-导出相册视频中...:\(filePath)")
-                            case .completed:
-                                DispatchQueue.main.async {
-                                    resultHandler(phAsset, avAsset, filePath, nil)
-                                }
-                                avAssetExportSession?.cancelExport()
-                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-                                BFLog(message: "导出相册视频-导出完成:\(filePath)")
-                            case .failed:
-                                DispatchQueue.main.async {
-                                    resultHandler(phAsset, avAsset, nil, avAssetExportSession?.error?.localizedDescription)
-                                }
-                                avAssetExportSession?.cancelExport()
-                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-                                BFLog(message: "导出相册视频-导出失败:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-                            case .cancelled:
-                                DispatchQueue.main.async {
-                                    resultHandler(phAsset, avAsset, nil, avAssetExportSession?.error?.localizedDescription)
-                                }
-                                avAssetExportSession?.cancelExport()
-                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-                                BFLog(message: "导出相册视频-取消导出:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-                            default:
-                                break
-                            }
-                        })
-                    })
-                }
-            } else if avAsset is AVComposition {
-                BFLog(message: "导出相册视频-是AVComposition = \(String(describing: avAsset))")
-                let assetResources = PHAssetResource.assetResources(for: phAsset)
-                var resource: PHAssetResource?
-                for assetRes in assetResources {
-                    if assetRes.type == .video || assetRes.type == .pairedVideo {
-                        resource = assetRes
-                    }
-                }
-                if phAsset.mediaType == .video, resource != nil {
-                    let fileName = (resource?.originalFilename ?? "") + (resource?.assetLocalIdentifier ?? "") + (resource?.uniformTypeIdentifier ?? "")
-                    let filePath = photoLibraryDirectory + fileName.md5 + ".mp4"
-                    let data = try? Data(contentsOf: NSURL.fileURL(withPath: filePath))
-                    if FileManager.default.fileExists(atPath: filePath) && (data?.count ?? 0) > fileSize / 40 {
-                        DispatchQueue.main.async {
-                            resultHandler(phAsset, avAsset, filePath, nil)
-                        }
-                    } else {
-                        PHAssetResourceManager.default().writeData(for: resource!, toFile: URL(fileURLWithPath: filePath), options: nil) { error in
-                            DispatchQueue.main.async {
-                                resultHandler(phAsset, avAsset, error == nil ? filePath : nil, nil)
-                            }
-                        }
-                    }
-                } else {
-                    DispatchQueue.main.async {
-                        resultHandler(phAsset, avAsset, nil, nil)
-                    }
-                }
-            } else {
-                DispatchQueue.main.async {
-                    resultHandler(phAsset, avAsset, nil, nil)
-                }
-            }
-        }
-    }
-
-    /// PHAsset 转码为.mp4保存本地
-    /// - Parameters:
-    ///   - phAsset: <#phAsset description#>
-    ///   - isAdjustRotationAngle: 是否调整旋转角度
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func writePHAssetDataToMP4(phAsset: PHAsset, isAdjustRotationAngle _: Bool = true, isCancelCurrentExport: Bool = false, deliveryMode _: PHVideoRequestOptionsDeliveryMode? = .automatic, resultHandler: @escaping (_ phAsset: PHAsset, _ aVAsset: AVAsset?, _ filePath: String?, _ errorMsg: String?) -> Void) {
-        BFLog(message: "导出相册视频-开始导出:phAsset = \(phAsset)")
-        if isCancelCurrentExport {
-            currentExportSession?.cancelExport()
-        }
-        PQPHAssetVideoParaseUtil.parasToAVAsset(phAsset: phAsset) { avAsset, fileSize, _, _ in
-            if avAsset is AVURLAsset {
-                // 创建目录
-                createDirectory(path: photoLibraryDirectory)
-                let fileName = (avAsset as! AVURLAsset).url.absoluteString
-                let filePath = photoLibraryDirectory + fileName.md5 + ".mp4"
-                let data = try? Data(contentsOf: NSURL.fileURL(withPath: filePath))
-                if FileManager.default.fileExists(atPath: filePath) && (data?.count ?? 0) > fileSize / 40 {
-                    BFLog(message: "导出相册视频-已经导出完成:\(filePath)")
-                    DispatchQueue.main.async {
-                        resultHandler(phAsset, avAsset, filePath, nil)
-                    }
-                } else {
-                    let tempExportSession = PQSingletoMemoryUtil.shared.allExportSession[phAsset]
-                    if tempExportSession != nil {
-                        BFLog(message: "导出相册视频-正在导出")
-                        return
-                    }
-                    BFLog(message: "导出相册视频-未导出视频过,开始导出:phAsset = \(phAsset)")
-                    // 删除以创建地址
-                    if FileManager.default.fileExists(atPath: filePath) {
-                        do {
-                            try FileManager.default.removeItem(at: NSURL.fileURL(withPath: filePath))
-                        } catch {
-                            BFLog(message: "导出相册视频-error == \(error)")
-                        }
-                    }
-                    do {
-                        try FileManager.default.copyItem(at: (avAsset as! AVURLAsset).url, to: URL(fileURLWithPath: filePath))
-                    } catch {
-                        BFLog(message: "导出相册视频-error == \(error)")
-                    }
-
-//                    NSError *error;
-//                            AVURLAsset *avurlasset = (AVURLAsset*)asset;
-//                            NSURL *fileURL = [NSURL fileURLWithPath:savePath];
-//
-//                            if ([[NSFileManager defaultManager] copyItemAtURL:avurlasset.URL toURL:fileURL error:&error]) {
-//                                CBLog(@"保存成功");
-//                                dispatch_async(dispatch_get_main_queue(), ^{
-//                                    if (result) {
-//                                        result(savePath,[savePath lastPathComponent]);
-//                                    }
-//                                });
-//                            }else{
-//                                CBLog(@"error=%@",error);
-//                                [[NSFileManager defaultManager]removeItemAtPath:savePath error:nil];
-//                                dispatch_async(dispatch_get_main_queue(), ^{
-//                                    failure(error.description);
-//                                });
-//                            }
-//                    let requestOptions = PHVideoRequestOptions()
-//                    // 解决慢动作视频返回AVComposition而不是AVURLAsset
-//                    //        videoRequestOptions.version = .original
-//                    requestOptions.version = .current
-//                    // 下载iCloud视频
-//                    requestOptions.isNetworkAccessAllowed = false
-//                    requestOptions.progressHandler = { progress, error, pointer, info in
-//                        BFLog(message: "导出相册视频-progress = \(progress),error = \(String(describing: error)),pointer = \(pointer),info = \(String(describing: info))")
-//                    }
-//                    requestOptions.deliveryMode = deliveryMode ?? .automatic
-
-//                    PHImageManager.default().requestExportSession(forVideo: phAsset, options: requestOptions, exportPreset: (deliveryMode == .automatic || deliveryMode == .mediumQualityFormat) ? AVAssetExportPreset1920x1080 :(deliveryMode == .highQualityFormat ? AVAssetExportPresetHighestQuality : AVAssetExportPresetLowQuality) , resultHandler: { avAssetExportSession, _ in
-//                        BFLog(message: "导出相册视频-请求到导出 avAssetExportSession = \(avAssetExportSession)")
-//                        currentExportSession = avAssetExportSession
-//                        if avAssetExportSession != nil {
-//                            PQSingletoMemoryUtil.shared.allExportSession[phAsset] = avAssetExportSession!
-//                        }
-//                        avAssetExportSession?.outputURL = NSURL(fileURLWithPath: filePath) as URL
-//                        avAssetExportSession?.shouldOptimizeForNetworkUse = true
-//                        avAssetExportSession?.outputFileType = .mp4
-//                        if isAdjustRotationAngle {
-//                            let rotationAngle = PQPHAssetVideoParaseUtil.videoRotationAngle(assert: avAsset!)
-//                            // mdf by ak 统一导出的视频为30FPS
-//                            var centerTranslate: CGAffineTransform = CGAffineTransform(translationX: 0, y: 0)
-//                            var mixedTransform: CGAffineTransform = CGAffineTransform()
-//                            let videoComposition = AVMutableVideoComposition()
-//                            videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
-//                            let tracks = avAsset?.tracks(withMediaType: .video)
-//                            let firstTrack = tracks?.first
-//
-//                            videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.width ?? 0, height: firstTrack?.naturalSize.height ?? 0)
-//
-//                            mixedTransform = centerTranslate.rotated(by: 0)
-//
-//                            if rotationAngle == 90 {
-//                                centerTranslate = CGAffineTransform(translationX: firstTrack?.naturalSize.height ?? 0, y: 0)
-//                                mixedTransform = centerTranslate.rotated(by: .pi / 2)
-//                                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.height ?? 0, height: firstTrack?.naturalSize.width ?? 0)
-//                            } else if rotationAngle == 180 {
-//                                centerTranslate = CGAffineTransform(translationX: firstTrack?.naturalSize.width ?? 0, y: firstTrack?.naturalSize.height ?? 0)
-//                                mixedTransform = centerTranslate.rotated(by: .pi)
-//                                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.width ?? 0, height: firstTrack?.naturalSize.height ?? 0)
-//                            } else if rotationAngle == 270 {
-//                                centerTranslate = CGAffineTransform(translationX: 0, y: firstTrack?.naturalSize.width ?? 0)
-//                                mixedTransform = centerTranslate.rotated(by: .pi / 2 * 3)
-//                                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.height ?? 0, height: firstTrack?.naturalSize.width ?? 0)
-//                            }
-//                            let roateInstruction = AVMutableVideoCompositionInstruction()
-//                            roateInstruction.timeRange = CMTimeRange(start: CMTime.zero, end: avAsset?.duration ?? CMTime.zero)
-//                            if firstTrack != nil {
-//                                let layRoateInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)
-//                                layRoateInstruction.setTransform(mixedTransform, at: CMTime.zero)
-//                                roateInstruction.layerInstructions = [layRoateInstruction]
-//                                videoComposition.instructions = [roateInstruction]
-//                                avAssetExportSession?.videoComposition = videoComposition
-//                            } else {
-//                                BFLog(message: "firstTrack is error !!!")
-//                            }
-//                        }
-//                        avAssetExportSession?.shouldOptimizeForNetworkUse = true
-//                        avAssetExportSession?.exportAsynchronously(completionHandler: {
-//                            BFLog(message: "导出相册视频-progress = \(avAssetExportSession?.progress ?? 0),status = \(String(describing: avAssetExportSession?.status))")
-//                            switch avAssetExportSession?.status {
-//                            case .unknown:
-//                                DispatchQueue.main.async {
-//                                    resultHandler(phAsset, avAsset, nil, avAssetExportSession?.error?.localizedDescription)
-//                                }
-//                                avAssetExportSession?.cancelExport()
-//                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-//                                BFLog(message: "导出相册视频-发生未知错误:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-//                            case .waiting:
-//                                BFLog(message: "导出相册视频-等待导出mp4:\(filePath)")
-//                            case .exporting:
-//                                BFLog(message: "导出相册视频-导出相册视频中...:\(filePath)")
-//                            case .completed:
-//                                DispatchQueue.main.async {
-//                                    resultHandler(phAsset, avAsset, filePath, nil)
-//                                }
-//                                avAssetExportSession?.cancelExport()
-//                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-//                                BFLog(message: "导出相册视频-导出完成:\(filePath)")
-//                            case .failed:
-//                                DispatchQueue.main.async {
-//                                    resultHandler(phAsset, avAsset, nil, avAssetExportSession?.error?.localizedDescription)
-//                                }
-//                                avAssetExportSession?.cancelExport()
-//                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-//                                BFLog(message: "导出相册视频-导出失败:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-//                            case .cancelled:
-//                                DispatchQueue.main.async {
-//                                    resultHandler(phAsset, avAsset, nil, avAssetExportSession?.error?.localizedDescription)
-//                                }
-//                                avAssetExportSession?.cancelExport()
-//                                PQSingletoMemoryUtil.shared.allExportSession.removeValue(forKey: phAsset)
-//                                BFLog(message: "导出相册视频-取消导出:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-//                            default:
-//                                break
-//                            }
-//                        })
-//                    })
-                }
-            } else if avAsset is AVComposition {
-                BFLog(message: "导出相册视频-是AVComposition = \(String(describing: avAsset))")
-                let assetResources = PHAssetResource.assetResources(for: phAsset)
-                var resource: PHAssetResource?
-                for assetRes in assetResources {
-                    if assetRes.type == .video || assetRes.type == .pairedVideo {
-                        resource = assetRes
-                    }
-                }
-                if phAsset.mediaType == .video, resource != nil {
-                    let fileName = (resource?.originalFilename ?? "") + (resource?.assetLocalIdentifier ?? "") + (resource?.uniformTypeIdentifier ?? "")
-                    let filePath = photoLibraryDirectory + fileName.md5 + ".mp4"
-                    let data = try? Data(contentsOf: NSURL.fileURL(withPath: filePath))
-                    if FileManager.default.fileExists(atPath: filePath) && (data?.count ?? 0) > fileSize / 40 {
-                        DispatchQueue.main.async {
-                            resultHandler(phAsset, avAsset, filePath, nil)
-                        }
-                    } else {
-                        PHAssetResourceManager.default().writeData(for: resource!, toFile: URL(fileURLWithPath: filePath), options: nil) { error in
-                            DispatchQueue.main.async {
-                                resultHandler(phAsset, avAsset, error == nil ? filePath : nil, nil)
-                            }
-                        }
-                    }
-                } else {
-                    DispatchQueue.main.async {
-                        resultHandler(phAsset, avAsset, nil, nil)
-                    }
-                }
-            } else {
-                DispatchQueue.main.async {
-                    resultHandler(phAsset, avAsset, nil, nil)
-                }
-            }
-        }
-    }
-
-    /// 导出相册视频
-    /// - Parameters:
-    ///   - aVAsset: <#aVAsset description#>
-    ///   - isAdjustRotationAngle: <#isAdjustRotationAngle description#>
-    ///   - resultHandler: <#resultHandler description#>
-    public class func exportAVAssetToMP4(aVAsset: AVURLAsset, isAdjustRotationAngle: Bool = true, resultHandler: @escaping (_ aVAsset: AVURLAsset?, _ filePath: String?, _ errorMsg: String?) -> Void) {
-        currentExportSession?.cancelExport()
-        BFLog(message: "开始导出相册视频:url = \(aVAsset.url.absoluteString)")
-        // 创建目录
-        createDirectory(path: photoLibraryDirectory)
-        let fileName = aVAsset.url.absoluteString
-        let filePath = photoLibraryDirectory + fileName.md5 + ".mp4"
-        let data = try? Data(contentsOf: NSURL.fileURL(withPath: filePath))
-        let fileSize = try! aVAsset.url.resourceValues(forKeys: [.fileSizeKey]).fileSize ?? 0
-        if FileManager.default.fileExists(atPath: filePath) && (data?.count ?? 0) > fileSize / 40 {
-            DispatchQueue.main.async {
-                resultHandler(aVAsset, filePath, nil)
-            }
-        } else {
-            BFLog(message: "未导出视频过,开始导出:aVAsset = \(aVAsset)")
-            // 删除以创建地址
-            try? FileManager.default.removeItem(at: NSURL.fileURL(withPath: filePath))
-            let avAssetExportSession = AVAssetExportSession(asset: aVAsset, presetName: AVAssetExportPreset1280x720)
-            currentExportSession = avAssetExportSession
-            avAssetExportSession?.outputURL = NSURL(fileURLWithPath: filePath) as URL
-            avAssetExportSession?.shouldOptimizeForNetworkUse = false
-            avAssetExportSession?.outputFileType = .mp4
-            if isAdjustRotationAngle {
-                let rotationAngle = PQPHAssetVideoParaseUtil.videoRotationAngle(assert: aVAsset)
-                // mdf by ak 统一导出的视频为30FPS
-                var centerTranslate: CGAffineTransform = CGAffineTransform(translationX: 0, y: 0)
-                var mixedTransform: CGAffineTransform = CGAffineTransform()
-                let videoComposition = AVMutableVideoComposition()
-                videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
-                let tracks = aVAsset.tracks(withMediaType: .video)
-                let firstTrack = tracks.first
-                videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.width ?? 0, height: firstTrack?.naturalSize.height ?? 0)
-
-                mixedTransform = centerTranslate.rotated(by: 0)
-
-                if rotationAngle == 90 {
-                    centerTranslate = CGAffineTransform(translationX: firstTrack?.naturalSize.height ?? 0, y: 0)
-                    mixedTransform = centerTranslate.rotated(by: .pi / 2)
-                    videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.height ?? 0, height: firstTrack?.naturalSize.width ?? 0)
-                } else if rotationAngle == 180 {
-                    centerTranslate = CGAffineTransform(translationX: firstTrack?.naturalSize.width ?? 0, y: firstTrack?.naturalSize.height ?? 0)
-                    mixedTransform = centerTranslate.rotated(by: .pi)
-                    videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.width ?? 0, height: firstTrack?.naturalSize.height ?? 0)
-                } else if rotationAngle == 270 {
-                    centerTranslate = CGAffineTransform(translationX: 0, y: firstTrack?.naturalSize.width ?? 0)
-                    mixedTransform = centerTranslate.rotated(by: .pi / 2 * 3)
-                    videoComposition.renderSize = CGSize(width: firstTrack?.naturalSize.height ?? 0, height: firstTrack?.naturalSize.width ?? 0)
-                }
-                let roateInstruction = AVMutableVideoCompositionInstruction()
-                roateInstruction.timeRange = CMTimeRange(start: CMTime.zero, end: aVAsset.duration)
-                let layRoateInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)
-                layRoateInstruction.setTransform(mixedTransform, at: CMTime.zero)
-                roateInstruction.layerInstructions = [layRoateInstruction]
-                videoComposition.instructions = [roateInstruction]
-                avAssetExportSession?.videoComposition = videoComposition
-            }
-
-            avAssetExportSession?.shouldOptimizeForNetworkUse = true
-            avAssetExportSession?.exportAsynchronously(completionHandler: {
-                BFLog(message: "导出相册视频progress = \(avAssetExportSession?.progress ?? 0)")
-                switch avAssetExportSession?.status {
-                case .unknown:
-                    DispatchQueue.main.async {
-                        resultHandler(aVAsset, nil, avAssetExportSession?.error?.localizedDescription)
-                    }
-                    BFLog(message: "导出相册视频发生未知错误:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-                case .waiting:
-                    BFLog(message: "等待导出mp4:\(filePath)")
-                case .exporting:
-                    BFLog(message: "导出相册视频中...:\(filePath)")
-                case .completed:
-                    DispatchQueue.main.async {
-                        resultHandler(aVAsset, filePath, nil)
-                    }
-                    BFLog(message: "导出相册视频完成:\(filePath)")
-                case .failed:
-                    DispatchQueue.main.async {
-                        resultHandler(aVAsset, nil, avAssetExportSession?.error?.localizedDescription)
-                    }
-                    BFLog(message: "导出相册视频失败:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-                case .cancelled:
-                    DispatchQueue.main.async {
-                        resultHandler(aVAsset, nil, avAssetExportSession?.error?.localizedDescription)
-                    }
-                    BFLog(message: "取消导出相册视频:\(filePath),\(avAssetExportSession?.error?.localizedDescription ?? "")")
-                default:
-                    break
-                }
-            })
-        }
-    }
-
-    /// 获取视频资源的旋转角度
-    /// - Parameter assert: <#assert description#>
-    /// - Returns: <#description#>
-    public class func videoRotationAngle(assert: AVAsset) -> Int {
-        var rotationAngle: Int = 0
-
-        let tracks = assert.tracks(withMediaType: .video)
-        if tracks.count > 0 {
-            let firstTrack = tracks.first
-            let transform = firstTrack?.preferredTransform
-            if transform?.a == 0, transform?.b == 1.0, transform?.c == -1.0, transform?.d == 0 {
-                rotationAngle = 90
-            } else if transform?.a == -1.0, transform?.b == 0, transform?.c == 0, transform?.d == -1.0 {
-                rotationAngle = 180
-            } else if transform?.a == 0, transform?.b == -1.0, transform?.c == 1.0, transform?.d == 0 {
-                rotationAngle = 270
-            } else if transform?.a == 1.0, transform?.b == 0, transform?.c == 0, transform?.d == 1.0 {
-                rotationAngle = 0
-            }
-        }
-        return rotationAngle
-    }
-
-    /// 裁剪背景音乐并导出
-    /// - Parameters:
-    ///   - url: 原始地址
-    ///   - startTime: 开始时间
-    ///   - endTime: 结束时间
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func cutAudioToLocal(url: String, startTime: Float, endTime: Float, resultHandler: @escaping (_ url: String, _ filePath: String?, _ startTime: Float, _ endTime: Float, _ errorMsg: String?) -> Void) {
-        // 创建目录
-        createDirectory(path: bgMusicDirectory)
-        let filePath = bgMusicDirectory + url.md5 + ".mp3"
-        let data = try? Data(contentsOf: NSURL.fileURL(withPath: filePath))
-        if FileManager.default.fileExists(atPath: filePath) && (data?.count ?? 0) > 0 {
-            DispatchQueue.main.async {
-                resultHandler(url, filePath, startTime, endTime, nil)
-            }
-        } else {
-            // 删除以创建地址
-            try? FileManager.default.removeItem(at: NSURL.fileURL(withPath: filePath))
-            let audioAsset = AVURLAsset(url: URL(string: url)!)
-            audioAsset.loadValuesAsynchronously(forKeys: ["duration", "tracks"]) {
-                let status = audioAsset.statusOfValue(forKey: "tracks", error: nil)
-                switch status {
-                case .loaded: // 加载完成
-                    // AVAssetExportPresetPassthrough /AVAssetExportPresetAppleM4A
-                    let exportSession = AVAssetExportSession(asset: audioAsset, presetName: AVAssetExportPresetHighestQuality)
-                    exportSession?.outputURL = URL(fileURLWithPath: filePath)
-                    exportSession?.outputFileType = .mp3
-                    exportSession?.timeRange = CMTimeRange(start: CMTime(seconds: Double(startTime), preferredTimescale: 1000), end: CMTime(seconds: Double(endTime), preferredTimescale: 1000))
-                    exportSession?.exportAsynchronously(completionHandler: {
-                        switch exportSession?.status {
-                        case .waiting:
-                            BFLog(message: "等待导出mp3:\(filePath)")
-                        case .exporting:
-                            BFLog(message: "导出中...:\(filePath)")
-                        case .completed:
-                            DispatchQueue.main.async {
-                                resultHandler(url, filePath, startTime, endTime, nil)
-                            }
-                            BFLog(message: "导出完成:\(filePath)")
-
-                        case .cancelled, .failed, .unknown:
-                            DispatchQueue.main.async {
-                                resultHandler(url, nil, startTime, endTime, exportSession?.error?.localizedDescription)
-                            }
-                            BFLog(message: "导出失败:\(filePath),\(exportSession?.error?.localizedDescription ?? "")")
-                        default:
-                            break
-                        }
-                    })
-                case .loading:
-                    BFLog(message: "加载中...:\(url)")
-                case .failed, .cancelled, .unknown:
-                    DispatchQueue.main.async {
-                        resultHandler(url, nil, startTime, endTime, "导出失败")
-                    }
-                default:
-                    break
-                }
-            }
-        }
-    }
-
-    /// 创建本地保存地址
-    /// - Parameters:
-    ///   - sourceFilePath: <#sourceFilePath description#>
-    ///   - completeHandle: <#completeHandle description#>
-    /// - Returns: <#description#>
-    public class func createLocalFile(sourceFilePath: String, completeHandle: (_ isFileExists: Bool, _ isCreateSuccess: Bool, _ filePath: String) -> Void) {
-        let cLocalPath = NSString(string: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!).appendingPathComponent("\(sourceFilePath.md5).mp4")
-        if FileManager.default.fileExists(atPath: cLocalPath) {
-            BFLog(message: "文件已经存在:\(cLocalPath)")
-            completeHandle(true, false, cLocalPath)
-        } else {
-            let result = FileManager.default.createFile(atPath: cLocalPath, contents: nil, attributes: nil)
-            BFLog(message: "文件创建:\(cLocalPath),\(result)")
-            completeHandle(false, result, cLocalPath)
-        }
-    }
-
-    /// 获取图库图片
-    /// - Parameters:
-    ///   - asset: <#asset description#>
-    ///   - itemSize: <#itemSize description#>
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func requestAssetImage(asset: PHAsset, itemSize: CGSize, resultHandler: @escaping (UIImage?, [AnyHashable: Any]?) -> Void) {
-        PHCachingImageManager().requestImage(for: asset, targetSize: itemSize, contentMode: .aspectFill, options: imagesOptions, resultHandler: { image, info in
-            BFLog(message: "info = \(info ?? [:])")
-            if info?.keys.contains("PHImageResultIsDegradedKey") ?? false, "\(info?["PHImageResultIsDegradedKey"] ?? "0")" == "0" {
-                resultHandler(image, info)
-            }
-        })
-    }
-
-    /// 获取图库原图
-    /// - Parameters:
-    ///   - asset: <#asset description#>
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func requestAssetOringinImage(asset: PHAsset, resultHandler: @escaping (_ isGIF: Bool, _ data: Data?, UIImage?, [AnyHashable: Any]?) -> Void) {
-        PHCachingImageManager().requestImageData(for: asset, options: singleImageOptions) { data, _, _, info in
-            var image: UIImage?
-            if data != nil {
-                image = UIImage(data: data!)
-            }
-            if info?.keys.contains("PHImageFileUTIKey") ?? false, "\(info?["PHImageFileUTIKey"] ?? "")" == "com.compuserve.gif" {
-                resultHandler(true, data, image, info)
-            } else {
-                resultHandler(false, data, image, info)
-            }
-        }
-    }
-
-    /// 获取gif帧跟时长
-    /// - Parameters:
-    ///   - data: <#data description#>
-    ///   - isRenderingTemplate
-    ///   - resultHandler: <#resultHandler description#>
-    /// - Returns: <#description#>
-    public class func parasGIFImage(data: Data, isRenderingColor: UIColor? = nil, resultHandler: @escaping (_ data: Data, _ images: [UIImage]?, _ duration: Double?) -> Void) {
-        let info: [String: Any] = [
-            kCGImageSourceShouldCache as String: true,
-            kCGImageSourceTypeIdentifierHint as String: kUTTypeGIF,
-        ]
-        guard let imageSource = CGImageSourceCreateWithData(data as CFData, info as CFDictionary) else {
-            resultHandler(data, nil, nil)
-            BFLog(message: "获取gifimageSource 失败")
-            return
-        }
-        // 获取帧数
-        let frameCount = CGImageSourceGetCount(imageSource)
-        var gifDuration = 0.0
-        var images = [UIImage]()
-        for i in 0 ..< frameCount {
-            // 取出索引对应的图片
-            guard let imageRef = CGImageSourceCreateImageAtIndex(imageSource, i, info as CFDictionary) else {
-                BFLog(message: "取出对应的图片失败")
-                return
-            }
-            if frameCount == 1 {
-                // 单帧
-                gifDuration = .infinity
-            } else {
-                // 1.获取gif没帧的时间间隔
-                // 获取到该帧图片的属性字典
-                guard let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil) as? [String: Any] else {
-                    BFLog(message: "取出对应的图片属性失败")
-                    return
-                }
-                // 获取该帧图片中的GIF相关的属性字典
-                guard let gifInfo = properties[kCGImagePropertyGIFDictionary as String] as? [String: Any] else {
-                    BFLog(message: "取出对应的图片属性失败")
-                    return
-                }
-                let defaultFrameDuration = 0.1
-                // 获取该帧图片的播放时间
-                let unclampedDelayTime = gifInfo[kCGImagePropertyGIFUnclampedDelayTime as String] as? NSNumber
-                // 如果通过kCGImagePropertyGIFUnclampedDelayTime没有获取到播放时长,就通过kCGImagePropertyGIFDelayTime来获取,两者的含义是相同的;
-                let delayTime = gifInfo[kCGImagePropertyGIFDelayTime as String] as? NSNumber
-                let duration = unclampedDelayTime ?? delayTime
-                guard let frameDuration = duration else {
-                    BFLog(message: "获取帧时间间隔失败")
-                    return
-                }
-                // 对于播放时间低于0.011s的,重新指定时长为0.100s;
-                let gifFrameDuration = frameDuration.doubleValue > 0.011 ? frameDuration.doubleValue : defaultFrameDuration
-                // 计算总时间
-                gifDuration += gifFrameDuration
-                // 2.图片
-                var frameImage: UIImage? = UIImage(cgImage: imageRef, scale: 1.0, orientation: .up)
-                if isRenderingColor != nil {
-                    frameImage = frameImage?.tintImage(color: isRenderingColor!, blendMode: .destinationIn)
-                }
-                if frameImage != nil {
-                    images.append(frameImage!)
-                }
-            }
-        }
-        resultHandler(data, images, gifDuration)
-    }
-}

+ 1 - 0
BFFramework/Classes/BFModules/BFUtility/PQSingletoRealmUtil.swift

@@ -8,6 +8,7 @@
 
 import RealmSwift
 import UIKit
+import BFCommonKit
 
 public class PQSingletoRealmUtil: NSObject {
     public  var schemaVersion : UInt64 = 32

+ 1 - 0
BFFramework/Classes/BFModules/BFUtility/PQSingletoSourcesFileUtil.swift

@@ -8,6 +8,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 public class PQSingletoSourcesFileUtil: NSObject {
     static public let shared = PQSingletoSourcesFileUtil()

+ 46 - 11
BFFramework/Classes/BFModules/BFUtility/PQSingletoVideoPlayer.swift

@@ -8,6 +8,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 public class PQSingletoVideoPlayer: NSObject {
     public static let shared = PQSingletoVideoPlayer()
@@ -24,10 +25,12 @@ public class PQSingletoVideoPlayer: NSObject {
     /// 播放状态回调
     public var playStatusBloc: ((_ playStatus: PQVIDEO_PLAY_STATUS) -> Void)?
     public var playControllerView: UIView?
-    public var playVideoData: PQVideoListModel?
+    public var playVideoData: BFVideoItemProtocol?
     public var isPlaying: Bool {
         return player.isPlaying()
     }
+    public var autoResumePlayWhenEnterForeground:Bool = true
+    var shouldResumePlayWhenEnterForeground:Bool = false
 
     public lazy var player: TXVodPlayer = {
         let player = TXVodPlayer()
@@ -44,7 +47,10 @@ public class PQSingletoVideoPlayer: NSObject {
     /// - Parameters:
     ///   - videoData: <#videoData description#>
     ///   - controllerView: <#controllerView description#>
-    public func configPlyer(videoData: PQVideoListModel, controllerView: UIView, renderMode: TX_Enum_Type_RenderMode = .RENDER_MODE_FILL_SCREEN) {
+    public func configPlyer(videoData: BFVideoItemProtocol, controllerView: UIView, renderMode: TX_Enum_Type_RenderMode = .RENDER_MODE_FILL_SCREEN) {
+//        if playVideoData?.id == videoData.id {
+//            return
+//        }
         isPlayEnd = false
         isRealPlay = false
         isSemiRealPlay = false
@@ -60,8 +66,7 @@ public class PQSingletoVideoPlayer: NSObject {
         playControllerView = controllerView
         playVideoData = videoData
         if playVideoData!.playProgress >= 0.0 {
-            //
-            var progress: CGFloat = playVideoData!.playProgress
+            var progress: CGFloat = CGFloat(playVideoData!.playProgress)
             if progress > 5.0, progress < 20 {
                 progress = progress - 5.0
                 if progress <= 0 {
@@ -77,6 +82,11 @@ public class PQSingletoVideoPlayer: NSObject {
             PQSingletoMemoryUtil.shared.playCount = PQSingletoMemoryUtil.shared.playCount + 1
         }
     }
+    
+    public func reRenderView(newView: UIView) {
+        player.removeVideoWidget()
+        player.setupVideoWidget(newView, insert: 0)
+    }
 
     /// 重制播放
     public func resetPlayer() {
@@ -85,7 +95,7 @@ public class PQSingletoVideoPlayer: NSObject {
             player.setupVideoWidget(playControllerView, insert: 0)
             if playVideoData!.playProgress >= 0.0 {
                 //
-                var progress: CGFloat = playVideoData!.playProgress
+                var progress: CGFloat = CGFloat(playVideoData!.playProgress)
                 if progress > 5.0, progress < 20 {
                     progress = progress - 5.0
                     if progress <= 0 {
@@ -115,8 +125,11 @@ public class PQSingletoVideoPlayer: NSObject {
     }
 
     /// 继续播放
-    public func resumePlayer() {
+    public func resumePlayer(renderMode: TX_Enum_Type_RenderMode? = nil) {
         player.resume()
+        if renderMode != nil {
+            player.setRenderMode(renderMode!)
+        }
     }
 
     /// 停止播放
@@ -138,6 +151,24 @@ public class PQSingletoVideoPlayer: NSObject {
 
     override private init() {
         super.init()
+
+        NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { notice in
+            if self.isPlaying {
+                self.pausePlayer()
+                self.shouldResumePlayWhenEnterForeground = true
+            }
+        }
+        NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: nil) { notice in
+            
+            if self.autoResumePlayWhenEnterForeground && self.shouldResumePlayWhenEnterForeground {
+
+                self.shouldResumePlayWhenEnterForeground = false
+
+                self.resumePlayer()
+
+            }
+        }
+
     }
 
     override public func copy() -> Any {
@@ -183,7 +214,7 @@ extension PQSingletoVideoPlayer: TXVodPlayListener {
                     PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_realPlay, videoData: playVideoData, pageSource: nil, businessType: .bt_videoRealPlay, objectType: nil, extParams: nil, shareId: nil, videoIds: nil, playId: playId)
                 }
             }
-            playVideoData?.playProgress = CGFloat(playProgress)
+            playVideoData?.playProgress = Float64(playProgress)
             if progressBloc != nil {
                 progressBloc!(loadProgress, playProgress, duration)
             }
@@ -232,7 +263,7 @@ extension PQSingletoVideoPlayer: TXVodPlayListener {
             if !isPlayerError, playVideoData != nil {
                 isPlayerError = true
                 // 播放失败
-                PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Frontend, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayError, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": true, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
+                PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Action, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayError, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": true, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
             }
         case PLAY_ERR_FILE_NOT_FOUND.rawValue: // 播放文件不存在
             if playStatusBloc != nil {
@@ -241,22 +272,26 @@ extension PQSingletoVideoPlayer: TXVodPlayListener {
             if !isPlayerError, playVideoData != nil {
                 isPlayerError = true
                 // 播放失败
-                PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Frontend, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayError, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": false, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
+                PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Action, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayError, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": false, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
             }
         case PLAY_ERR_HEVC_DECODE_FAIL.rawValue, PLAY_ERR_HLS_KEY.rawValue, PLAY_ERR_GET_PLAYINFO_FAIL.rawValue, PLAY_WARNING_VIDEO_DECODE_FAIL.rawValue, PLAY_WARNING_AUDIO_DECODE_FAIL.rawValue: // H265解码失败,HLS解码key获取失败,获取点播文件信息失败,当前视频解码失败,当前音频解码失败
-
+            if playStatusBloc != nil {
+                playStatusBloc!(.PQVIDEO_PLAY_STATUS_FAUILE)
+            }
             if !isPlayerError, playVideoData != nil {
                 isPlayerError = true
                 // 播放失败
-                PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Frontend, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayError, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": false, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
+                PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Action, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayError, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": false, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
             }
         case PLAY_WARNING_RECONNECT.rawValue: // 断线重连已启动重新连接
             if playStatusBloc != nil {
                 playStatusBloc!(.PQVIDEO_PLAY_STATUS_RECONNECT)
             }
+            PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Action, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayException, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": true, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
         case PLAY_WARNING_RECV_DATA_LAG.rawValue, PLAY_WARNING_VIDEO_PLAY_LAG.rawValue: // 网络来包不稳:可能是下行带宽不足 | 当前视频播放出现卡顿(用户直观感受)
             // 播放失败
             PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Frontend, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlaySlow, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event, "position": player.currentPlaybackTime()], shareId: nil, videoIds: nil, playId: playId)
+            PQEventTrackViewModel.videoRelationReportUpload(reportLogType: .reportLogType_Action, videoData: playVideoData, pageSource: nil, businessType: .bt_videoPlayException, objectType: nil, extParams: ["pageSource": playVideoData!.pageSource.rawValue, "networkType": networkStatus(), "extra": "0", "hasRetry": true, "url": playVideoData?.videoPath ?? "", "videoId": playVideoData?.uniqueId ?? "0", "what": event], shareId: nil, videoIds: nil, playId: playId)
         default:
             break
         }

+ 0 - 95
BFFramework/Classes/BFModules/BFUtility/PQVideoSnapshotUtil.swift

@@ -1,95 +0,0 @@
-//
-//  PQVideoSnapshotUtil.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/8/14.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import AVFoundation
-import AVKit
-import UIKit
-
-public class PQVideoSnapshotUtil: NSObject {
-    /// AVPlayer截屏
-    /// - Parameter playerItem: <#playerItem description#>
-    /// - Returns: <#description#>
-    class public  func snapshotImage(avPlayer: AVPlayer, complateHandle: @escaping (_ image: UIImage?) -> Void) {
-        guard let playerItem = avPlayer.currentItem else { // playerItem is AVPlayerItem
-            complateHandle(nil)
-            return
-        }
-        let videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: nil)
-        playerItem.add(videoOutput)
-        let time = videoOutput.itemTime(forHostTime: CACurrentMediaTime())
-        if videoOutput.hasNewPixelBuffer(forItemTime: time) {
-            let lastSnapshotPixelBuffer = videoOutput.copyPixelBuffer(forItemTime: time, itemTimeForDisplay: nil)
-            if lastSnapshotPixelBuffer != nil {
-                let ciImage = CIImage(cvPixelBuffer: lastSnapshotPixelBuffer!)
-                let context = CIContext(options: nil)
-                let rect = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(CVPixelBufferGetWidth(lastSnapshotPixelBuffer!)), height: CGFloat(CVPixelBufferGetHeight(lastSnapshotPixelBuffer!)))
-                let cgImage = context.createCGImage(ciImage, from: rect)
-                if cgImage != nil {
-                    complateHandle(UIImage(cgImage: cgImage!))
-                    return
-                }
-            }
-        } else {
-            complateHandle(nil)
-        }
-    }
-
-    /// 非m3u8视频截屏
-    /// - Parameters:
-    ///   - videoURL: 视频地址
-    ///   - time: 视频某个时间点
-    /// - Returns: <#description#>
-    class public  func videoSnapshot(videoURL: URL, time: TimeInterval) -> UIImage? {
-        let asset = AVURLAsset(url: videoURL, options: avAssertOptions)
-        let assetImageGenerator = AVAssetImageGenerator(asset: asset)
-        assetImageGenerator.appliesPreferredTrackTransform = true
-        assetImageGenerator.requestedTimeToleranceBefore = CMTime.zero
-        assetImageGenerator.requestedTimeToleranceAfter = CMTime.zero
-        assetImageGenerator.apertureMode = .encodedPixels
-        let thumbnailCGImage: CGImage?
-        let thumbnailImageTime: CFTimeInterval = time
-        var thumbnailImage: UIImage?
-        do {
-            thumbnailCGImage = try assetImageGenerator.copyCGImage(at: CMTimeMake(value: Int64(thumbnailImageTime), timescale: 1), actualTime: nil)
-            if let cgImage = thumbnailCGImage {
-                thumbnailImage = UIImage(cgImage: cgImage)
-            }
-        } catch {}
-        return thumbnailImage
-    }
-
-    /// 获取非m3u8多张视频截图
-    /// - Parameters:
-    ///   - videoURL: 视频地址
-    ///   - duration: 视频时长
-    ///   - count: 截取数量
-    /// - Returns: <#description#>
-    class public  func videoSnapshot(videoURL: URL, duration: TimeInterval, count: Int, complateHandle: @escaping ([UIImage]?) -> Void) {
-        DispatchQueue.global().async {
-            var images: [UIImage]? = Array()
-            let asset = AVURLAsset(url: videoURL, options: avAssertOptions)
-            let assetImageGenerator = AVAssetImageGenerator(asset: asset)
-            assetImageGenerator.requestedTimeToleranceBefore = CMTime.zero
-            assetImageGenerator.requestedTimeToleranceAfter = CMTime.zero
-            assetImageGenerator.appliesPreferredTrackTransform = true
-            assetImageGenerator.apertureMode = .encodedPixels
-            for index in 0...count - 1 {
-                let thumbnailCGImage: CGImage?
-                let thumbnailImageTime: CFTimeInterval = ((duration / Double(count)) * Double(index))
-                BFLog(message: "截取视频时长 =(\(videoURL),duration = \(duration),count = \(count),line = \(thumbnailImageTime)")
-                do {
-                    thumbnailCGImage = try assetImageGenerator.copyCGImage(at: CMTimeMake(value: Int64(thumbnailImageTime), timescale: 1), actualTime: nil)
-                    if let cgImage = thumbnailCGImage {
-                        images?.append(UIImage(cgImage: cgImage))
-                    }
-                } catch {}
-            }
-            complateHandle(images)
-        }
-    }
-}

+ 0 - 48
BFFramework/Classes/BFModules/BFUtility/PQWeakTimer.swift

@@ -1,48 +0,0 @@
-//
-//  PQWeakTimer.swift
-//  PQSpeed
-//
-//  Created by lieyunye on 2020/6/18.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import Foundation
-
-public class PQWeakTimer {
-     public weak var timer: Timer?
-    public weak var target: AnyObject?
-    public let action: (Timer) -> Void
-
-    public init(timeInterval: TimeInterval,
-                 target: AnyObject,
-                 repeats: Bool,
-                 action: @escaping (Timer) -> Void)
-    {
-        self.target = target
-        self.action = action
-        timer = Timer.scheduledTimer(timeInterval: timeInterval,
-                                     target: self,
-                                     selector: #selector(fire),
-                                     userInfo: nil,
-                                     repeats: repeats)
-    }
-
-    public class func scheduledTimer(timeInterval: TimeInterval,
-                              target: AnyObject,
-                              repeats: Bool,
-                              action: @escaping (Timer) -> Void) -> Timer
-    {
-        return PQWeakTimer(timeInterval: timeInterval,
-                           target: target,
-                           repeats: repeats,
-                           action: action).timer!
-    }
-
-    @objc public func fire(timer: Timer) {
-        if target != nil {
-            action(timer)
-        } else {
-            timer.invalidate()
-        }
-    }
-}

+ 0 - 156
BFFramework/Classes/BFModules/BFUtility/SWNetRequest.swift

@@ -1,156 +0,0 @@
-//
-//  SWNetRequest.swift
-//  LiteraryHeaven
-//
-//  Created by SanW on 2017/8/2.
-//  Copyright © 2017年 ONON. All rights reserved.
-//
-
-import Alamofire
-import UIKit
-
-// 默认超时时间
-public let timeoutInterval: TimeInterval = 30
-
-// MARK: - 错误
-
-/// 错误
-public struct PQError: Error {
-    public var msg: String? // 提示信息
-    public var code: Int // 错误吗
-
-    init(msg: String?, code: Int = 0) {
-        self.msg = msg
-        self.code = code
-    }
-
-    public var localizedDescription: String {
-        return msg ?? ""
-    }
-}
-
-// MARK: - 网络请求
-
-/// 网络请求
-public class SWNetRequest: NSObject {
-    static let sessionManager: Alamofire.SessionManager = {
-        let configuration = URLSessionConfiguration.default
-        configuration.timeoutIntervalForRequest = timeoutInterval
-        return Alamofire.SessionManager(configuration: configuration)
-    }()
-
-    static let reTrySessionManager: Alamofire.SessionManager = {
-        let configuration = URLSessionConfiguration.default
-        configuration.timeoutIntervalForRequest = 5
-        return Alamofire.SessionManager(configuration: configuration)
-    }()
-
-    /// 回调方法
-    public typealias completeHander = (_ responseobject: Any?, _ extData: [String: Any]?, _ error: PQError?, _ timeline: Timeline) -> Void
-    /// get请求
-    public class func getRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
-        requestData(method: .get, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, extData, error, timeline in
-            response(responseObject, extData, error, timeline)
-        }
-    }
-
-    /// post请求
-    public class func postRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
-        requestData(method: .post, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, extData, error, timeline in
-            response(responseObject, extData, error, timeline)
-        }
-    }
-
-    /// 发送head请求
-    /// - Parameter url: <#url description#>
-    /// - Returns: <#description#>
-    class public func headRequestData(url: String, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) {
-        BFLog(message: "发起head请求 = \(url)")
-        if !isValidURL(url: url) {
-            completionHandler(nil, nil, PQError(msg: "url错误", code: 1001))
-            return
-        }
-        // http://www.mxfjx.com/uploadfiles/2014/4/小鸡%20鸡蛋%20蛋生鸡%20鸡生蛋_conew1.gif
-        url.urlEncoded()
-        let reqUrl = URL(string: url)!
-        var request = URLRequest(url: reqUrl)
-        request.timeoutInterval = 1 // 设置超时1s
-        request.httpMethod = "HEAD"
-        let session = URLSession.shared
-        let headTask = session.dataTask(with: request) { data, response, error in
-            completionHandler(data, response, error)
-            BFLog(message: "head请求返回 = \(url),code = \((response as? HTTPURLResponse)?.statusCode ?? 0),response = \(String(describing: response))")
-        }
-        headTask.resume()
-    }
-
-    /// put请求
-    public class func putRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
-        requestData(method: .put, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, extData, error, timeline in
-            response(responseObject, extData, error, timeline)
-        }
-    }
-
-    /// delete请求
-    public class func deleteRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
-        requestData(method: .delete, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, extData, error, timeline in
-            response(responseObject, extData, error, timeline)
-        }
-    }
-
-    /// 网络请求
-    fileprivate class func requestData(method: HTTPMethod, encoding: ParameterEncoding, url: String, parames: [String: Any]?, timeoutInterval _: TimeInterval = timeoutInterval, response: @escaping completeHander) {
-        var requestParams: [String: Any] = Dictionary<String, Any>.init()
-        if encoding is JSONEncoding, !url.hasSuffix(searchMaterialUrl), !url.hasSuffix(searchRecommendMaterialUrl), !url.hasSuffix(datashowAllowUrl),!url.hasSuffix(searchBGMMaterialUrl) {
-            requestParams["baseInfo"] = commonParams()
-            requestParams["params"] = parames
-        } else {
-            requestParams = commonParams()
-            if parames != nil, parames?.count ?? 0 > 0 {
-                if parames?.keys.contains("abInfoData") ?? false, "\(parames?["abInfoData"] ?? "")".count > 0, "\(parames?["abInfoData"] ?? "")" != "{}" {
-                    requestParams.removeValue(forKey: "abInfoData")
-                }
-                for (key, value) in parames!.reversed() {
-                    requestParams[key] = value
-                }
-            }
-        }
-        BFLog(message: "发起请求:\(url),params:\(requestParams)")
-        (timeoutInterval <= 5 ? reTrySessionManager : sessionManager).request(url, method: method, parameters: requestParams, encoding: encoding, headers: nil).responseJSON { jsonResponse in
-            BFLog(message: "jsonResponse = \(jsonResponse.timeline)")
-            /// 返回值
-            if jsonResponse.result.isSuccess {
-                let respondDict: [String: Any] = try! JSONSerialization.jsonObject(with: jsonResponse.data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: Any]
-                BFLog(message: "请求成功:\(url),respond:\(respondDict)")
-                if respondDict.keys.contains("code") && "\(respondDict["code"] ?? "")" == "0" && respondDict.keys.contains("data") {
-                    let extData = respondDict["extData"] as? [String: Any]
-                    if extData != nil && (extData?.keys.contains("abInfoData") ?? false) {
-                        PQSingletoMemoryUtil.shared.parasABinfoData(abInfo: extData?["abInfoData"] as? String)
-                    }
-                    response(respondDict["data"], extData, nil, jsonResponse.timeline)
-                } else if (respondDict.keys.contains("msg") && "\(respondDict["msg"] ?? "")".count > 0) || (respondDict.keys.contains("message") && "\(respondDict["message"] ?? "")".count > 0) {
-                    response(respondDict["data"], nil, PQError(msg: "\(respondDict["msg"] ?? "")", code: Int("\(respondDict["code"] ?? "")") ?? 10001), jsonResponse.timeline)
-                } else {
-                    response(nil, nil, PQError(msg: jsonResponse.result.error?.localizedDescription, code: 10001), jsonResponse.timeline)
-                }
-            } else {
-                BFLog(message: "请求失败:\(url),error:\(jsonResponse.result.error?.localizedDescription ?? "")")
-                let code: Int? = (jsonResponse.result.error as NSError?)?.code
-                response(nil, nil, PQError(msg: (code == -1009 || code == -1001) ? "网络不可用" : jsonResponse.result.error?.localizedDescription, code: code ?? 10001), jsonResponse.timeline)
-            }
-        }
-    }
-
-    /// 取消网络请求
-    /// - Parameter url: 某一个地址,空则取消所有
-    /// - Returns: <#description#>
-    public class func cancelTask(url: String?) {
-        sessionManager.session.getAllTasks(completionHandler: { tasks in
-            tasks.forEach { task in
-                if task.currentRequest?.url?.absoluteString == url {
-                    task.cancel()
-                }
-            }
-        })
-    }
-}

+ 0 - 184
BFFramework/Classes/Base/Controller/PQBaseWebViewController.swift

@@ -1,184 +0,0 @@
-
-//
-//  PQBaseWebViewController.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/5/27.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import UIKit
-import WebKit
-
-open class PQBaseWebViewController: PQBaseViewController {
-   public var emptyData: PQEmptyModel? = {
-        let emptyData = PQEmptyModel()
-        emptyData.title = "网页加载失败,请重试~"
-        emptyData.emptyImage = "pic_network"
-        return emptyData
-    }()
-
-    lazy public var webView: WKWebView = {
-        let config: WKWebViewConfiguration = WKWebViewConfiguration()
-        config.allowsInlineMediaPlayback = true
-        let webView: WKWebView = WKWebView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei), configuration: config)
-        webView.backgroundColor = UIColor.white
-        if #available(iOS 11.0, *) {
-            webView.scrollView.contentInsetAdjustmentBehavior = .never
-        } else {
-            automaticallyAdjustsScrollViewInsets = false
-        }
-        webView.navigationDelegate = self
-        return webView
-    }()
-
-    lazy public var progresslayer: CALayer = {
-        let progresslayer = CALayer()
-        progresslayer.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth * 0.1, height: 2)
-        progresslayer.backgroundColor = UIColor.hexColor(hexadecimal: "#FF9500").cgColor
-        return progresslayer
-    }()
-
-    @objc public var baseUrl: String? {
-        didSet {
-            if baseUrl != nil, baseUrl?.count ?? 0 > 0 {
-                webView.load(URLRequest(url: NSURL(string: baseUrl ?? "")! as URL, cachePolicy: .reloadIgnoringCacheData))
-                // 添加属性监听
-                webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
-                isAddObserve = true
-                view.layer.addSublayer(progresslayer)
-            }
-        }
-    }
-
-    @objc public var baseTitle: String?
-    public var evaluateJavaScript: String? // 交互
-    var isAddObserve: Bool = false
-    override open func viewDidLoad() {
-        super.viewDidLoad()
-        // Do any additional setup after loading the view.
-        view.addSubview(webView)
-        leftButton(image: "icon_blanc_back")
-        navHeadImageView?.backgroundColor = UIColor.white
-    }
-
-    override public func viewWillAppear(_ animated: Bool) {
-        super.viewWillAppear(animated)
-        if (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag)) != nil {
-            (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag))?.isHidden = true
-        }
-    }
-
-    override public func viewWillDisappear(_ animated: Bool) {
-        super.viewWillDisappear(animated)
-        if (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag)) != nil {
-            (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag))?.isHidden = false
-        }
-    }
-
-    deinit {
-        if isAddObserve {
-            webView.removeObserver(self, forKeyPath: "estimatedProgress")
-        }
-    }
-}
-
-extension PQBaseWebViewController: WKNavigationDelegate {
-   public func refreshClick() {
-        if baseUrl != nil, baseUrl?.count ?? 0 > 0 {
-            webView.load(URLRequest(url: NSURL(string: baseUrl ?? "")! as URL, cachePolicy: .useProtocolCachePolicy))
-        }
-    }
-
-    @objc public func back() {
-        if webView.canGoBack {
-            webView.goBack()
-        } else if navigationController != nil {
-            navigationController?.popViewController(animated: true)
-        } else {
-            dismiss(animated: true, completion: nil)
-        }
-    }
-
-    override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
-        if keyPath == "estimatedProgress" {
-            progresslayer.opacity = 1
-            let float = (change?[NSKeyValueChangeKey.newKey] as! NSNumber).floatValue
-            progresslayer.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth * CGFloat(float), height: 3)
-            if float == 1 {
-                weak var weakself = self
-                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
-                    weakself?.progresslayer.opacity = 0
-                }
-                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.8) {
-                    weakself?.progresslayer.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: 0, height: 3)
-                }
-            }
-        } else {
-            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
-        }
-    }
-
-    public func webView(_ webView: WKWebView, didFinish _: WKNavigation!) {
-        if baseTitle == nil || baseTitle?.count ?? 0 <= 0 {
-            webView.evaluateJavaScript("document.title") { [weak self] (any, _) -> Void in
-                self?.setTitle(title: any as? String)
-                self?.baseTitle = any as? String
-            }
-        }
-        if evaluateJavaScript != nil, (evaluateJavaScript?.count ?? 0) > 0 {
-            webView.evaluateJavaScript(evaluateJavaScript!) { _, _ in
-            }
-        }
-    }
-
-    public func webView(_ webView: WKWebView, didFail _: WKNavigation!, withError error: Error) {
-        BFLog(message: error)
-        if baseTitle == nil || baseTitle?.count ?? 0 <= 0 {
-            webView.evaluateJavaScript("document.title") { [weak self] (any, _) -> Void in
-                self?.setTitle(title: any as? String)
-                self?.baseTitle = any as? String
-            }
-        }
-    }
-
-    public func webView(_: WKWebView, didFailProvisionalNavigation _: WKNavigation!, withError _: Error) {}
-
-    public func webView(_: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
-        BFLog(message: "navigationResponse:\(String(describing: navigationResponse))")
-        decisionHandler(.allow)
-    }
-
-    public func webView(_: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
-        BFLog(message: "didStartProvisionalNavigation:\(String(describing: navigation))")
-    }
-
-    public func webView(_: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
-        BFLog(message: "didReceiveServerRedirectForProvisionalNavigation:\(String(describing: navigation))")
-    }
-
-    public func webView(_: WKWebView, didCommit navigation: WKNavigation!) {
-        BFLog(message: "\(String(describing: navigation))")
-    }
-
-//    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
-//        let url : String = navigationAction.request.url?.absoluteString ?? "";
-//        if(url.count == 0 || url == "about:blank"){
-//            decisionHandler(.cancel)
-//            return
-//        }
-//        let vc = PQBaseWebViewController.init()
-//        vc.baseUrl = url
-//        navigationController?.pushViewController(vc, animated: true)
-//        BFLog(message: "decidePolicyFor \(String(describing: navigationAction))")
-//        decisionHandler(.allow)
-//    }
-    override public var preferredStatusBarStyle: UIStatusBarStyle {
-        if #available(iOS 13.0, *) {
-            return .darkContent
-        } else {
-            // Fallback on earlier versions
-            return .default
-        }
-    }
-}

+ 0 - 46
BFFramework/Classes/Base/Controller/PQNavigatinController.swift

@@ -1,46 +0,0 @@
-//
-//  PQNavigatinController.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/5/25.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import UIKit
-
-open class PQNavigatinController: UINavigationController, UIGestureRecognizerDelegate {
-    public var isPop: Bool = false
-
-   open  override func viewDidLoad() {
-        super.viewDidLoad()
-
-        // Do any additional setup after loading the view.
-    }
-
-   open override func pushViewController(_ viewController: UIViewController, animated _: Bool) {
-        if viewControllers.count > 0 {
-            viewController.hidesBottomBarWhenPushed = true
-        }
-        super.pushViewController(viewController, animated: true)
-    }
-
-   public func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
-        return topViewController!.supportedInterfaceOrientations
-    }
-
-   public func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
-        return topViewController!.preferredInterfaceOrientationForPresentation
-    }
-
-   open override var childForStatusBarStyle: UIViewController? {
-        return topViewController
-    }
-
-   open override var childForStatusBarHidden: UIViewController? {
-        return topViewController
-    }
-
-   public func gestureRecognizerShouldBegin(_: UIGestureRecognizer) -> Bool {
-        return viewControllers.count > 1
-    }
-}

+ 0 - 189
BFFramework/Classes/Base/Model/PQBaseModel.swift

@@ -1,189 +0,0 @@
-//
-//  PQBaseModel.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/5/25.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import RealmSwift
-import UIKit
-
-open class PQBaseModel: Object {
-    @objc dynamic public var uniqueId: String? // 唯一ID
-    @objc dynamic public var videoId: Int = 0 // 视频ID
-    @objc dynamic public var eventId: String? // 事件ID
-    @objc dynamic public var title: String? // 标题
-    @objc dynamic public var attributedTitle: NSMutableAttributedString? // 富文本标题
-    @objc dynamic public var summary: String? // 描述
-    @objc dynamic public var imageUrl: String = "" // 图片地址
-    @objc dynamic public var selectedImage: String = "" // 图片地址
-    @objc dynamic public var isSelected: Bool = false
-    @objc dynamic public var recommendLogVO: String? // 推荐日志对象
-    @objc dynamic public var abInfoData: String? // AB
-    @objc dynamic public var pageCategoryId: Int = 0 // 页面分类ID
-    @objc dynamic public var version: String = versionName // 版本号
-    @objc dynamic public var mid = getMachineCode() // 设备ID
-    @objc dynamic public var date: Int = 0 // 当前时间戳  CGFloat(Date.init().timeIntervalSince1970) * 1000
-    @objc dynamic public var itemWidth: Float = 0 // cell宽
-    @objc dynamic public var primaryKeys: String? // 区分存储唯一值
-    override class public func primaryKey() -> String? {
-        return "uniqueId"
-    }
-
-    public override required  init() {
-        super.init()
-        uniqueId = getUniqueId(desc: "uniqueId")
-    }
-
-    override class open func ignoredProperties() -> [String] {
-        return ["attributedTitle"]
-    }
-
-    @objc func toString() -> String {
-        var json: [String: Any] = [
-            "version": version,
-            "mid": mid,
-            "pageCategoryId": pageCategoryId,
-            "selectedImage": selectedImage,
-            "isSelected": isSelected,
-            "imageUrl": imageUrl,
-        ]
-        if uniqueId != nil {
-            json["uniqueId"] = uniqueId
-            json["videoId"] = videoId
-        }
-        if eventId != nil {
-            json["eventId"] = eventId
-        }
-        if title != nil {
-            json["title"] = title
-        }
-        if summary != nil {
-            json["summary"] = summary
-        }
-        if recommendLogVO != nil {
-            json["recommendLogVO"] = recommendLogVO
-        }
-        return dictionaryToJsonString(json) ?? ""
-    }
-
-    public init(jsonDict: [String: Any]) {
-        super.init()
-        if jsonDict.keys.contains("id") {
-            uniqueId = "\(jsonDict["id"] ?? "")"
-            videoId = Int(uniqueId ?? "0") ?? 0
-        }
-        if jsonDict.keys.contains("uniqueId") {
-            uniqueId = "\(jsonDict["uniqueId"] ?? "")"
-            videoId = Int(uniqueId ?? "0") ?? 0
-        }
-        if jsonDict.keys.contains("eventId") {
-            eventId = "\(jsonDict["eventId"] ?? "")"
-        }
-        if jsonDict.keys.contains("title") {
-            title = "\(jsonDict["title"] ?? "")"
-        }
-        if jsonDict.keys.contains("summary") {
-            summary = "\(jsonDict["summary"] ?? "")"
-        }
-        if jsonDict.keys.contains("imageUrl") {
-            imageUrl = "\(jsonDict["imageUrl"] ?? "")"
-        }
-        if jsonDict.keys.contains("selectedImage") {
-            selectedImage = "\(jsonDict["selectedImage"] ?? "")"
-        }
-        if jsonDict.keys.contains("isSelected") {
-            isSelected = jsonDict["isSelected"] as! Bool
-        }
-        if jsonDict.keys.contains("recommendLogVO") {
-            recommendLogVO = "\(jsonDict["recommendLogVO"] ?? "")"
-        }
-        if jsonDict.keys.contains("pageCategoryId") {
-            pageCategoryId = Int("\(jsonDict["pageCategoryId"] ?? "0")") ?? 0
-        }
-        if jsonDict.keys.contains("version") {
-            version = "\(jsonDict["version"] ?? "")"
-        }
-        if jsonDict.keys.contains("mid") {
-            mid = "\(jsonDict["mid"] ?? "")"
-        }
-    }
-}
-
-// MARK: - 当前应用本地存储的model
-
-/// 当前应用本地存储的model
-public  class PQLocalStoreModel: PQBaseModel {
-    @objc dynamic public var currentDate: String?
-    @objc required init() {
-        super.init()
-        currentDate = systemCurrentDate()
-    }
-}
-
-// MARK: - oss上传model
-
-/// oss上传model
-public class PQOssUploadModel: NSObject {
-    public var accessKeyId: String?
-    public var secretKeyId: String?
-    public var securityToken: String?
-    public var endpoint: String?
-    public var endpoints: [String]?
-    public var bucketName: String?
-    public var fileName: String?
-    public var uploadID: String?
-    public var expiration: String? // 过期时间
-    public init(jsonDict: [String: Any]) {
-        super.init()
-
-        if jsonDict.keys.contains("AccessKeyId") {
-            accessKeyId = "\(jsonDict["AccessKeyId"] ?? "")"
-        }
-        if jsonDict.keys.contains("AccessKeySecret") {
-            secretKeyId = "\(jsonDict["AccessKeySecret"] ?? "")"
-        }
-        if jsonDict.keys.contains("SecurityToken") {
-            securityToken = "\(jsonDict["SecurityToken"] ?? "")"
-        }
-        if jsonDict.keys.contains("Hosts") {
-            endpoints = jsonDict["Hosts"] as? [String]
-        }
-        if jsonDict.keys.contains("Host") {
-            endpoint = "\(jsonDict["Host"] ?? "")"
-            if endpoint != nil {
-                if endpoints == nil {
-                    endpoints = [endpoint!]
-                } else {
-                    endpoints?.append(endpoint!)
-                }
-            }
-        }
-        if jsonDict.keys.contains("Bucket") {
-            bucketName = "\(jsonDict["Bucket"] ?? "")"
-        }
-        if jsonDict.keys.contains("FileName") {
-            fileName = "\(jsonDict["FileName"] ?? "")"
-        }
-        if jsonDict.keys.contains("Upload") {
-            uploadID = "\(jsonDict["Upload"] ?? "")"
-        }
-        if jsonDict.keys.contains("Expiration") {
-            expiration = "\(jsonDict["Expiration"] ?? "")"
-        }
-    }
-}
-
-// MARK: - 空白页面model
-
-/// 空白页面model
-public class PQEmptyModel: NSObject {
-    public var title: String? // 标题
-    public var summary: String? // 描述
-    public var emptyImage: String? // 空白提示图
-    public var isRefreshHidden: Bool = true // 是否隐藏刷新按钮
-    public var refreshImage: String? // 刷新按钮图片
-    public var refreshTitle: NSMutableAttributedString? // 刷新按钮文字
-    public var refreshBgColor: UIColor? // 刷新按钮背景颜色
-}

+ 2 - 1
BFFramework/Classes/Base/View/PQActivityIndicatorView.swift

@@ -7,7 +7,8 @@
 //  功能: 显示 UIActivityIndicatorView
 
 import UIKit
-
+import BFCommonKit
+ 
 class PQActivityIndicatorView: UIView {
     func showHud(isCovered: Bool = false) {
         hideHud()

+ 2 - 1
BFFramework/Classes/Base/View/PQAssetCategoryCell.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 public class PQAssetCategoryCell: UICollectionViewCell {
     public var representedAssetIdentifier: String!
@@ -34,7 +35,7 @@ public class PQAssetCategoryCell: UICollectionViewCell {
     lazy public var seleImage: UIImageView = {
         let seleImage = UIImageView()
         seleImage.tintColor = PQBFConfig.shared.styleTitleColor
-        seleImage.image = UIImage.init().BF_Image(named:  "icon_uploadVideo_do").withRenderingMode(.alwaysTemplate)
+        seleImage.image = UIImage.moduleImage(named: "icon_uploadVideo_do", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate)
         seleImage.isHidden = true
         return seleImage
     }()

+ 4 - 3
BFFramework/Classes/Base/View/PQBaseVideoInfoView.swift

@@ -7,17 +7,18 @@
 //
 
 import UIKit
+import BFCommonKit
 
 open class PQBaseVideoInfoView: UIView {
     lazy public var imageView: UIImageView = {
-        let imageView = UIImageView(image: UIImage.init().BF_Image(named:  "msg_default"))
+        let imageView = UIImageView(image:UIImage.moduleImage(named: "msg_default", moduleName: "BFFramework",isAssets: false))
         imageView.addCorner(corner: 4)
         imageView.contentMode = .scaleAspectFill
         return imageView
     }()
 
     lazy public var videoTagView: UIImageView = {
-        let videoTagView = UIImageView(image: UIImage.init().BF_Image(named:  "msg_video_tag"))
+        let videoTagView = UIImageView(image:UIImage.moduleImage(named: "msg_video_tag", moduleName: "BFFramework",isAssets: false))
         return videoTagView
     }()
 
@@ -51,7 +52,7 @@ open class PQBaseVideoInfoView: UIView {
    open func addData() {
         // 这里会crash
         let coverImg = (videoData?.videoCoverSnapshotPath != nil && (videoData?.videoCoverSnapshotPath?.count ?? 0) > 0) ? videoData?.videoCoverSnapshotPath ?? "" : (videoData?.coverImg?["coverImgPath"] as? String ?? "")
-        imageView.setNetImage(url: coverImg, placeholder: UIImage.init().BF_Image(named: "msg_default"))
+    imageView.setNetImage(url: coverImg, placeholder: UIImage.moduleImage(named: "msg_default", moduleName: "BFFramework",isAssets: false)!)
         titleLab.text = videoData?.title
     }
 

+ 0 - 254
BFFramework/Classes/Base/View/PQChoseMaterialCell.swift

@@ -1,254 +0,0 @@
-//
-//  PQPQChoseMaterialCell.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/8/28.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import Kingfisher
-import UIKit
-import Photos
-
-public class PQChoseMaterialCell: UICollectionViewCell {
-    // 是否显示素材标识
-    public var isShowMediaTag: Bool = true
-    // 是否是已经添加过的
-    public var isAdded: Bool = false
-    public var representedAssetIdentifier: String!
-    public var materialClicHandle: ((_ sender: UIButton, _ materialData: PQEditVisionTrackMaterialsModel?) -> Void)?
-
-    lazy public var materialImageView: AnimatedImageView = {
-        let materialImageView = AnimatedImageView()
-        materialImageView.contentMode = .scaleAspectFill
-        materialImageView.isUserInteractionEnabled = true
-        materialImageView.clipsToBounds = true
-        return materialImageView
-    }()
-
-    lazy public var borderView: UIView = {
-        let borderView = UIView()
-        borderView.layer.borderColor = UIColor.hexColor(hexadecimal: "#333333").cgColor
-        borderView.layer.borderWidth = 1.5
-        return borderView
-    }()
-
-    lazy public var statusLab: UILabel = {
-        let statusLab = UILabel()
-        statusLab.textColor = UIColor.white
-        statusLab.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7)
-        statusLab.font = UIFont.systemFont(ofSize: 11)
-        statusLab.text = "GIF"
-        statusLab.addCorner(corner: 3)
-        return statusLab
-    }()
-
-    lazy public var videoStatuImageView: UIImageView = {
-        let videoStatuImageView = UIImageView(image: UIImage.init().BF_Image(named:  "allPreview"))
-        return videoStatuImageView
-    }()
-
-    lazy public var videoLoadingView: AnimatedImageView = {
-        let videoLoadingView = AnimatedImageView()
-        videoLoadingView.kf.setImage(with: URL(fileURLWithPath:  Bundle.init().BF_mainbundle().path(forResource: "material_loading", ofType: ".gif")!))
-        videoLoadingView.stopAnimating()
-        return videoLoadingView
-    }()
-
-    lazy public var choseContentView: UIView = {
-        let choseContentView = UIView()
-        let ges = UITapGestureRecognizer(target: self, action: #selector(choseTap(ges:)))
-        choseContentView.addGestureRecognizer(ges)
-//        choseContentView.backgroundColor = UIColor.hexColor(hexadecimal: "#FF0000")
-        return choseContentView
-    }()
-
-    lazy public var choseBtn: UIButton = {
-        let choseBtn = UIButton(type: .custom)
-        choseBtn.setBackgroundImage(UIImage.init().BF_Image(named:  "videomk_chose_nomal"), for: .normal)
-        choseBtn.setBackgroundImage(UIImage.init().BF_Image(named:  "videomk_chose_selected").withRenderingMode(.alwaysTemplate), for: .selected)
-        choseBtn.tintColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
-        choseBtn.setTitleColor(UIColor.white, for: .normal)
-        choseBtn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
-        choseBtn.tag = 1
-        choseBtn.addCorner(corner: 15)
-        choseBtn.isUserInteractionEnabled = false
-        return choseBtn
-    }()
-
-    /// 删除按钮
-    lazy public var deleteBtn: UIButton = {
-        let deleteBtn = UIButton(type: .custom)
-        deleteBtn.tintColor = PQBFConfig.shared.styleBackGroundColor
-        deleteBtn.setImage(PQBFConfig.shared.materialDeleteImage, for: .normal)
-        deleteBtn.tag = 2
-        deleteBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
-        deleteBtn.isHidden = !isAdded
-        return deleteBtn
-    }()
-
-    @objc class public func choseMaterialCell(collectionView: UICollectionView, indexPath: IndexPath) -> PQChoseMaterialCell {
-        let cell: PQChoseMaterialCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PQChoseMaterialCell.self), for: indexPath) as! PQChoseMaterialCell
-        return cell
-    }
-
-    override public init(frame: CGRect) {
-        super.init(frame: frame)
-        contentView.addSubview(borderView)
-        contentView.addSubview(materialImageView)
-        contentView.addSubview(deleteBtn)
-        materialImageView.addSubview(videoStatuImageView)
-        materialImageView.addSubview(choseContentView)
-        choseContentView.addSubview(choseBtn)
-        materialImageView.addSubview(statusLab)
-        materialImageView.addSubview(videoLoadingView)
-    }
-
-    required public  init?(coder _: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    public  var materialData: PQEditVisionTrackMaterialsModel? {
-        didSet {
-            addData()
-            addLayout()
-        }
-    }
-
-    public func addData() {
-        if materialData?.coverImageUI != nil {
-            materialImageView.image = materialData?.coverImageUI
-        } else if materialData?.asset != nil{
-//            DispatchQueue.global().async {[weak self] in
-//                (PHCachingImageManager.default() as? PHCachingImageManager)?.requestImage(for: (self?.materialData?.asset)!, targetSize: photoItemSize, contentMode: .aspectFill, options: nil) {[weak self] image, info in
-//                    if info?.keys.contains("PHImageResultIsDegradedKey") ?? false, "\(info?["PHImageResultIsDegradedKey"] ?? "0")" == "0", self?.representedAssetIdentifier == self?.materialData?.asset?.localIdentifier {
-//                        if image != nil {
-//                            self?.materialData?.coverImageUI = image
-//                            DispatchQueue.main.async {[weak self] in
-//                                self?.materialImageView.image = image
-//                            }
-//                        } else if image == nil, info?.keys.contains("PHImageResultIsInCloudKey") ?? false {
-//                            let option = PHImageRequestOptions()
-//                            option.isNetworkAccessAllowed = true
-//                            option.resizeMode = .fast
-//                            (PHCachingImageManager.default() as? PHCachingImageManager)?.requestImageData(for: (self?.materialData?.asset)!, options: option) { data, _, _, _ in
-//                                if data != nil, self?.representedAssetIdentifier == self?.materialData?.asset?.localIdentifier {
-//                                    let image = UIImage(data: data!)
-//                                    self?.materialData?.coverImageUI = image
-//                                    DispatchQueue.main.async {[weak self] in
-//                                        self?.materialImageView.image = image
-//                                    }
-//                                }
-//                            }
-//                        }
-//                    }
-//                }
-//            }
-        }else if(materialData?.netResCoverImageURL != nil){
-            materialImageView.setNetImage(url: materialData?.netResCoverImageURL ?? "")
-        }
-
-        if materialData?.type == StickerType.VIDEO.rawValue {
-            var duration = (materialData?.duration ?? 0.0)
-            if duration < 1 {
-                duration = 1
-            }
-            statusLab.text = "  \(Float64(duration).formatDurationToHMS())  "
-            statusLab.isHidden = false
-        } else if materialData?.type == StickerType.GIF.rawValue {
-            statusLab.text = "  GIF  "
-            statusLab.isHidden = false
-        } else {
-            statusLab.text = nil
-            statusLab.isHidden = true
-        }
-        videoStatuImageView.isHidden = !isShowMediaTag || materialData?.type != StickerType.VIDEO.rawValue
-        choseContentView.isHidden = isAdded
-        deleteBtn.isHidden = !isAdded
-        if !isAdded {
-            choseBtn.isSelected = materialData?.isSelected ?? false
-            if materialData?.isSelected ?? false {
-                choseBtn.setTitle("\(materialData?.selectedIndex ?? 1)", for: .normal)
-            } else {
-                choseBtn.setTitle(nil, for: .normal)
-            }
-        }else{
-            materialImageView.contentMode = .scaleAspectFit
-            materialImageView.backgroundColor = UIColor.hexColor(hexadecimal: "#0F0F14")
-        }
-        videoLoadingView.isHidden = !(!isAdded && materialData?.type == StickerType.VIDEO.rawValue && materialData?.isSelected == true && materialData?.downloadState == .downloading)
-        if videoLoadingView.isHidden {
-            videoLoadingView.stopAnimating()
-        } else {
-            videoLoadingView.startAnimating()
-        }
-        BFLog(message: "导出视频 = \(videoLoadingView.isHidden),asset = \(String(describing: materialData?.asset)),downloadState = \(String(describing: materialData?.downloadState))")
-//        if videoLoadingView.isHidden {
-//            videoLoadingView.stopAnimating()
-//            videoLoadingView.layer.removeAllAnimations()
-//        } else {
-//            videoLoadingView.stopAnimating()
-//            videoLoadingView.layer.removeAllAnimations()
-//            videoLoadingView.showLoadingAnimation()
-//        }
-    }
-
-    public  func addLayout() {
-        if isAdded {
-            borderView.snp.makeConstraints { make in
-                make.size.equalTo(CGSize.zero)
-            }
-            deleteBtn.snp.makeConstraints { make in
-                make.right.equalToSuperview()
-                make.top.equalToSuperview()
-                make.width.height.equalTo(cDefaultMargin * 2)
-            }
-            materialImageView.snp.makeConstraints { make in
-                make.left.equalToSuperview()
-                make.right.equalTo(deleteBtn.snp_centerX)
-                make.top.equalTo(deleteBtn.snp_centerY)
-                make.width.equalTo(materialImageView.snp_height)
-            }
-        } else {
-            borderView.snp.makeConstraints { make in
-                make.size.equalToSuperview()
-            }
-            materialImageView.snp.makeConstraints { make in
-                make.size.equalToSuperview()
-            }
-            choseContentView.snp.makeConstraints { make in
-                make.top.right.equalToSuperview()
-                make.width.height.equalTo(cDefaultMargin * 5)
-            }
-            choseBtn.snp.makeConstraints { make in
-                make.top.right.equalToSuperview()
-                make.width.height.equalTo(cDefaultMargin * 3)
-            }
-        }
-        statusLab.snp.makeConstraints { make in
-            make.bottom.right.equalToSuperview().offset(-4)
-            make.height.equalTo(18)
-        }
-        videoStatuImageView.snp.makeConstraints { make in
-            make.center.equalToSuperview()
-        }
-        videoLoadingView.snp.makeConstraints { make in
-            make.center.equalToSuperview()
-            make.width.height.equalTo(cDefaultMargin * 4)
-        }
-    }
-
-    @objc public func btnClick(sender: UIButton) {
-        if materialClicHandle != nil {
-            materialClicHandle!(sender, materialData)
-        }
-    }
-
-    @objc public func choseTap(ges _: UITapGestureRecognizer) {
-        btnClick(sender: choseBtn)
-    }
-
-    deinit {
-        videoLoadingView.stopAnimating()
-    }
-}

+ 0 - 121
BFFramework/Classes/Base/View/PQFollowButton.swift

@@ -1,121 +0,0 @@
-//
-//  PQFollowButton.swift
-//  PQSpeed
-//
-//  Created by lieyunye on 2020/6/18.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import Foundation
-
-public class PQFollowButton: UIButton {
-    public  let bgLayer = CAShapeLayer()
-
-    public  var attenBtn: UIButton = {
-        let attenBtn = UIButton(type: .custom)
-        attenBtn.isUserInteractionEnabled = false
-        attenBtn.setTitle("", for: .selected)
-        attenBtn.setImage(UIImage.init().BF_Image(named: "icon_oder"), for: .selected)
-        attenBtn.setTitle("+", for: .normal)
-        attenBtn.setImage(nil, for: .normal)
-        attenBtn.setTitleColor(UIColor.white, for: .normal)
-        attenBtn.titleLabel?.font = UIFont.systemFont(ofSize: 20, weight: .bold)
-        attenBtn.layer.cornerRadius = 10
-//        attenBtn.layer.masksToBounds = true
-        attenBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
-        attenBtn.tag = 2
-        attenBtn.titleEdgeInsets = UIEdgeInsets(top: -3, left: 0, bottom: 0, right: 0)
-        return attenBtn
-    }()
-
-    override public  init(frame: CGRect) {
-        super.init(frame: frame)
-        addSubview(attenBtn)
-    }
-
-    required public  init?(coder _: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    override public func layoutSubviews() {
-        super.layoutSubviews()
-        attenBtn.snp.makeConstraints { make in
-            make.edges.equalTo(self).inset(UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
-        }
-    }
-
-    public  func reset() {
-        attenBtn.isHidden = false
-        attenBtn.layer.removeAllAnimations()
-        bgLayer.removeAllAnimations()
-        bgLayer.sublayers?.forEach {
-            $0.removeAllAnimations()
-            $0.removeFromSuperlayer()
-        }
-        bgLayer.removeFromSuperlayer()
-    }
-
-    public  func start() {
-        let bounds = self.bounds
-
-        bgLayer.frame = bounds
-        bgLayer.cornerRadius = bounds.height / 2.0
-        bgLayer.masksToBounds = true
-        layer.addSublayer(bgLayer)
-
-        let bgScale = CABasicAnimation(keyPath: "transform.scale")
-        bgScale.fromValue = 1
-        bgScale.toValue = 1.2
-        bgScale.duration = 0.2
-        attenBtn.layer.add(bgScale, forKey: nil)
-
-        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
-            self.attenBtn.isHidden = true
-            let opacity = CAKeyframeAnimation(keyPath: "backgroundColor")
-            opacity.values = [UIColor.red.cgColor, UIColor.white.cgColor]
-            opacity.duration = 0.5
-            opacity.fillMode = .forwards
-            opacity.isRemovedOnCompletion = false
-            self.bgLayer.add(opacity, forKey: nil)
-
-            let bgLayer1 = CAShapeLayer()
-            let frame = CGRect(x: (bounds.size.width - bounds.size.height) / 2.0, y: 0, width: bounds.size.height, height: bounds.size.height)
-            bgLayer1.frame = frame
-            self.bgLayer.addSublayer(bgLayer1)
-
-            let linePath = UIBezierPath()
-
-            let radius: CGFloat = frame.size.width / 2.0
-            linePath.move(to: CGPoint(x: radius * 0.45, y: radius * 1.0))
-            linePath.addLine(to: CGPoint(x: radius * 0.84, y: radius * 1.32))
-            linePath.addLine(to: CGPoint(x: radius * 1.48, y: radius * 0.68))
-
-            let layer = CAShapeLayer()
-
-            layer.path = linePath.cgPath
-            layer.fillColor = UIColor.clear.cgColor
-            layer.strokeColor = UIColor.hexColor(hexadecimal: "#EE0051").cgColor
-            layer.lineWidth = 2.5
-            bgLayer1.addSublayer(layer)
-
-            let animation = CABasicAnimation()
-            animation.duration = 0.5
-            animation.keyPath = "strokeEnd"
-            animation.fromValue = 0
-            animation.toValue = 1
-            animation.fillMode = .forwards
-            animation.isRemovedOnCompletion = false
-
-            layer.add(animation, forKey: "strokeEnd")
-
-            let scale = CABasicAnimation(keyPath: "transform.scale")
-            scale.fromValue = 1
-            scale.toValue = 0
-            scale.duration = 0.2
-            scale.beginTime = CACurrentMediaTime() + 1.5
-            scale.fillMode = .forwards
-            scale.isRemovedOnCompletion = false
-            self.bgLayer.add(scale, forKey: nil)
-        }
-    }
-}

+ 0 - 41
BFFramework/Classes/Base/View/PQGIFImageView.swift

@@ -1,41 +0,0 @@
-//
-//  PQGIFImageView.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/9/2.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import UIKit
-
-public class PQGIFImageView: UIImageView {
-   public var imagesDara: [String]? {
-        didSet {
-            generateImages()
-            displayGIF(1, Int.max)
-        }
-    }
-
-    public var images: [UIImage] = Array<UIImage>.init()
-    public func generateImages() {
-        if imagesDara != nil, (imagesDara?.count ?? 0) > 0 {
-            for item in imagesDara! {
-                let image = UIImage(named: item)!
-                images.append(image)
-            }
-        }
-    }
-
-    public func displayGIF(_ duration: TimeInterval, _ repeatCount: Int) {
-        if !isAnimating {
-            layer.removeAllAnimations()
-            if images.count <= 0 {
-                return
-            }
-            animationImages = images
-            animationDuration = duration
-            animationRepeatCount = repeatCount
-            startAnimating()
-        }
-    }
-}

+ 0 - 53
BFFramework/Classes/Base/View/PQHeartAnimation.swift

@@ -1,53 +0,0 @@
-//
-//  PQHeartAnimation.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/6/11.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import UIKit
-
-public class PQHeartAnimation: NSObject {
-    static let angleArr: [CGFloat] = [CGFloat.pi / 4.0, -CGFloat.pi / 4.0, 0.0]
-    var isRepeat: Bool = false
-
-    static public func showAnimation(isRepeat: Bool = false, point: CGPoint, size: CGFloat = 80.0, baseView: UIView, completeHander: @escaping (_ isFinised: Bool) -> Void) {
-        if isRepeat, baseView.viewWithTag(cHeartTag) != nil {
-            return
-        }
-        let imgV = UIImageView(frame: CGRect(x: point.x - size / 2.0, y: point.y - size / 2.0, width: size, height: size))
-        imgV.tag = cHeartTag
-        imgV.image = UIImage.init().BF_Image(named:  "ic_heart")
-        imgV.contentMode = .scaleAspectFill
-        baseView.addSubview(imgV)
-
-        // 偏移角度
-        var num = 2
-        if !isRepeat {
-            num = Int(arc4random_uniform(3))
-        }
-//      BFLog(message: "num = \(num)")
-        imgV.transform = CGAffineTransform(rotationAngle: angleArr[num])
-        // 放大动画
-        let animation = CAKeyframeAnimation(keyPath: "transform.scale")
-        animation.duration = 0.5
-        animation.calculationMode = CAAnimationCalculationMode.cubic
-        animation.values = [1.3, 0.8, 1.0]
-        imgV.layer.add(animation, forKey: "transform.scale")
-
-        UIView.animate(withDuration: 1, delay: 0.5, options: .layoutSubviews, animations: {
-            imgV.alpha = 0.0
-            var newFrame = imgV.frame
-            newFrame.origin.x -= (isRepeat ? -cDefaultMargin * 2 : cDefaultMargin)
-            newFrame.origin.y -= 45.0
-            newFrame.size.height += 10.0
-            newFrame.size.width += 10.0
-            imgV.frame = newFrame
-        }) { isOK in
-            imgV.layer.removeAllAnimations()
-            imgV.removeFromSuperview()
-            completeHander(isOK)
-        }
-    }
-}

+ 0 - 515
BFFramework/Classes/Base/View/PQRemindView.swift

@@ -1,515 +0,0 @@
-
-// MARK: - 设置页退出登录跟注销账号提示视图
-
-/// 设置页退出登录跟注销账号提示视图
-open class PQRemindView: UIView {
-    public var isBanned: Bool = false // 是否是拉黑用户提示
-    public var isBlank: Bool = false { // 是否是黑色弹窗
-        didSet {
-            if isBlank {
-                contentView.backgroundColor = UIColor.hexColor(hexadecimal: "#212223")
-                titleLab.textColor = UIColor.white
-                contentLab.textColor = UIColor.white
-                cancelBtn.setTitleColor(UIColor.white, for: .normal)
-                confirmBtn.setTitleColor(UIColor.white, for: .normal)
-            } else {
-                contentView.backgroundColor = UIColor.white
-                contentLab.textColor = UIColor.hexColor(hexadecimal: "#666666")
-                titleLab.textColor = UIColor.black
-                cancelBtn.setTitleColor(UIColor.black, for: .normal)
-                confirmBtn.setTitleColor(UIColor.black, for: .normal)
-            }
-        }
-    }
-
-    public var remindBlock: ((_ sender: UIButton, _ remindData: PQBaseModel?) -> Void)?
-
-    lazy public var contentView: UIView = {
-        let contentView = UIView()
-        contentView.backgroundColor = UIColor.white
-        contentView.addCorner(corner: 4)
-        return contentView
-    }()
-
-    lazy public var titleLab: UILabel = {
-        let titleLab = UILabel()
-        titleLab.font = UIFont.systemFont(ofSize: 18, weight: .medium)
-        titleLab.textAlignment = .center
-        titleLab.numberOfLines = 0
-        titleLab.textColor = UIColor.black
-        return titleLab
-    }()
-
-    lazy public var contentLab: UILabel = {
-        //        let contentLab = TYAttributedLabel.init()
-        //        contentLab.textAlignment = CTTextAlignment.center
-        //        contentLab.verticalAlignment = .center
-        //        contentLab.highlightedLinkBackgroundColor = UIColor.white
-        //        contentLab.numberOfLines = 0
-        //        contentLab.font = UIFont.systemFont(ofSize: 14)
-        //        contentLab.textColor = UIColor.hexColor(hexadecimal: "#666666")
-        let contentLab = UILabel()
-        contentLab.font = UIFont.systemFont(ofSize: 16)
-        contentLab.textAlignment = .center
-        contentLab.numberOfLines = 0
-        contentLab.textColor = UIColor.hexColor(hexadecimal: "#666666")
-        return contentLab
-    }()
-
-    lazy public var cancelBtn: UIButton = {
-        let cancelBtn = UIButton(type: .custom)
-        cancelBtn.setTitle("取消", for: .normal)
-        cancelBtn.setTitleColor(UIColor.black, for: .normal)
-        cancelBtn.tag = 1
-        cancelBtn.addTarget(self, action: #selector(btnClck(sender:)), for: .touchUpInside)
-        cancelBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
-        return cancelBtn
-    }()
-
-    lazy public var confirmBtn: UIButton = {
-        let confirmBtn = UIButton(type: .custom)
-        confirmBtn.setTitle("确定", for: .normal)
-        confirmBtn.setTitleColor(UIColor.black, for: .normal)
-        confirmBtn.tag = 2
-        confirmBtn.addTarget(self, action: #selector(btnClck(sender:)), for: .touchUpInside)
-        confirmBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
-        return confirmBtn
-    }()
-
-    lazy public var verticalLine: UIView = {
-        let verticalLine = UIView()
-        verticalLine.backgroundColor = UIColor.hexColor(hexadecimal: "#E5E5E5")
-        return verticalLine
-    }()
-
-    lazy public var horizonLine: UIView = {
-        let horizonLine = UIView()
-        horizonLine.backgroundColor = UIColor.hexColor(hexadecimal: "#E5E5E5")
-        return horizonLine
-    }()
-
-    override public init(frame: CGRect) {
-        super.init(frame: frame)
-        addSubview(contentView)
-        contentView.addSubview(titleLab)
-        contentView.addSubview(contentLab)
-        contentView.addSubview(cancelBtn)
-        contentView.addSubview(confirmBtn)
-        contentView.addSubview(verticalLine)
-        contentView.addSubview(horizonLine)
-        backgroundColor = cShadowColor
-    }
-
-    required public init?(coder _: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    public var  remindData: PQBaseModel? {
-        didSet {
-            addData()
-            addLayout()
-        }
-    }
-
-    open func addData() {
-        titleLab.text = remindData?.title
-        contentLab.text = remindData?.summary
-        cancelBtn.setTitleColor(isBanned ? (isBlank ? UIColor.white : UIColor.black) : (isBlank ? UIColor.white : UIColor.hexColor(hexadecimal: "#666666")), for: .normal)
-        if isBanned {
-            titleLab.textAlignment = .center
-        } else {
-            titleLab.textAlignment = .left
-        }
-    }
-
-   open func addLayout() {
-        var summH: CGFloat = 0
-        var titleH: CGFloat = 0
-        if (remindData?.summary?.count ?? 0) > 0 {
-            summH = sizeWithText(text: remindData?.summary ?? "", font: UIFont.systemFont(ofSize: 16, weight: .medium), size: CGSize(width: cScreenWidth - cDefaultMargin * 12, height: CGFloat.greatestFiniteMagnitude)).height + cDefaultMargin
-        }
-        if (remindData?.title?.count ?? 0) > 0 {
-            titleH = sizeWithText(text: remindData?.title ?? "", font: UIFont.systemFont(ofSize: 18, weight: .medium), size: CGSize(width: cScreenWidth - cDefaultMargin * 12, height: CGFloat.greatestFiniteMagnitude)).height + cDefaultMargin
-            if titleH < cDefaultMargin * 2 {
-                titleH = cDefaultMargin * 2
-            }
-        }
-        let contentH: CGFloat = cDefaultMargin * 2 + (titleH > 0 ? titleH + cDefaultMargin : 0) + (summH > 0 ? summH + cDefaultMargin : 0) + cDefaultMargin * 3 + (isBanned ? cDefaultMargin * 2 : 0)
-        contentView.snp.makeConstraints { make in
-            make.left.equalTo(self).offset(cDefaultMargin * 4)
-            make.right.equalTo(self).offset(-cDefaultMargin * 4)
-            make.height.equalTo(contentH)
-            make.center.equalTo(self)
-        }
-        titleLab.snp.makeConstraints { make in
-            make.left.equalTo(contentView).offset(cDefaultMargin * 2)
-            make.right.equalTo(contentView).offset(-cDefaultMargin * 2)
-            make.height.equalTo(titleH)
-            make.top.equalTo(contentView).offset(cDefaultMargin * 2)
-        }
-        contentLab.snp.makeConstraints { make in
-            make.top.equalTo(titleLab.snp_bottom).offset(summH > 0 ? cDefaultMargin : 0)
-            make.left.right.equalTo(titleLab)
-            make.height.equalTo(summH)
-        }
-        if isBanned {
-            let btnW: CGFloat = (cScreenWidth - 1 - cDefaultMargin * 8) / 2
-            verticalLine.snp.makeConstraints { make in
-                make.top.equalTo(contentLab.snp_bottom).offset(cDefaultMargin)
-                make.height.equalTo(1)
-                make.left.width.equalToSuperview()
-            }
-            cancelBtn.snp.makeConstraints { make in
-                make.left.equalToSuperview()
-                make.top.equalTo(verticalLine.snp_bottom)
-                make.width.equalTo(btnW)
-                make.bottom.equalTo(contentView)
-            }
-            horizonLine.snp.makeConstraints { make in
-                make.left.equalTo(cancelBtn.snp_right)
-                make.height.top.equalTo(cancelBtn)
-                make.width.equalTo(1)
-            }
-            confirmBtn.snp.makeConstraints { make in
-                make.right.equalToSuperview()
-                make.height.width.bottom.equalTo(cancelBtn)
-            }
-        } else {
-            confirmBtn.snp.makeConstraints { make in
-                make.right.equalTo(titleLab)
-                make.height.equalTo(cDefaultMargin * 4)
-                make.width.equalTo(cDefaultMargin * 6)
-                make.bottom.equalTo(contentView).offset(-cDefaultMargin)
-            }
-            cancelBtn.snp.makeConstraints { make in
-                make.right.equalTo(confirmBtn.snp_left).offset(-cDefaultMargin)
-                make.height.equalTo(cDefaultMargin * 4)
-                make.width.equalTo(cDefaultMargin * 6)
-                make.bottom.equalTo(confirmBtn)
-            }
-        }
-    }
-
-    @objc open func btnClck(sender: UIButton) {
-        removeFromSuperview()
-        if remindBlock != nil {
-            remindBlock!(sender, remindData!)
-        }
-    }
-}
-
-// MARK: 空白提示页
-
-/// 空白提示页
-open class PQEmptyRemindView: UIView {
-    // 回调
-    public var fullRefreshBloc: ((_ isNetConnected: Bool, _ emptyData: PQEmptyModel?) -> Void)?
-
-    lazy public var imageView: UIImageView = {
-        let imageView = UIImageView()
-        imageView.backgroundColor = UIColor.clear
-        imageView.contentMode = .scaleAspectFit
-        return imageView
-    }()
-
-    lazy public var remindLab: UILabel = {
-        let remindLab = UILabel()
-        remindLab.font = UIFont.systemFont(ofSize: 16)
-        remindLab.numberOfLines = 1
-        remindLab.textAlignment = NSTextAlignment.center
-        remindLab.textColor = UIColor.white
-        return remindLab
-    }()
-
-    lazy public var shimmeringView: FBShimmeringView = {
-        let shimmeringView = FBShimmeringView()
-        shimmeringView.isShimmering = false
-        shimmeringView.shimmeringBeginFadeDuration = 0.3
-        shimmeringView.shimmeringEndFadeDuration = 0.1
-        shimmeringView.shimmeringOpacity = 0.2
-        shimmeringView.shimmeringSpeed = 300
-        shimmeringView.contentView = remindLab
-        return shimmeringView
-    }()
-
-    lazy public var remindSubLab: UILabel = {
-        let remindSubLab = UILabel()
-        remindSubLab.font = UIFont.systemFont(ofSize: 14)
-        remindSubLab.numberOfLines = 1
-        remindSubLab.textAlignment = NSTextAlignment.center
-        remindSubLab.textColor = UIColor.hexColor(hexadecimal: "#999999")
-        return remindSubLab
-    }()
-
-    lazy public var refreshBtn: UIButton = {
-        let refreshBtn = UIButton(type: .custom)
-        refreshBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
-        refreshBtn.titleLabel?.font = UIFont.systemFont(ofSize: 15)
-        refreshBtn.setTitleColor(UIColor.white, for: .normal)
-        refreshBtn.setTitle("刷新", for: .normal)
-        refreshBtn.setTitle("重新连接网络", for: .selected)
-        refreshBtn.addCorner(corner: cDefaultMargin * 2)
-        refreshBtn.isHidden = true
-        refreshBtn.addTarget(self, action: #selector(fullRefresh), for: .touchUpInside)
-        return refreshBtn
-    }()
-
-    override public init(frame: CGRect) {
-        super.init(frame: frame)
-        addSubview(imageView)
-        addSubview(shimmeringView)
-        addSubview(remindSubLab)
-        addSubview(refreshBtn)
-        let ges = UITapGestureRecognizer(target: self, action: #selector(fullRefresh))
-        addGestureRecognizer(ges)
-        backgroundColor = PQBFConfig.shared.styleBackGroundColor
-    }
-
-    required public init?(coder _: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    @objc public var emptyData: PQEmptyModel? {
-        didSet {
-            addData()
-            addLayout()
-        }
-    }
-}
-
-extension PQEmptyRemindView {
-    public func addData() {
-        if !isNetConnected() {
-            remindLab.text = "网络连接失败,请检查网络后重试"
-            remindSubLab.isHidden = true
-            refreshBtn.isHidden = false
-            refreshBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
-            refreshBtn.setTitleColor(UIColor.white, for: .normal)
-            refreshBtn.setTitle("刷新", for: .normal)
-            imageView.image = UIImage.init().BF_Image(named:  "pic_network")
-        } else {
-            if emptyData?.emptyImage != nil, emptyData?.emptyImage?.count ?? 0 > 0 {
-                imageView.image = UIImage.init().BF_Image(named:  emptyData?.emptyImage ?? "")
-            } else {
-                imageView.image = nil
-            }
-            remindLab.text = emptyData?.title
-            remindSubLab.text = emptyData?.summary
-            refreshBtn.isHidden = emptyData?.isRefreshHidden ?? true
-            if emptyData?.refreshImage != nil, (emptyData?.refreshImage?.count ?? 0) > 0 {
-                refreshBtn.setImage(UIImage.init().BF_Image(named:  emptyData?.refreshImage ?? ""), for: .normal)
-            } else {
-                refreshBtn.setImage(nil, for: .normal)
-            }
-            refreshBtn.setAttributedTitle(emptyData?.refreshTitle, for: .normal)
-            if emptyData?.refreshBgColor != nil {
-                refreshBtn.backgroundColor = emptyData?.refreshBgColor
-            }
-        }
-    }
-
-    override public var isHidden: Bool {
-        didSet {
-            addData()
-            addLayout()
-        }
-    }
-
-    public func addLayout() {
-        var imageH: CGFloat = cDefaultMargin * 7
-        var contentH: CGFloat = 0
-
-        if (emptyData?.emptyImage != nil &&  emptyData?.emptyImage?.count ?? 0 > 0) || !isNetConnected() {
-            contentH = contentH + imageH + cDefaultMargin
-        } else {
-            imageH = 0
-        }
-        if emptyData?.title != nil, emptyData?.title?.count ?? 0 > 0 {
-            contentH = contentH + cDefaultMargin * 2 + cDefaultMargin
-        }
-        if emptyData?.summary != nil, emptyData?.summary?.count ?? 0 > 0 {
-            contentH = contentH + cDefaultMargin * 2 + cDefaultMargin
-        }
-        if !refreshBtn.isHidden {
-            contentH = contentH + cDefaultMargin + cDefaultMargin * 4
-        }
-        let topY = (frame.height - contentH) / 2
-        imageView.snp.remakeConstraints { make in
-            make.top.equalTo(topY)
-            make.centerX.equalTo(self)
-            make.height.equalTo(imageH)
-        }
-        shimmeringView.snp.makeConstraints { make in
-            make.left.right.equalTo(self)
-            make.top.equalTo(imageView.snp_bottom).offset(cDefaultMargin)
-        }
-        remindLab.snp.remakeConstraints { make in
-            make.size.equalToSuperview()
-        }
-        remindSubLab.snp.makeConstraints { make in
-            make.left.right.equalTo(self)
-            make.top.equalTo(remindLab.snp_bottom).offset(cDefaultMargin)
-        }
-        refreshBtn.snp.makeConstraints { make in
-            make.width.equalTo(cDefaultMargin * 13)
-            make.height.equalTo(cDefaultMargin * 4)
-            make.top.equalTo(remindSubLab.snp_bottom).offset(cDefaultMargin)
-            make.centerX.equalToSuperview()
-        }
-    }
-
-    @objc func fullRefresh() {
-        let isConnected: Bool = isNetConnected()
-        if !isConnected {
-            cShowHUB(superView: nil, msg: "网络不给力")
-        }
-        if fullRefreshBloc != nil {
-            fullRefreshBloc!(isConnected, emptyData)
-        }
-    }
-
-    func addShimmeringView() {}
-
-    func removeShimmeringView() {}
-}
-
-// MARK: - 上传提示框
-
-/// 上传提示框
-public class PQUploadRemindView: PQRemindView {
-    public var canMoreOpration: Bool = false // 是否还有更多操作
-    public var confirmTitle: String = "我知道了"
-    public var cancelTitle: String = "取消"
-    public var cacelColor: UIColor = UIColor.hexColor(hexadecimal: "#666666")
-    public var attributedTitle: NSAttributedString?
-
-    override public func addData() {
-        titleLab.textAlignment = .center
-        if attributedTitle != nil {
-            titleLab.attributedText = attributedTitle
-        } else {
-            titleLab.text = remindData?.title
-        }
-        if remindData?.attributedTitle != nil {
-            contentLab.attributedText = remindData?.attributedTitle
-        } else {
-            contentLab.text = remindData?.summary
-        }
-        cancelBtn.setTitleColor(cacelColor, for: .normal)
-        confirmBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#EE0051"), for: .normal)
-        confirmBtn.setTitle(confirmTitle, for: .normal)
-        cancelBtn.setTitle(cancelTitle, for: .normal)
-        let ges = UITapGestureRecognizer(target: self, action: #selector(removeView))
-        addGestureRecognizer(ges)
-    }
-
-    override public func addLayout() {
-        let titleH: CGFloat = ((remindData?.title != nil && (remindData?.title?.count ?? 0) > 0) || attributedTitle != nil) ? cDefaultMargin * 2 : 0
-
-        let summH: CGFloat = sizeTextFits(attributedText: remindData?.attributedTitle != nil ? remindData?.attributedTitle : NSMutableAttributedString(string: remindData?.summary ?? ""), text: nil, numberOfLines: 0, font: UIFont.systemFont(ofSize: 14), maxSize: CGSize(width: cScreenWidth - cDefaultMargin * 12, height: CGFloat.greatestFiniteMagnitude)).height + cDefaultMargin
-
-        let contentH: CGFloat = (titleH == 0 ? 0 : cDefaultMargin * 3) + cDefaultMargin * 2 + summH + cDefaultMargin + cDefaultMargin * 5
-
-        contentView.snp.makeConstraints { make in
-            make.left.equalTo(self).offset(cDefaultMargin * 3)
-            make.right.equalTo(self).offset(-cDefaultMargin * 3)
-            make.height.equalTo(contentH)
-            make.center.equalTo(self)
-        }
-        titleLab.snp.makeConstraints { make in
-            make.left.equalTo(contentView).offset(cDefaultMargin * 2)
-            make.right.equalTo(contentView).offset(-cDefaultMargin * 2)
-            make.height.equalTo(titleH)
-            make.top.equalTo(contentView).offset(titleH == 0 ? 0 : cDefaultMargin * 2)
-        }
-        contentLab.snp.makeConstraints { make in
-            make.top.equalTo(titleLab.snp_bottom).offset(cDefaultMargin)
-            make.left.right.equalTo(titleLab)
-            make.height.equalTo(summH)
-        }
-        if canMoreOpration {
-            let btnW: CGFloat = (cScreenWidth - 1 - cDefaultMargin * 8) / 2
-            verticalLine.snp.makeConstraints { make in
-                make.top.equalTo(contentLab.snp_bottom).offset(cDefaultMargin)
-                make.height.equalTo(1)
-                make.left.width.equalToSuperview()
-            }
-            cancelBtn.snp.makeConstraints { make in
-                make.left.equalToSuperview()
-                make.top.equalTo(verticalLine.snp_bottom)
-                make.width.equalTo(btnW)
-                make.bottom.equalTo(contentView)
-            }
-            horizonLine.snp.makeConstraints { make in
-                make.left.equalTo(cancelBtn.snp_right)
-                make.height.top.equalTo(cancelBtn)
-                make.width.equalTo(1)
-            }
-            confirmBtn.snp.makeConstraints { make in
-                make.right.equalToSuperview()
-                make.height.width.bottom.equalTo(cancelBtn)
-            }
-        } else {
-            verticalLine.snp.makeConstraints { make in
-                make.top.equalTo(contentLab.snp_bottom).offset(cDefaultMargin)
-                make.height.equalTo(1)
-                make.left.width.equalToSuperview()
-            }
-            confirmBtn.snp.makeConstraints { make in
-                make.right.left.equalTo(titleLab)
-                make.top.equalTo(verticalLine.snp_bottom)
-                make.bottom.equalTo(contentView)
-            }
-        }
-    }
-
-    @objc func removeView() {
-        removeFromSuperview()
-    }
-
-    @objc public override func btnClck(sender: UIButton) {
-        removeFromSuperview()
-        if remindBlock != nil {
-            remindBlock!(sender, remindData!)
-        }
-    }
-
-    /// 快速生成
-    /// - Parameters:
-    ///   - title: <#title description#>
-    ///   - summary: <#summary description#>
-    ///   - confirmTitle: <#confirmTitle description#>
-    ///   - remindHandle: <#remindHandle description#>
-    /// - Returns: <#description#>
-    class public func showUploadRemindView(title: String?, attributedTitle: NSAttributedString? = nil, summary: String, canMoreOpration: Bool = false, confirmTitle: String?, cancelTitle: String? = nil, cancelColor: UIColor? = nil, remindHandle: @escaping (_ sender: UIButton, _ baseModel: PQBaseModel?) -> Void) {
-        if UIApplication.shared.keyWindow?.viewWithTag(cUploadViewRemindTag) != nil {
-            UIApplication.shared.keyWindow?.viewWithTag(cUploadViewRemindTag)?.removeFromSuperview()
-        }
-        let remindData = PQBaseModel()
-        let paragraphStyle = NSMutableParagraphStyle()
-        paragraphStyle.lineSpacing = 3.0
-        paragraphStyle.alignment = .center
-        remindData.title = title
-        remindData.attributedTitle = NSMutableAttributedString(string: summary, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor.hexColor(hexadecimal: "#666666"), NSAttributedString.Key.paragraphStyle: paragraphStyle])
-        let remindView = PQUploadRemindView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
-        remindView.canMoreOpration = canMoreOpration
-        if confirmTitle != nil {
-            remindView.confirmTitle = confirmTitle!
-        }
-        if cancelTitle != nil {
-            remindView.cancelTitle = cancelTitle!
-        }
-        if cancelColor != nil {
-            remindView.cacelColor = cancelColor!
-        }
-        if attributedTitle != nil {
-            remindView.attributedTitle = attributedTitle
-        }
-        remindView.remindBlock = { sender, baseModel in
-            remindHandle(sender, baseModel)
-        }
-        remindView.tag = cUploadViewRemindTag
-        UIApplication.shared.keyWindow?.addSubview(remindView)
-        remindView.remindData = remindData
-    }
-}

+ 2 - 1
BFFramework/Classes/Base/View/PQSectionHeadView.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 public class PQSectionHeadView: UIView {
     // 清除按钮回调
@@ -42,7 +43,7 @@ public class PQSectionHeadView: UIView {
     lazy public  var clearBtn: UIButton = {
         let clearBtn = UIButton(type: .custom)
         clearBtn.setTitle("全部已读 ", for: .normal)
-        clearBtn.setImage(UIImage.init().BF_Image(named: "msg_clear_noreaded"), for: .normal)
+        clearBtn.setImage(UIImage.moduleImage(named: "msg_clear_noreaded", moduleName: "BFFramework",isAssets: false), for: .normal)
         clearBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#666666"), for: .normal)
         clearBtn.titleLabel?.font = UIFont(name: "PingFangSC", size: 13)
         clearBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)

+ 1 - 0
BFFramework/Classes/Base/View/PQSelectedOprationView.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 // MARK: - 选择操作view
 

+ 0 - 27
BFFramework/Classes/Base/View/PQTabBar.swift

@@ -1,27 +0,0 @@
-//
-//  PQTabBar.swift
-//  PQSpeed
-//
-//  Created by SanW on 2021/1/18.
-//  Copyright © 2021 BytesFlow. All rights reserved.
-//
-
-import UIKit
-
-public class PQTabBar: UITabBar {
-    override open func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
-        if isHidden { // 如果隐藏的话不处理事件
-            return super.hitTest(point, with: event)
-        }
-        let view = super.hitTest(point, with: event)
-        if view == nil {
-            for subView in subviews {
-                let myPoint = subView.convert(point, from: self)
-                if subView.bounds.contains(myPoint) {
-                    return subView
-                }
-            }
-        }
-        return view
-    }
-}

+ 0 - 106
BFFramework/Classes/Base/View/PQTextView.swift

@@ -1,106 +0,0 @@
-//
-//  PQTextView.swift
-//  PQSpeed
-//
-//  Created by SanW on 2020/6/11.
-//  Copyright © 2020 BytesFlow. All rights reserved.
-//
-
-import UIKit
-
-open class PQTextView: UITextView {
-    private let textValuesQueue = DispatchQueue(label: "com.BytesFlow.textValuesQueue", qos: .default)
-
-   public var textDidChangedHandle: ((_ textView: UITextView) -> Void)?
-    // 最多输入的个数
-    public  var maxTextLength : Int?
-    // 输入个数超过时提示
-    public  var maxTextLengthRemind : String?
-    // add by ak 默认字的起点位置
-    public  var placeHolderDefultPoint = CGPoint.init(x: 5, y: 7)
-    /// setNeedsDisplay调用drawRect
-    public  var placeHolder: String = "" {
-        didSet {
-            setNeedsDisplay()
-        }
-    }
-
-    /// placeHolder是否居中
-    public  var isCenter: Bool = false {
-        didSet {
-            setNeedsDisplay()
-        }
-    }
-
-    public var placeHolderColor: UIColor = UIColor.gray {
-        didSet {
-            setNeedsDisplay()
-        }
-    }
-
-    open override var font: UIFont? {
-        didSet {
-            setNeedsDisplay()
-        }
-    }
-
-    open override var text: String! {
-        didSet{
-           setNeedsLayout()
-        }
-    }
-
-    open override var attributedText: NSAttributedString! {
-        didSet {
-            setNeedsDisplay()
-        }
-    }
-
-    public override init(frame: CGRect, textContainer: NSTextContainer?) {
-        super.init(frame: frame, textContainer: textContainer)
-        /// default字号
-        PQNotification.addObserver(self, selector: #selector(textDidChanged(noti:)), name: UITextView.textDidChangeNotification, object: self)
-    }
-
-    required public init?(coder _: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    @objc func textDidChanged(noti _: NSNotification) {
-        if maxTextLength != nil && text.count > maxTextLength! {
-            text = String(text.prefix(maxTextLength!))
-            cShowHUB(superView: nil, msg: (maxTextLengthRemind != nil && (maxTextLengthRemind?.count ?? 0) > 0) ? maxTextLengthRemind : "最多输入\( maxTextLength!)个字符")
-        }
-        setNeedsDisplay()
-        if textDidChangedHandle != nil {
-            textDidChangedHandle!(self)
-        }
-    }
-
-    open override func draw(_ rect: CGRect) {
-        if hasText {
-            return
-        }
-        let size = sizeWithText(text: placeHolder, font: font ?? UIFont.systemFont(ofSize: 14), size: rect.size)
-        var newRect = CGRect()
-        newRect.size.width = size.width
-        newRect.size.height = size.height
-        if isCenter {
-            newRect.origin.x = (rect.width - size.width) / 2
-            newRect.origin.y = (rect.height - size.height) / 2
-        } else {
-            newRect.origin.x = placeHolder.contains("未识别到文字") ? 0 : placeHolderDefultPoint.x
-            newRect.origin.y = placeHolder.contains("未识别到文字") ? 0 : placeHolderDefultPoint.y
-        }
-        (placeHolder as NSString).draw(in: newRect, withAttributes: [NSAttributedString.Key.font: font ?? UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: placeHolderColor])
-    }
-
-    open override func layoutSubviews() {
-        super.layoutSubviews()
-        setNeedsDisplay()
-    }
-
-    deinit {
-        PQNotification.removeObserver(self, name: UITextView.textDidChangeNotification, object: self)
-    }
-}

+ 30 - 28
BFFramework/Classes/Base/ViewModel/PQBaseViewModel.swift

@@ -10,6 +10,8 @@ import Alamofire
 import UIKit
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
+import BFNetRequestKit
 
 public class PQBaseViewModel: NSObject {
     
@@ -26,7 +28,7 @@ public class PQBaseViewModel: NSObject {
     ///   - completeHander: completeHander description
     /// - Returns: <#description#>
     public class func searchBGMListData(_ keyWord: String?, _ pageNum: Int = 1, _ pageSize: Int = 30,videoCount: Int = 0, imageCount: Int = 0, totalDuration: Float64 = 0, completeHander: @escaping (_ bgmList: [PQVoiceModel], _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.materialSearchApi + searchBGMMaterialUrl, parames: ["keyWord": keyWord ?? "", "pageNo": pageNum, "pageSize": pageSize], encoding: JSONEncoding.default) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.materialSearchApi + searchBGMMaterialUrl, parames: ["keyWord": keyWord ?? "", "pageNo": pageNum, "pageSize": pageSize], commonParams: commonParams(), encoding: JSONEncoding.default) { response, _, error, _ in
             DispatchQueue.global().async {
                 var bgmList = Array<PQVoiceModel>.init()
                 if response is NSNull || response == nil {
@@ -61,7 +63,7 @@ public class PQBaseViewModel: NSObject {
             completeHander(true)
             return
         }
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + systemAppConfigUrl, parames: nil) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + systemAppConfigUrl, parames: nil, commonParams: commonParams()) { response, _, _, _ in
             if response != nil, !(response is NSNull), (response as! [String: Any]).keys.contains("needLogin") {
                 let needLogin: String = "\((response as! [String: Any])["needLogin"] ?? "0")"
                 saveUserDefaults(key: cNeedLoginKey, value: needLogin)
@@ -78,7 +80,7 @@ public class PQBaseViewModel: NSObject {
     /// - Parameter completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func systemBaseConfig(completeHander: @escaping (_ isSuccess: Bool) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + systemConfigUrl, parames: nil) { _, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + systemConfigUrl, parames: nil, commonParams: commonParams()) { _, _, _, _ in
             completeHander(true)
         }
     }
@@ -91,7 +93,7 @@ public class PQBaseViewModel: NSObject {
     ///   - completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func deleteVideo(videoId: Int, completeHander: @escaping (_ isSuccess: Bool,_ videoId: Int, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + deleteVideoUrl, parames: ["videoId": videoId]) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + deleteVideoUrl, parames: ["videoId": videoId], commonParams: commonParams()) { response, _, error, _ in
             if response != nil {
                 postNotification(name: cDeleteVideoSuccessKey, userInfo: ["videoId": "\(videoId)"])
                 completeHander(true,videoId, nil)
@@ -107,7 +109,7 @@ public class PQBaseViewModel: NSObject {
     ///   - completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func hateVideo(videoId: Int, completeHander: @escaping (_ isSuccess: Bool, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + hateVideoUrl, parames: ["videoId": videoId]) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + hateVideoUrl, parames: ["videoId": videoId], commonParams: commonParams()) { response, _, error, _ in
             if response != nil {
                 completeHander(true, nil)
             } else {
@@ -140,7 +142,7 @@ public class PQBaseViewModel: NSObject {
         } else {
             params["pageNo"] = pageNo
         }
-        SWNetRequest.postRequestData(url: url, parames: params) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: url, parames: params, commonParams: commonParams()) { response, _, error, _ in
             BFLog(message: "当前线程:\(Thread.isMainThread) ")
             DispatchQueue.global().async {
                 BFLog(message: "当前线程 global:\(Thread.isMainThread) ")
@@ -188,7 +190,7 @@ public class PQBaseViewModel: NSObject {
         } else {
             url = url + reportVideoListUrl
         }
-        SWNetRequest.postRequestData(url: url, parames: nil) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: url, parames: nil, commonParams: commonParams()) { response, _, _, _ in
             var reportList = Array<PQBaseModel>.init()
             if response is NSNull || response == nil {
                 completeHander(reportList)
@@ -232,7 +234,7 @@ public class PQBaseViewModel: NSObject {
             url = url + reportVideoUrl
             params["videoId"] = uniqueId
         }
-        SWNetRequest.postRequestData(url: url, parames: params) { _, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: url, parames: params, commonParams: commonParams()) { _, _, _, _ in
             completeHander(true)
         }
     }
@@ -249,7 +251,7 @@ public class PQBaseViewModel: NSObject {
         } else {
             url = url + unBannedUserUrl
         }
-        SWNetRequest.postRequestData(url: url, parames: ["targetUid": targetUid]) { _, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: url, parames: ["targetUid": targetUid], commonParams: commonParams()) { _, _, _, _ in
             postNotification(name: cBannedNotiKey, userInfo: ["userId": targetUid, "isBanned": isBanned ? 1 : 0])
             completeHander(true, isBanned)
         }
@@ -261,7 +263,7 @@ public class PQBaseViewModel: NSObject {
     ///   - completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func isBannedUser(targetUid: Int, completeHander: @escaping (_ isSuccess: Bool, _ isBanned: Bool) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + isBannedUserUrl, parames: ["targetUid": targetUid]) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + isBannedUserUrl, parames: ["targetUid": targetUid], commonParams: commonParams()) { response, _, _, _ in
             if response == nil {
                 completeHander(false, false)
             } else {
@@ -274,7 +276,7 @@ public class PQBaseViewModel: NSObject {
     /// - Parameter completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     class public func bannedUserList(completeHander: @escaping (_ listData: [PQUserInfoModel]?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + bannedUserListUrl, parames: nil) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + bannedUserListUrl, parames: nil, commonParams: commonParams()) { response, _, _, _ in
             var listData = Array<PQUserInfoModel>.init()
             if response is NSNull || response == nil {
                 completeHander(listData)
@@ -307,7 +309,7 @@ public class PQBaseViewModel: NSObject {
             url = url + videoDetailUrl
             params = ["videoId": videoId]
         }
-        SWNetRequest.postRequestData(url: url, parames: params) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: url, parames: params, commonParams: commonParams()) { response, _, error, _ in
             if response is NSNull || response == nil {
                 completeHander(nil, error?.code, error?.msg)
                 return
@@ -332,7 +334,7 @@ public class PQBaseViewModel: NSObject {
     }
 
     public class func h5ShareLinkInfo(videoId: String, pageSource: PAGESOURCE, completeHander: @escaping (_ shareLinkPath: String?, _ mag: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + h5ShareLinkUrl, parames: ["videoId": videoId, "pageSource": pageSource.rawValue, "h5WxRootPageSource": pageSource.rawValue]) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + h5ShareLinkUrl, parames: ["videoId": videoId, "pageSource": pageSource.rawValue, "h5WxRootPageSource": pageSource.rawValue], commonParams: commonParams()) { response, _, _, _ in
             if response is NSNull || response == nil {
                 completeHander(nil, "获取分享地址失败")
                 return
@@ -342,7 +344,7 @@ public class PQBaseViewModel: NSObject {
     }
 
     public class func wxFriendShareInfo(videoId: String, completeHander: @escaping (_ shareImagePath: String?, _ shareTitle: String?, _ shareWeappRawId: String?, _ mag: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + wxFriendUrl, parames: ["videoId": videoId]) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + wxFriendUrl, parames: ["videoId": videoId], commonParams: commonParams()) { response, _, _, _ in
             if response is NSNull || response == nil {
                 completeHander(nil, nil, nil, "获取分享好友数据失败")
                 return
@@ -355,7 +357,7 @@ public class PQBaseViewModel: NSObject {
     /// 获取白名单设置
     /// - Returns: <#description#>
     public class func datashowAllowData(completeHander: @escaping (_ isShowInfo: Bool, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + datashowAllowUrl, parames: ["mid": getMachineCode()], encoding: JSONEncoding.default) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + datashowAllowUrl, parames: ["mid": getMachineCode()], commonParams: commonParams(), encoding: JSONEncoding.default) { response, _, _, _ in
             if response is NSNull || response == nil {
                 completeHander(false, "获取白名单数据失败")
                 return
@@ -368,7 +370,7 @@ public class PQBaseViewModel: NSObject {
     /// add by ak 取 STS token
     /// - Parameter completeHander: completeHander description
     public class func getStsToken(completeHander: @escaping completeHander) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + getStsTokenUrl, parames: ["fileType": "2", "type": 1]) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + getStsTokenUrl, parames: ["fileType": "2", "type": 1], commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
                 completeHander(nil, error?.msg)
                 return
@@ -381,7 +383,7 @@ public class PQBaseViewModel: NSObject {
     /// - Parameter completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func ossTempToken(completeHander: @escaping completeHander) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + ossTempTokenUrl, parames: ["type": "2", "fileType": "1"]) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + ossTempTokenUrl, parames: ["type": "2", "fileType": "1"], commonParams: commonParams()) { response, _, _, _ in
             completeHander(response as? [String: Any], nil)
         }
     }
@@ -391,7 +393,7 @@ public class PQBaseViewModel: NSObject {
     /// - Returns: <#description#>
     public class func getBaseConfig(completeHander: @escaping (_ titles: Array<String>?) -> Void) {
       
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + getBaseConfigURL, parames: nil) { response, _, _, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + getBaseConfigURL, parames: nil, commonParams: commonParams()) { response, _, _, _ in
             if response != nil, !(response is NSNull) {
  
                 let responseDic = response as! [String: Any]
@@ -447,7 +449,7 @@ extension PQBaseViewModel {
          "title": "string",
          "updateTimestamp": 0
          */
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + saveDraftboxUrl, parames: parames) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + saveDraftboxUrl, parames: parames, commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
                 completeHander(nil, error?.msg)
                 return
@@ -474,7 +476,7 @@ extension PQBaseViewModel {
         }
        
         parames["rhythmMode"] = rhythmMode.rawValue
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + saveProjectUrl, parames: parames) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + saveProjectUrl, parames: parames, commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
                 completeHander(nil, error?.msg)
                 return
@@ -494,7 +496,7 @@ extension PQBaseViewModel {
         if projectId != nil {
             parames["projectId"] = projectId
         }
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + updateProjectUrl, parames: parames) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + updateProjectUrl, parames: parames, commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
                 completeHander(nil, error?.msg)
                 return
@@ -512,7 +514,7 @@ extension PQBaseViewModel {
     ///   - completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func reportSendVideo(_ projectId: String, _ videoId: String, videoFromScene: videoFromScene, completeHander: @escaping (_ isSeccess: Bool, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + reportSendVideoUrl, parames: ["projectId": projectId, "videoId": videoId, "fromScene": videoFromScene.rawValue]) { _, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + reportSendVideoUrl, parames: ["projectId": projectId, "videoId": videoId, "fromScene": videoFromScene.rawValue], commonParams: commonParams()) { _, _, error, _ in
 
             BFLog(message: "发布视频后上报:projectId = \(projectId),videoId = \(videoId)")
             if error != nil {
@@ -531,7 +533,7 @@ extension PQBaseViewModel {
     ///   - completeHander: <#completeHander description#>
     public class func listUserDraftbox(lastTimestamp: Int, pageSize: Int = 10, isSelected: Bool = false, completeHander: @escaping (_ projectList: [PQEditProjectModel]?, _ msg: String?) -> Void) {
         let params: [String: Any] = ["pageSize": pageSize, "lastTimestamp": lastTimestamp]
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + listUserDraftboxUrl, parames: params) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + listUserDraftboxUrl, parames: params, commonParams: commonParams()) { response, _, error, _ in
             if error?.code == -1009 || error?.code == -1001 {
                 cShowHUB(superView: nil, msg: "网络不可用")
             }
@@ -563,7 +565,7 @@ extension PQBaseViewModel {
     /// - Parameter completeHander: <#completeHander description#>
     /// - Returns: <#description#>
     public class func draftboxUserCount(completeHander: @escaping (_ draftboxCount: Int, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + draftboxUserCountUrl, parames: nil) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + draftboxUserCountUrl, parames: nil, commonParams: commonParams()) { response, _, error, _ in
             if response is NSNull || response == nil {
                 completeHander(0, error?.msg)
                 return
@@ -587,7 +589,7 @@ extension PQBaseViewModel {
             url = url + deleteDraftboxUrl
             params["draftboxId"] = draftboxIds ?? ""
         }
-        SWNetRequest.postRequestData(url: url, parames: params) { _, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: url, parames: params, commonParams: commonParams()) { _, _, error, _ in
             completeHander(error == nil, error?.msg)
         }
     }
@@ -599,7 +601,7 @@ extension PQBaseViewModel {
     ///   - copyType: 复制类型(1:复制自己的项目,2:创建副本(复制别人的项目) 3:再创作)
     ///   - completeHander: <#completeHander description#>
     public class func copyDraftbox(draftboxId: String?, title: String, copyType: Int, completeHander: @escaping (_ newDraftboxId: String?, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + copyDraftboxUrl, parames: ["draftboxId": draftboxId ?? "", "title": title, "copyType": copyType]) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + copyDraftboxUrl, parames: ["draftboxId": draftboxId ?? "", "title": title, "copyType": copyType], commonParams: commonParams()) { response, _, error, _ in
             if response is NSNull || response == nil {
                 completeHander(nil, error?.msg)
                 return
@@ -614,7 +616,7 @@ extension PQBaseViewModel {
     ///   - title: 标题
     ///   - completeHander: <#completeHander description#>
     public class func updateDraftBoxTitle(draftboxId: String?, title: String, completeHander: @escaping (_ newDraftData: PQEditProjectModel?, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + updateDraftboxTitleUrl, parames: ["draftboxId": draftboxId ?? "", "title": title]) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + updateDraftboxTitleUrl, parames: ["draftboxId": draftboxId ?? "", "title": title], commonParams: commonParams()) { response, _, error, _ in
             if response is NSNull || response == nil {
                 completeHander(nil, error?.msg)
                 return
@@ -629,7 +631,7 @@ extension PQBaseViewModel {
     ///   - completeHander: <#completeHander description#>
     public class func draftboxGetSdata(draftboxId: String?, completeHander: @escaping (_ projectModel: PQEditSdataModel?, _ msg: String?) -> Void) {
         let params: [String: Any] = ["draftboxId": draftboxId ?? ""]
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + draftboxGetSdataUrl, parames: params) { response, _, error, _ in
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.clipapiapi + draftboxGetSdataUrl, parames: params, commonParams: commonParams()) { response, _, error, _ in
 
             if response is NSNull || response == nil {
                 completeHander(nil, error?.msg)

+ 1 - 0
BFFramework/Classes/Base/ViewModel/PQDownloadFileManager.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQDownloadFileManager: NSObject {
     /// 创建文件

+ 2 - 0
BFFramework/Classes/Base/ViewModel/PQDownloadManager.swift

@@ -8,6 +8,8 @@
 //
 
 import UIKit
+import BFCommonKit
+import BFNetRequestKit
 
 // MARK: - 下载管理
 

+ 2 - 0
BFFramework/Classes/Base/ViewModel/PQSessionManager.swift

@@ -7,6 +7,8 @@
 //
 
 import UIKit
+import BFCommonKit
+import BFNetRequestKit
 
 open class PQSessionManager: NSObject {
     public var downloadTaskDatas: [String: PQDownloadModel] = Dictionary<String, PQDownloadModel>.init()

+ 22 - 13
BFFramework/Classes/Base/ViewModel/PQUploadViewModel.swift

@@ -6,6 +6,8 @@
 //  Copyright © 2020 BytesFlow. All rights reserved.
 //
 
+import BFCommonKit
+import BFNetRequestKit
 import UIKit
 
 public class PQUploadViewModel: NSObject {
@@ -19,13 +21,16 @@ public class PQUploadViewModel: NSObject {
     ///   - descr: 描述
     ///   - videoFromScene 视频来源场景 1:普通上传 2:创作工具,3:普通上传转创作工具,4:后台转换加工,5:卡点视频制作
     /// - Returns: <#description#>
-    class public func publishVideo(projectId: String?, fileExtensions: String?, title: String, videoPath: String, coverImgPath: String?, descr: String, videoFromScene: videoFromScene, reCreateData: PQReCreateModel?, eventTrackData: PQVideoMakeEventTrackModel?, completeHander: @escaping (_ videoData: PQVideoListModel?, _ jsonDict: [String: Any]?, _ msg: String?) -> Void) {
+    public class func publishVideo(projectId: String?, fileExtensions: String?, title: String, videoPath: String, coverImgPath: String?, descr: String, videoFromScene: videoFromScene, reCreateData: PQReCreateModel?, eventTrackData: PQVideoMakeEventTrackModel?, topicId: String? = nil, completeHander: @escaping (_ videoData: PQVideoListModel?, _ jsonDict: [String: Any]?, _ msg: String?) -> Void) {
         BFLog(message: "AKAKAAKprojectId is\(String(describing: projectId)) videoFromScene is \(videoFromScene)")
-        var params : Dictionary<String,Any> = ["title": title, "fileExtensions": fileExtensions ?? "application/octet-stream", "videoPath": videoPath, "descr": descr, "viewStatus": 1, "produceProjectId": (projectId ?? "") as String, "videoFromScene": videoFromScene.rawValue]
-        if coverImgPath != nil && (coverImgPath?.count ?? 0) > 0 {
+        var params: [String: Any] = ["title": title, "fileExtensions": fileExtensions ?? "application/octet-stream", "videoPath": videoPath, "descr": descr, "viewStatus": 1, "produceProjectId": (projectId ?? "") as String, "videoFromScene": videoFromScene.rawValue]
+        if coverImgPath != nil, (coverImgPath?.count ?? 0) > 0 {
             params["coverImgPath"] = coverImgPath
         }
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + videoSendUrl, parames: params) { response, _, error, _ in
+        if topicId != nil, (topicId?.count ?? 0) > 0 {
+            params["topicId"] = topicId
+        }
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + videoSendUrl, parames: params, commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
                 completeHander(nil, nil, error?.msg)
                 return
@@ -48,11 +53,11 @@ public class PQUploadViewModel: NSObject {
             }
             PQEventTrackViewModel.baseReportUpload(businessType: .bt_up_process, objectType: .ot_up_publishSuccess, pageSource: nil, extParams: extParams, remindmsg: "上传相关")
             if projectId != nil {
-                PQBaseViewModel.reportSendVideo(projectId!, tempModel.uniqueId ?? "",videoFromScene: videoFromScene) { isSuccess, _ in
+                PQBaseViewModel.reportSendVideo(projectId!, tempModel.uniqueId ?? "", videoFromScene: videoFromScene) { isSuccess, _ in
                     if !isSuccess {
-                        PQBaseViewModel.reportSendVideo(projectId!, tempModel.uniqueId ?? "",videoFromScene: videoFromScene) { isSuccess, _ in
+                        PQBaseViewModel.reportSendVideo(projectId!, tempModel.uniqueId ?? "", videoFromScene: videoFromScene) { isSuccess, _ in
                             if !isSuccess {
-                                PQBaseViewModel.reportSendVideo(projectId!, tempModel.uniqueId ?? "",videoFromScene: videoFromScene) { isSuccess, _ in
+                                PQBaseViewModel.reportSendVideo(projectId!, tempModel.uniqueId ?? "", videoFromScene: videoFromScene) { isSuccess, _ in
                                     if !isSuccess {}
                                 }
                             }
@@ -78,16 +83,20 @@ public class PQUploadViewModel: NSObject {
     ///   - descr: 描述
     ///   - completeHander: <#completeHander description#>
     /// - Returns: <#description#>
-   public class func updateVideo(title: String, videoId: String, coverImgPath: String, descr: String, completeHander: @escaping (_ videoData: PQVideoListModel?, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + updateVideoUrl, parames: ["title": title, "videoId": videoId, "coverImgPath": coverImgPath, "descr": descr, "viewStatus": 1, "barrageSwitch": 1]) { response, _, error, _ in
+    public class func updateVideo(title: String, videoId: String, coverImgPath: String, descr: String,topicId:Int64? = nil, completeHander: @escaping (_ response:[String:Any]?,_ videoData: PQVideoListModel?, _ msg: String?) -> Void) {
+        var params : Dictionary<String,Any> = ["title": title, "videoId": videoId, "coverImgPath": coverImgPath, "descr": descr, "viewStatus": 1, "barrageSwitch": 1]
+        if topicId != nil && (topicId ?? 0) > 0 {
+            params["topicId"] = topicId!
+        }
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + updateVideoUrl, parames: params, commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
-                completeHander(nil, error?.msg)
+                completeHander(nil,nil, error?.msg)
                 return
             }
             // 1015
             let tempModel = PQVideoListModel(jsonDict: response as! [String: Any])
             tempModel.auditStatus = 1
-            completeHander(tempModel, nil)
+            completeHander(response as? [String: Any],tempModel, nil)
         }
     }
 
@@ -98,8 +107,8 @@ public class PQUploadViewModel: NSObject {
     ///   - totalTime: 总时长
     ///   - completeHander: <#completeHander description#>
     /// - Returns: <#description#>
-    class public func vodeoCoverImageList(videoId: String, videoPath: String, totalTime: Int, videoHeight: CGFloat, videoWidth: CGFloat, completeHander: @escaping (_ coverImages: [PQUploadModel]?, _ msg: String?) -> Void) {
-        SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + vodeoCoverImageUrl, parames: ["id": videoId, "videoPath": videoPath, "totalTime": totalTime]) { response, _, error, _ in
+    public class func vodeoCoverImageList(videoId: String, videoPath: String, totalTime: Int, videoHeight: CGFloat, videoWidth: CGFloat, completeHander: @escaping (_ coverImages: [PQUploadModel]?, _ msg: String?) -> Void) {
+        BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + vodeoCoverImageUrl, parames: ["id": videoId, "videoPath": videoPath, "totalTime": totalTime], commonParams: commonParams()) { response, _, error, _ in
             if error != nil {
                 completeHander(nil, error?.msg)
                 return

+ 1 - 0
BFFramework/Classes/EventTrack/Model/PQVideoMakeEventTrackModel.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 public class PQVideoMakeEventTrackModel: NSObject {
     // 进入创作工具的入口

+ 31 - 21
BFFramework/Classes/EventTrack/ViewModel/PQEventTrackViewModel.swift

@@ -7,6 +7,8 @@
 //
 
 import UIKit
+import BFCommonKit
+import BFNetRequestKit
 
 // MARK: - 埋点数据上报
 
@@ -46,7 +48,7 @@ public class PQEventTrackViewModel: NSObject {
             if extParams != nil, (extParams?.keys.count ?? 0) > 0 {
                 tempParams["extParams"] = dictionaryToJsonString(extParams!)
             }
-            SWNetRequest.postRequestData(url: PQENVUtil.shared.commonapi + staticsFrontendReportUrl, parames: tempParams) { _, _, _, _ in
+            BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.commonapi + staticsFrontendReportUrl, parames: tempParams,commonParams: commonParams()) { _, _, _, _ in
                 BFLog(message: "\(remindmsg ?? "基础")埋点数据上报:\(tempParams)")
             }
         }
@@ -64,27 +66,30 @@ public class PQEventTrackViewModel: NSObject {
     ///   - videoIds: <#videoIds description#>
     ///   - playId: <#playId description#>
     ///   - headVideoId: <#headVideoId description#>
-    public class func videoRelationReportUpload(reportLogType: reportLogType, videoData: PQVideoListModel?, pageSource: PAGESOURCE? = nil, businessType: businessType?, objectType: objectType? = nil, extParams: [String: Any]? = nil, shareId: String? = nil, videoIds: String? = nil, playId: String? = nil, headVideoId: String? = nil) {
+    public class func videoRelationReportUpload(reportLogType: reportLogType, videoData: BFVideoItemProtocol?, pageSource: PAGESOURCE? = nil, businessType: businessType?, objectType: objectType? = nil, extParams: [String: Any]? = nil, shareId: String? = nil, videoIds: String? = nil, playId: String? = nil, headVideoId: String? = nil) {
         var tempExtParams: [String: Any] = extParams ?? [:]
-        if videoData?.reCreateVideoData != nil {
-            tempExtParams["projectId"] = videoData?.reCreateVideoData?.projectId ?? ""
-            tempExtParams["parentProjectId"] = videoData?.reCreateVideoData?.parentProjectId ?? ""
-            tempExtParams["rootProjectId"] = videoData?.reCreateVideoData?.rootProjectId ?? ""
-            tempExtParams["canProduce"] = videoData?.reCreateVideoData?.canReproduce ?? 0
-            if !tempExtParams.keys.contains("clickedVideoId") {
-                tempExtParams["videoId"] = videoData?.uniqueId ?? "0"
-            }
-            if videoData?.reCreateVideoData?.parentVideoId != nil {
-                tempExtParams["parentVideoId"] = videoData?.reCreateVideoData?.parentVideoId ?? ""
+        if videoData is PQVideoListModel {
+            if (videoData as? PQVideoListModel)?.reCreateVideoData != nil {
+                tempExtParams["projectId"] = (videoData as? PQVideoListModel)?.reCreateVideoData?.projectId ?? ""
+                tempExtParams["parentProjectId"] = (videoData as? PQVideoListModel)?.reCreateVideoData?.parentProjectId ?? ""
+                tempExtParams["rootProjectId"] = (videoData as? PQVideoListModel)?.reCreateVideoData?.rootProjectId ?? ""
+                tempExtParams["canProduce"] = (videoData as? PQVideoListModel)?.reCreateVideoData?.canReproduce ?? 0
+                if !tempExtParams.keys.contains("clickedVideoId") {
+                    tempExtParams["videoId"] = "\(videoData?.id ?? 0)"
+                }
+                if (videoData as? PQVideoListModel)?.reCreateVideoData?.parentVideoId != nil {
+                    tempExtParams["parentVideoId"] = (videoData as? PQVideoListModel)?.reCreateVideoData?.parentVideoId ?? ""
+                }
             }
         }
+        
         if objectType == .ot_reproduce_clickButton || objectType == .ot_reproduce_collectionBar || objectType == .ot_reproduce_collectionClicButton || objectType == .ot_reproduce_sameSourceButton {
             PQEventTrackViewModel.baseReportUpload(businessType: businessType, objectType: objectType, pageSource: pageSource != nil ? pageSource! : (videoData?.pageSource ?? .sp_category), extParams: tempExtParams, remindmsg: "再创作上报")
         } else {
-            PQEventTrackViewModel.reportVideoPlayUpload(reportLogType: reportLogType, videoId: videoData?.uniqueId ?? "0", headVideoId: headVideoId ?? videoData?.headVideoId, videoIds: videoIds, pageSource: pageSource != nil ? pageSource! : (videoData?.pageSource ?? .sp_category), playId: playId ?? "", recommendId: videoData?.recommendId, recommendLogVO: videoData?.recommendLogVO, abInfoData: videoData?.abInfoData, measureType: videoData?.measureType, measureId: videoData?.measureId, businessType: businessType, shareId: shareId ?? "", extParams: tempExtParams, objectType: objectType)
+            PQEventTrackViewModel.reportVideoPlayUpload(reportLogType: reportLogType, videoId: "\(videoData?.id ?? 0)", headVideoId: headVideoId ?? videoData?.headVideoId, videoIds: (videoIds == nil ? "\(videoData?.id ?? 0)" : videoIds), pageSource: pageSource != nil ? pageSource! : (videoData?.pageSource ?? .sp_category), playId: playId ?? "", recommendId: videoData?.recommendId, recommendLogVO: videoData?.recommendLogVO, abInfoData: videoData?.abInfoData, measureType: videoData?.measureType, measureId: videoData?.measureId, businessType: businessType, shareId: shareId ?? "", extParams: tempExtParams, objectType: objectType)
         }
     }
-
+    
     /// 播放相关数据上报
     /// - Parameters:
     ///   - reportLogType: 日志类型
@@ -130,11 +135,15 @@ public class PQEventTrackViewModel: NSObject {
             if businessType != nil {
                 tempEventData["businessType"] = businessType?.rawValue
             }
+            tempEventData["pageSource"] = pageSource.rawValue
             // extParams
             var tempExtParams: [String: Any] = extParams ?? [:]
             if headVideoId != nil, (headVideoId?.count ?? 0) > 0 {
                 tempExtParams["headVideoId"] = (headVideoId ?? "0")
             }
+            if videoId.count > 0 {
+                tempExtParams["videoId"] = videoId
+            }
             var url: String = PQENVUtil.shared.longvideoapi
             switch reportLogType {
             case .reportLogType_view:
@@ -159,6 +168,7 @@ public class PQEventTrackViewModel: NSObject {
                     params["rootLaunchShareId"] = shareId
                     params["parentShareId"] = shareId
                     params["shareDepth"] = "0"
+                    params["videoId"] = videoIds
                 }
                 if businessType != nil {
                     params["businessType"] = businessType?.rawValue
@@ -174,7 +184,7 @@ public class PQEventTrackViewModel: NSObject {
             if tempExtParams.keys.count > 0 {
                 params["extParams"] = dictionaryToJsonString(tempExtParams)
             }
-            SWNetRequest.postRequestData(url: url, parames: params) { response, _, error, _ in
+            BFNetRequestAdaptor.postRequestData(url: url, parames: params,commonParams: commonParams()) { response, _, error, _ in
                 BFLog(message: "播放相关数据上报:\(String(describing: error)),\(response ?? [:])")
             }
         }
@@ -241,7 +251,7 @@ public class PQEventTrackViewModel: NSObject {
             if abInfoData != nil, !(abInfoData?.isEmpty ?? true) {
                 params["abInfoData"] = abInfoData
             }
-            SWNetRequest.postRequestData(url: url, parames: params) { response, _, error, _ in
+            BFNetRequestAdaptor.postRequestData(url: url, parames: params,commonParams: commonParams()) { response, _, error, _ in
                 BFLog(message: "用户点击分享数据上报:\(String(describing: error)),\(response ?? [:])")
             }
         }
@@ -319,7 +329,7 @@ public class PQEventTrackViewModel: NSObject {
             if firstParams == nil || ((firstParams?.count ?? 0) <= 0) {
                 saveUserDefaults(key: cFirstParams, value: dictionaryToJsonString(params) ?? "")
             }
-            SWNetRequest.postRequestData(url: PQENVUtil.shared.commonapi + staticsFrontendReportUrl, parames: params) { response, _, error, _ in
+            BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.commonapi + staticsFrontendReportUrl, parames: params,commonParams: commonParams()) { response, _, error, _ in
                 BFLog(message: "冷热启动上报:\(String(describing: error)),\(response ?? [:]),params = \(params)")
                 if PQSingletoMemoryUtil.shared.isColdLaunch {
                     PQSingletoMemoryUtil.shared.coldLaunchStatus = error == nil ? 2 : 3
@@ -357,7 +367,7 @@ public class PQEventTrackViewModel: NSObject {
             if params.keys.contains("aps"){
                 params.removeValue(forKey: "aps")
             }
-            SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + pushActionReportUrl, parames: params) { response, _, error, _ in
+            BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + pushActionReportUrl, parames: params,commonParams: commonParams()) { response, _, error, _ in
                 BFLog(message: "推送点击数据上报:\(String(describing: error)),\(response ?? [:])")
             }
         }
@@ -369,7 +379,7 @@ public class PQEventTrackViewModel: NSObject {
     /// - Returns: <#description#>
     public class func reportPushDeviceTokenUpload(registerId: String, deviceToken: String, completeHander: @escaping (_ isSuccess: Bool) -> Void) {
         DispatchQueue.global().async {
-            SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + pushDeviceTokenReportUrl, parames: ["registerId": registerId, "deviceToken": deviceToken, "brand": cPushChannel]) { response, _, error, _ in
+            BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + pushDeviceTokenReportUrl, parames: ["registerId": registerId, "deviceToken": deviceToken, "brand": cPushChannel],commonParams: commonParams()) { response, _, error, _ in
                 completeHander(error == nil ? true : false)
                 BFLog(message: "deviceToken数据上报:\(String(describing: error)),\(response ?? [:])")
             }
@@ -386,7 +396,7 @@ public class PQEventTrackViewModel: NSObject {
     public class func searchReportUpload(keyWord: String, searchType: Int, searchNumber: Int = 10, reportType: Int = 2) {
         DispatchQueue.global().async {
             let params: [String: Any] = ["keyWord": keyWord, "searchType": searchType, "searchNumber": searchNumber, "reportType": reportType]
-            SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + searchReportUrl, parames: params) { response, _, error, _ in
+            BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + searchReportUrl, parames: params,commonParams: commonParams()) { response, _, error, _ in
                 BFLog(message: "搜索数据上报:\(String(describing: error)),\(response ?? [:])")
             }
         }
@@ -516,7 +526,7 @@ public class PQEventTrackViewModel: NSObject {
             if tempExtParams.keys.count > 0 {
                 tempParams["extParams"] = dictionaryToJsonString(tempExtParams)
             }
-            SWNetRequest.postRequestData(url: PQENVUtil.shared.longvideoapi + messagePeportUrl, parames: tempParams) { _, _, _, _ in
+            BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.longvideoapi + messagePeportUrl, parames: tempParams,commonParams: commonParams()) { _, _, _, _ in
                 BFLog(message: "\(remindmsg ?? "基础")埋点数据上报:\(tempParams)")
             }
         }

+ 1 - 0
BFFramework/Classes/PModels/PQDownloadModel.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFNetRequestKit
 
 // MARK: - 文件扩展名
 

+ 1 - 0
BFFramework/Classes/PModels/PQLoginUserInfo.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 // MARK: - 登录用户信息
 

+ 1 - 0
BFFramework/Classes/PModels/PQReCreateModel.swift

@@ -8,6 +8,7 @@
 
 import RealmSwift
 import UIKit
+import BFCommonKit
 
 public class PQReCreateModel: Object {
     @objc dynamic public var canReproduce: Int = 0 // 是否可以被再创作,1:是,0:否

+ 1 - 0
BFFramework/Classes/PModels/PQUploadModel.swift

@@ -9,6 +9,7 @@
 
 import Photos
 import UIKit
+import BFCommonKit
 
 open class PQUploadModel: PQBaseModel {
    public var image: UIImage? // 图片

+ 1 - 0
BFFramework/Classes/PModels/PQUserInfoModel.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 open class PQUserInfoModel: PQBaseModel {
     public  var avatarUrl: String? // 头像地址

+ 130 - 18
BFFramework/Classes/PModels/PQVideoListModel.swift

@@ -6,13 +6,122 @@
 //  Copyright © 2020 BytesFlow. All rights reserved.
 //
 
+import BFCommonKit
 import UIKit
 
-open class PQVideoListModel: PQBaseModel {
-    @objc required public init() {
+public protocol BFVideoItemProtocol {
+    dynamic var uniqueId: String? { get set } // 唯一ID
+    dynamic var videoId: Int { get set } // 视频ID
+    dynamic var id: UInt64 { get set } // 视频ID
+    dynamic var eventId: String? { get set } // 事件ID
+    dynamic var title: String? { get set } // 标题
+    dynamic var attributedTitle: NSMutableAttributedString? { get set } // 富文本标题
+    dynamic var summary: String? { get set } // 描述
+    dynamic var imageUrl: String { get set } // 图片地址
+    dynamic var selectedImage: String { get set } // 图片地址
+    dynamic var isSelected: Bool { get set }
+    dynamic var recommendLogVO: String? { get set } // 推荐日志对象
+    dynamic var abInfoData: String? { get set } // AB
+    dynamic var pageCategoryId: Int { get set } // 页面分类ID
+    dynamic var version: String { get set } // 版本号
+    dynamic var mid: String { get set } // 设备ID
+    dynamic var date: Int { get set } // 当前时间戳  Float64(Date.init().timeIntervalSince1970) * 1000
+    var headVideoId: String? { get set } // 当前的相关推荐视频是属于哪个视频的相关推荐,值为那个头部视频的videoId
+    var auditStatus: Int { get set } // 审核状态 1 审核中,2 不通过 3 待修改,4 自己可见 5 通过 ,
+    var barrageCount: Int { get set } // 弹幕数量
+    var barrageSwitch: Int { get set } // 是否打开弹幕 1打开 -1关闭 ,
+    var auditReason: String? { get set } // 审核不通过或者待修改的原因
+    var barrage: Any? { get set } // 弹幕集合
+    var chargeDetail: [String: Any]? { get set } // 收费的相关信息
+    var commentCount: Int { get set } // 评论数量
+    var coverImg: [String: Any]? { get set } // 封面对象 ,
+    var cutVoStr: String? { get set } // h5剪切板内容 ,
+    var descr: String? { get set } // 视频简介 ,
+    var encryption: Int { get set } // 是否加密视频:0是1不是 ,
+    var favorited: Bool { get set } // 是否收藏 ,
+    var favoriteds: Int { get set } //  收藏数 ,
+    var fileExtensions: String? { get set } // 视频后缀 ,
+    var firstPicture: Bool { get set } // 封面是否是第一帧,false不是true是 ,
+    var gmtCreate: String? { get set } // 创建时间 ,
+    var gmtCreateDescr: String? { get set } // 发视频时间描述 ,
+    var gmtCreateTimestamp: Int { get set } // 创建时间戳 ,
+    var gmtModifie: String? { get set } // 修改时间 ,
+    var gmtModifiedTimestamp: Int { get set } // 修改时间戳 ,
+    var h5ShareImgPath: String? { get set } // h5分享图URL ,
+    var hasShareSpaceData: Bool { get set } // 是否有分享空间数据,
+    var isRecommendShare: Int { get set } // 是否有分发推荐的封面和标题 1 有 0 无 传空或者不传默认为0,
+    var lastTimestamp: Int { get set } // 时间戳 ,
+    //  liteVideoData (LiteVideoDataVO, optional): lite数据,
+    var measure: Int { get set }
+    var measureId: Int { get set }
+    var measureType: Int { get set } // 0 非流量池 1曝光池2普通推荐测试池3待推荐测试池 ,
+    var playBeforeDay: Int { get set } // 播放时间距离今天的天数 ,
+    var playCount: Int { get set } // 播放次数 ,
+    var playCountFormatStr: String? { get set } //  用户视频总播放数,格式化后的值,前端直接显示 ,
+    var playCountTotal: Int { get set } // 总播放次数 ,
+    var playTime: Int { get set } // 播放时间 ,
+    var processShareHeadLab: [String: Any]? { get set } // 视频分享片尾数据 ,
+    var processShareTailLab: [String: Any]? { get set } // 视频分享片尾数据 ,
+    var pwd: String? { get set } // 视频密码 ,
+    var recommendId: String? { get set } // 推荐链路ID ,
+    var recommendSource: Int { get set } // 0 默认 1 第四范式
+    var recommendStatus: Int { get set } // 推荐状态 ,
+    var rotate: Int { get set } // 旋转角度 ,
+    var sampleJobId: String? { get set }
+    var sampleRequestId: String? { get set }
+    var sampleTotalTime: Int { get set }
+    var sampleTranscodeStatus: Int { get set }
+    var sampleTransedVideoPath: String? { get set }
+    var sendBeforeDay: Int { get set } // 发视频距离今天的天数 ,
+    var sensitiveMsg: String? { get set } // 敏感提示信息 ,
+    var sensitiveStatus: Int { get set } //  内容敏感状态(0:未检验,1:不敏感,2:敏感,3:敏感已审) ,
+    var shareCount: Int { get set } // 分享到朋友圈次数 ,
+    var shareId: String? { get set } // 分享的 ID
+    var shareCountFriend: Int { get set } // 分享到微信好友 ,
+    var shareImgPath: String? { get set } // 分享图URL ,
+    var shareLinkType: Int { get set } // 分享到微信好友的图片的链接的类型 ,
+    var sharePageType: Int { get set } // 0 综合模块 1 feed流 ,
+    var shareTitle: String? { get set } // 分享到微信好友的图片的title ,
+    var showHotRecommend: Bool { get set } // 是否需要显示热门推荐 ,
+    var size: Int { get set } //  大小 ,
+    var status: Int { get set } // 数据状态,1 有效,2 已删除,3 已屏蔽,4 关注可见,5 分享可见 6 自己可见 ,
+    var tabShareImgPath: String? { get set } // 转发分享图URL ,
+    var thumbnailImagePath: String? { get set } // 缩略图URL ,
+    var totalTime: Int { get set } // 视频时长 ,
+    var totalTimeParas: String? { get set } // 视频时长十分秒 ,
+    var transcodeStatus: Int { get set } // 转码状态:1-不需转码 2-转码中 3-转码完成 4-转码失败 ,
+    var transcodeVOList: [Any]? { get set } // 多码率数据 ,
+    var uid: Int { get set } // 视频的用户ID ,
+    var user: [String: Any]? { get set } //  用户对象 ,
+    var videoCollectionId: Int { get set } // 视频所在的视频集ID ,
+    var videoCoverSnapshotPath: String? { get set } // 原始封面图片 ,
+    var videoPath: String? { get set } // 视频地址 ,
+    var videoReportMeta: String? { get set } // 视频上报数据,上报时原样返回 ,
+    var videoShareJumpModel: [String: Any]? { get set } // 分享页跳转的信息 ,
+    var playProgress: Float64 { get set } // 已播放时长
+    var duration: Float64 { get set } // 视频总时长
+    var tab_pageType: TAB_PAGETYPE { get set } // 0-推荐 1-关注
+    var pageSource: PAGESOURCE { get set }
+    var isVerticality: Bool { get set }
+    var isShareList: Bool { get set } // 是否是分享列表
+    var uplpadBucketKey: String? { get set } // 上传视频地址
+    var uplpadStatus: Int { get set } // 上传视频状态  1-上传中 2-上传完成 3-上传失败 4-发布中 4-发布完成
+    var uplpadRequest: OSSMultipartUploadRequest? { get set }
+    var stsToken: [String: Any]? { get set } // 上传信息
+    var localPath: String? { get set } // 地址
+    var progress: Float { get set }
+    var projectId: String? { get set } // 项目ID-发布创作的视频时必传,会在进入创作工具页时生成,以app_no_projectdata为前缀
+    var autoType: autoType? { get set } // autoType 自动动作的类型
+    // 发布视频来源类型
+    var videoFromScene: videoFromScene { get set }
+}
+
+open class PQVideoListModel: PQBaseModel, BFVideoItemProtocol {
+    @objc public required init() {
         super.init()
     }
 
+    public var id: UInt64 = 0
     public var headVideoId: String? // 当前的相关推荐视频是属于哪个视频的相关推荐,值为那个头部视频的videoId
     public var auditStatus: Int = 0 // 审核状态 1 审核中,2 不通过 3 待修改,4 自己可见 5 通过 ,
     public var barrageCount: Int = 0 // 弹幕数量
@@ -103,15 +212,15 @@ open class PQVideoListModel: PQBaseModel {
     public var watchInfoH: CGFloat = 0 // add by ak watch info 高度
     public var watchInfoY: CGFloat = 0 // add by ak watch info Y 值
     public var relationData: [PQVideoListModel]?
-    public var playProgress: CGFloat = 0 // 已播放时长
-    public var duration: CGFloat = 0 // 视频总时长
+    public var playProgress: Float64 = 0 // 已播放时长
+    public var duration: Float64 = 0 // 视频总时长
     public var tab_pageType: TAB_PAGETYPE = .TAB_PAGETYPE_NORMAL // 0-推荐 1-关注
     public var pageSource: PAGESOURCE = .sp_category
     public var isVerticality: Bool = false
     public var isShareList: Bool = false // 是否是分享列表
 
     public var funcH: CGFloat = cDefaultMargin * 33
-    public let funcW: CGFloat = cDefaultMargin * 5
+    public var funcW: CGFloat = cDefaultMargin * 5
     public var uplpadImage: UIImage? // 上传的图片封面
     public var uplpadBucketKey: String? // 上传视频地址
     public var uplpadStatus: Int = 0 // 上传视频状态  1-上传中 2-上传完成 3-上传失败 4-发布中 4-发布完成
@@ -126,15 +235,17 @@ open class PQVideoListModel: PQBaseModel {
     public var autoType: autoType? // autoType 自动动作的类型
     // add by ak 发布视频来源类型
     public var videoFromScene: videoFromScene = .UploadNormal
-    
+
     // 视频分类
-    public var categoryName:String = ""
+    public var categoryName: String = ""
     // 视频分类图
-    public var categoryImage:String?
-    
+    public var categoryImage: String?
+    public var topicInfo: [String: Any]?
     override public init(jsonDict: [String: Any]) {
         super.init(jsonDict: jsonDict)
-
+        if jsonDict.keys.contains("id") {
+            id = UInt64("\(jsonDict["id"] ?? "")") ?? 0
+        }
         if jsonDict.keys.contains("videoPath") {
             videoPath = "\(jsonDict["videoPath"] ?? "")"
             videoURL = videoPath
@@ -176,6 +287,9 @@ open class PQVideoListModel: PQBaseModel {
             user = jsonDict["user"] as? [String: Any]
             userInfo = PQUserInfoModel(jsonDict: user!)
         }
+        if jsonDict.keys.contains("topicInfo") {
+            topicInfo = jsonDict["topicInfo"] as? [String: Any]
+        }
         if jsonDict.keys.contains("shareCountFriend") {
             shareCountFriend = Int("\(jsonDict["shareCountFriend"] ?? "0")") ?? 0
         }
@@ -232,19 +346,19 @@ open class PQVideoListModel: PQBaseModel {
             totalTimeParas = Float64(totalTime).formatDurationToHMS()
         }
         if jsonDict.keys.contains("width") {
-            width = CGFloat(Int("\(jsonDict["width"] ?? 0)") ?? 0)
+            width = CGFloat(Float("\(jsonDict["width"] ?? 0)") ?? 0)
             if rotate > 0 {
-                originImageH = CGFloat(Int("\(jsonDict["width"] ?? 0)") ?? 0)
+                originImageH = width
             } else {
-                originImageW = CGFloat(Int("\(jsonDict["width"] ?? 0)") ?? 0)
+                originImageW = width
             }
         }
         if jsonDict.keys.contains("height") {
-            height = CGFloat(Int("\(jsonDict["height"] ?? 0)") ?? 0)
+            height = CGFloat(Float("\(jsonDict["height"] ?? 0)") ?? 0)
             if rotate > 0 {
-                originImageW = CGFloat(Int("\(jsonDict["height"] ?? 0)") ?? 0)
+                originImageW = height
             } else {
-                originImageH = CGFloat(Int("\(jsonDict["height"] ?? 0)") ?? 0)
+                originImageH = height
             }
         }
         if jsonDict.keys.contains("produceProjectDataV2"), ((jsonDict["produceProjectDataV2"] as? [String: Any])?.keys.count ?? 0) > 0 {
@@ -271,9 +385,7 @@ open class PQVideoListModel: PQBaseModel {
         itemHeight = (cScreenWidth - cDefaultMargin * 3) / 2 * originImageH / originImageW + tempTitleH + cDefaultMargin * 4.5
 
         if title != nil, (title?.count ?? 0) > 0 {
- 
             titleH = sizeWithText(text: title ?? "", font: UIFont.systemFont(ofSize: 26, weight: .medium), size: CGSize(width: cScreenWidth - cDefaultMargin * 2, height: CGFloat.greatestFiniteMagnitude)).height + cDefaultMargin
-
         }
         if titleH > 70 {
             titleH = 70

+ 1 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditAudioTrackMaterialModel.swift

@@ -9,6 +9,7 @@
 import Foundation
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
 
 public class PQEditAudioTrackMaterialModel: PQEditBaseModel {
     /**

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditAudioTrackModel.swift

@@ -15,6 +15,8 @@ import Foundation
 
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
+
 public class PQEditAudioTrackModel: PQEditBaseModel {
     public var audioTrackMaterials: List<PQEditAudioTrackMaterialModel> = List<PQEditAudioTrackMaterialModel>.init()
     @objc dynamic public var count: Int = 0

+ 1 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditBaseModel.swift

@@ -8,6 +8,7 @@
 
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
 
 // 自定义时长转换协议,服务单位为微秒,我们使用 S
 public let timeTransform = TransformOf<Float64, Float64>(fromJSON: { (value: Float64?) -> Float64? in

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditFileMergeTable.swift

@@ -8,6 +8,8 @@
 
 import RealmSwift
 import UIKit
+import BFCommonKit
+
 public class PQEditFileMergeTable: Object {
     // 草稿箱ID 服务端生成
     @objc dynamic public var draftboxId: String = ""

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditProjectModel.swift

@@ -26,6 +26,8 @@
 import Foundation
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
+
 public class PQEditProjectModel: PQEditBaseModel {
     // 大 JSON 结构化数据
     @objc dynamic public var sData: PQEditSdataModel?

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditSdataModel.swift

@@ -9,6 +9,8 @@
 import ObjectMapper
 import RealmSwift
 import UIKit
+import BFCommonKit
+
 public class PQEditSdataModel: PQEditBaseModel {
     @objc dynamic public var systemParam: PQEditSystemParamModel?
     @objc dynamic public var videoMetaData: PQEditVideoMetaDataModel?

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditSectionModel.swift

@@ -15,6 +15,8 @@ import Foundation
 import AVFoundation
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
+
 public class PQEditSectionModel: PQEditBaseModel {
     @objc dynamic public var addAutoEffect: Int = 0
     @objc dynamic public var sectionDuration: Float64 = 0 {

+ 1 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditSectionTimelineModel.swift

@@ -14,6 +14,7 @@
 import Foundation
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
 
 public class PQEditSectionTimelineModel: PQEditBaseModel {
     @objc dynamic public var audioTrack: PQEditAudioTrackModel?

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditSubtitleInfoModel.swift

@@ -9,6 +9,8 @@
 import ObjectMapper
 import RealmSwift
 import UIKit
+import BFCommonKit
+
 public class PQEditSubtitleInfoModel: PQEditBaseModel {
     @objc dynamic public var layoutType: String = ""
     @objc dynamic public var text: String = "" {

+ 2 - 1
BFFramework/Classes/PModels/editDarftModels/PQEditVisionTrackMaterialsModel.swift

@@ -18,6 +18,7 @@ import Photos
 
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
 
 public class PQEditVisionTrackMaterialsModel: PQEditBaseModel {
     @objc dynamic public var width: Float = 0
@@ -215,7 +216,7 @@ public class PQEditVisionTrackMaterialsModel: PQEditBaseModel {
             outSideChannel = "\(jsonDict["outSideChannel"] ?? "")"
         }
 
-//        itemWidth = Float((cScreenWidth - PQChoseMaterialController.itemSpacing * 4) / 3)
+        itemWidth = Float((cScreenWidth - 16 * 4) / 3)
         itemHeight = itemWidth * (height / (width == 0 ? 1 : width))
     }
 

+ 2 - 0
BFFramework/Classes/PModels/editDarftModels/PQEditVisionTrackModel.swift

@@ -14,6 +14,8 @@
 import Foundation
 import ObjectMapper
 import RealmSwift
+import BFCommonKit
+
 public class PQEditVisionTrackModel: PQEditBaseModel {
     @objc dynamic public var count: Int = 0
     @objc dynamic public var duration: Float64 = 0

+ 2 - 0
BFFramework/Classes/PQGPUImage/Source/iOS/MovieOutput.swift

@@ -1,4 +1,5 @@
 import AVFoundation
+import BFCommonKit
 
 public protocol AudioEncodingTarget {
     func activateAudioTrack()
@@ -345,6 +346,7 @@ public class MovieOutput: ImageConsumer, AudioEncodingTarget {
 
             do {
                 try NSObject.catchException {
+                    // SanW - 奔溃 - 201.9.22 10:15
                     if !assetWriterAudioInput.append(sampleBuffer) {
                         debugPrint("WARNING: Trouble appending audio sample buffer: \(String(describing: self.assetWriter.error))")
                     }

+ 1 - 0
BFFramework/Classes/PQGPUImage/Source/iOS/SpeakerOutput.swift

@@ -10,6 +10,7 @@
 import AudioToolbox
 import AVFoundation
 import Foundation
+import BFCommonKit
 
 public class SpeakerOutput: AudioEncodingTarget {
     public var changesAudioSession = true

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/Extension/String+Video.swift

@@ -7,6 +7,7 @@
 //
 
 import Foundation
+import BFCommonKit
 
 public extension Namespace where Base == String {
     static func formatTime(_ time: Int) -> String {

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/PQBaseFilter.swift

@@ -7,6 +7,7 @@
 //  功能:所有 filter 基类
 
 import UIKit
+import BFCommonKit
 
 // 时间精度
 public let BASE_FILTER_TIMESCALE:Int32 = 1_000_000

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/PQGPUImageDebugFilter.swift

@@ -10,6 +10,7 @@ import UIKit
 import OpenGLES
 
 import AVFoundation
+import BFCommonKit
 
 open class PQGPUImageDebug: BasicOperation {
     // ui label

+ 1 - 1
BFFramework/Classes/PQGPUImage/akfilters/PQGPUImageFilterGroup.swift

@@ -7,7 +7,7 @@
 //
 
 import Foundation
-
+import BFCommonKit
 
 open class PQGPUImageFilterGroup: PQBaseFilter{
     

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/PQGPUImageTools.swift

@@ -7,6 +7,7 @@
 //
 
 import Foundation
+import BFCommonKit
 
 #if GLES
     import OpenGLES

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/PQGifFilter.swift

@@ -8,6 +8,7 @@
 
 import Foundation
 import UIKit
+import BFCommonKit
 
 open class PQGifFilter: PQBaseFilter {
     var gifImageCount: Int = 0

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/PQMovieInput.swift

@@ -8,6 +8,7 @@
 
 import AVFoundation
 import VideoToolbox
+import BFCommonKit
 
 public protocol PQMovieInputDelegate: AnyObject {
 

+ 1 - 2
BFFramework/Classes/PQGPUImage/akfilters/PQSubTitleFilter.swift

@@ -8,10 +8,9 @@
 
 import Foundation
 import UIKit
-
 import OpenGLES
-
 import AVFoundation
+import BFCommonKit
 
 // add by ak  if have alpha used discard
 public let AlphaPassthroughFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n     lowp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n     if (color.a < 1.0) \n     {\n         discard;\n     } \n     else\n     {\n         gl_FragColor = color;\n     }\n }\n "

+ 1 - 0
BFFramework/Classes/PQGPUImage/akfilters/Tools/NXAVAssetExportSession.swift

@@ -7,6 +7,7 @@
 //  功能:根据原视频导出新格式视频 如 修改fps
 
 import UIKit
+import BFCommonKit
 
 class NXAVAssetExportSession: NSObject {
     // 使用 Core Animation 框架。设置视频水印、视频标题、动画浮层等。

+ 1 - 1
BFFramework/Classes/PQGPUImage/akfilters/Tools/PQCompositionExporter.swift

@@ -9,7 +9,7 @@
 import AVFoundation
 import Foundation
 import ObjectMapper
-// import GPUImage
+import BFCommonKit
 
 public class PQCompositionExporter {
     public var progressClosure: ((_ currTime: Float, _ duration: Float, _ progress: Float) -> Void)?

+ 80 - 28
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointEditerController.swift

@@ -13,8 +13,10 @@ public enum createStickersModel: Int {
     case createStickersModelOnlyMusic = 3 // 仅配乐
 }
 
+import BFCommonKit
 import Foundation
 import ObjectMapper
+import Photos
 import RealmSwift
 import UIKit
 
@@ -34,7 +36,35 @@ class PQStuckPointEditerController: PQBaseViewController {
     // 选择的图片总数
     var selectedImageDataCount: Int = 0
     // 选中的素材数据
-    var selectedPhotoData: [PQEditVisionTrackMaterialsModel]?
+    var selectedPhotoData: [PHAsset]? {
+        didSet {
+            if selectedPhotoData != nil, (selectedPhotoData?.count ?? 0) > 0 {
+                selectedMetarialData = Array<PQEditVisionTrackMaterialsModel>.init()
+                selectedPhotoData?.forEach { phAsset in
+                    let metarialData = PQEditVisionTrackMaterialsModel()
+                    metarialData.asset = phAsset
+                    metarialData.width = Float(phAsset.pixelWidth)
+                    metarialData.itemWidth = Float(phAsset.pixelWidth)
+                    metarialData.height = Float(phAsset.pixelHeight)
+                    metarialData.itemHeight = Float(phAsset.pixelHeight)
+                    if phAsset.mediaType == .image {
+                        metarialData.type = "image"
+                    } else if phAsset.mediaType == .video {
+                        metarialData.type = "video"
+                        metarialData.duration = Float64(phAsset.duration)
+                    }
+                    metarialData.canvasFillType = phAsset.canvasFillType ?? ""
+                    metarialData.locationPath = phAsset.localPath ?? ""
+                    metarialData.selectedIndex = phAsset.selectedIndex ?? 1
+                    metarialData.originalData = phAsset.originalData
+                    metarialData.coverImageUI = phAsset.image
+                    selectedMetarialData?.append(metarialData)
+                }
+            }
+        }
+    }
+
+    var selectedMetarialData: [PQEditVisionTrackMaterialsModel]?
     // 选中的音乐数据
     var stuckPointMusicData: PQVoiceModel?
     // 保存所有段的所有贴纸,音频信息,用于播放器的渲染使用
@@ -44,6 +74,7 @@ class PQStuckPointEditerController: PQBaseViewController {
     var mStickers: [PQEditVisionTrackMaterialsModel]?
     // 播放器的开始和结束时间,1,刚进界面使用推荐的开始结束时间,2,用户修改起结点时修改
     var playeTimeRange: CMTimeRange = CMTimeRange()
+
     // 首帧图片
     var firstFrameImage: UIImage?{
         didSet{
@@ -87,6 +118,8 @@ class PQStuckPointEditerController: PQBaseViewController {
     // 经过档位处理后的卡点信息
     var stuckPointsTemp: Array = Array<Float>.init()
     var stuckPointsTempInt64: Array = Array<Int64>.init()
+
+
     // 下一步
     lazy var nextBtn: UIButton = {
         let nextBtn = UIButton(type: .custom)
@@ -438,7 +471,7 @@ class PQStuckPointEditerController: PQBaseViewController {
         musicNameView.addCorner(corner: musicNameView.frame.height / 2)
         let musicImageView = UIImageView()
         musicImageView.tintColor = PQBFConfig.shared.styleTitleColor
-        musicImageView.image = UIImage().BF_Image(named: "stuckPoint_reCreate_music").withRenderingMode(.alwaysTemplate)
+        musicImageView.image = UIImage.moduleImage(named: "stuckPoint_reCreate_music", moduleName: "BFFramework", isAssets: false)?.withRenderingMode(.alwaysTemplate)
         musicImageView.frame = CGRect(x: musicNameView.frame.height / 2 - 5, y: (musicNameView.frame.height - 22) / 2, width: 22, height: 22)
         musicNameView.addSubview(musicImageView)
         musicNameLab.frame.origin.x = musicImageView.frame.maxX + 5
@@ -480,8 +513,8 @@ class PQStuckPointEditerController: PQBaseViewController {
                 prepareMeta()
             }
         }
-      
     }
+      
     @objc func enterBackground() {
         BFLog(message: "进入到后台")
         // 取消导出
@@ -665,10 +698,17 @@ class PQStuckPointEditerController: PQBaseViewController {
         settingPlayerView()
     }
 
+        
+      override func viewWillAppear(_ animated: Bool) {
+
+          PQNotification.addObserver(self, selector: #selector(enterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
+      }
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         lineView?.isHidden = true
-        UIApplication.shared.isIdleTimerDisabled = true
+        DispatchQueue.main.async {
+            UIApplication.shared.isIdleTimerDisabled = true
+        }
         musicNameLab.move()
 
         PQNotification.addObserver(self, selector: #selector(enterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
@@ -677,7 +717,9 @@ class PQStuckPointEditerController: PQBaseViewController {
     
     override func viewWillDisappear(_ animated: Bool) {
         super.viewWillDisappear(animated)
-        UIApplication.shared.isIdleTimerDisabled = false
+        DispatchQueue.main.async {
+            UIApplication.shared.isIdleTimerDisabled = false
+        }
         musicNameLab.stop()
         playerView.pause()
 
@@ -689,7 +731,7 @@ class PQStuckPointEditerController: PQBaseViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        leftButton(image: "icon_detail_back", tintColor: PQBFConfig.shared.styleTitleColor)
+        leftButton(image: UIImage(named: "icon_detail_back"), tintColor: PQBFConfig.shared.styleTitleColor)
         navHeadImageView?.addSubview(nextBtn)
         navHeadImageView?.addSubview(musicNameView)
 
@@ -841,17 +883,6 @@ class PQStuckPointEditerController: PQBaseViewController {
     @objc func nextBtnClick(sender _: UIButton) {
         BFLog(message: "去发布")
         playerView.pause()
-        let videoExporter = PQStuckPointPublicController()
-        videoExporter.rhythmMode = currentCreateStickersModel
-        videoExporter.syncedUpVideoSpeedMin = modelSpeed_maxSpeed
-        videoExporter.syncedUpVideoSpeedMax = modelSpeed_minSpeed
-        videoExporter.isReCreate = isReCreate
-        videoExporter.selectedTotalDuration = selectedTotalDuration
-        videoExporter.selectedDataCount = selectedDataCount
-        videoExporter.selectedImageDataCount = selectedImageDataCount
-        videoExporter.finallyUserAudioTime =  Float(finallyStuckPoints.last ?? 0) - Float(finallyStuckPoints.first ?? 0)
-        videoExporter.clipAudioRange = getClipAudioRange()
-        videoExporter.playeTimeRange = playeTimeRange
         // 使用深 copy
         let json = projectModel.toJSONString(prettyPrint: false)
         if json == nil {
@@ -859,10 +890,29 @@ class PQStuckPointEditerController: PQBaseViewController {
             return
         }
         let tempModel: PQEditProjectModel? = Mapper<PQEditProjectModel>().map(JSONString: json!)
-        videoExporter.mStickers = mStickers
-        videoExporter.audioMixModel = stuckPointMusicData
-        videoExporter.editProjectModel = tempModel
-        navigationController?.pushViewController(videoExporter, animated: true)
+        let materialVC: PQStuckPointMaterialController? = navigationController?.viewControllers.first(where: { (vc) -> Bool in
+            vc is PQStuckPointMaterialController
+        }) as? PQStuckPointMaterialController
+
+        if materialVC != nil, materialVC?.isToPublicHandle != nil {
+            materialVC?.isToPublicHandle!(isReCreate, selectedTotalDuration, selectedDataCount, selectedImageDataCount, mStickers, stuckPointMusicData, tempModel)
+        } else {
+            let videoExporter = PQStuckPointPublicController()
+            videoExporter.rhythmMode = currentCreateStickersModel
+            videoExporter.syncedUpVideoSpeedMin = modelSpeed_maxSpeed
+            videoExporter.syncedUpVideoSpeedMax = modelSpeed_minSpeed
+            videoExporter.isReCreate = isReCreate
+            videoExporter.selectedTotalDuration = selectedTotalDuration
+            videoExporter.selectedDataCount = selectedDataCount
+            videoExporter.selectedImageDataCount = selectedImageDataCount
+            videoExporter.finallyUserAudioTime =  Float(finallyStuckPoints.last ?? 0) - Float(finallyStuckPoints.first ?? 0)
+            videoExporter.clipAudioRange = getClipAudioRange()
+            videoExporter.playeTimeRange = playeTimeRange
+            videoExporter.mStickers = mStickers
+            videoExporter.audioMixModel = stuckPointMusicData
+            videoExporter.editProjectModel = tempModel
+            navigationController?.pushViewController(videoExporter, animated: true)
+        }
         // 点击上报:去合成
         PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_commit, pageSource: .sp_stuck_previewSyncedUp, extParams: ["musicName": stuckPointMusicData?.musicName ?? "", "musicId": stuckPointMusicData?.musicId ?? "", "rhythmNumber": stuckPointMusicData?.speed ?? 2, "duration": ((stuckPointMusicData?.endTime ?? 0) - (stuckPointMusicData?.startTime ?? 0)) * 1000], remindmsg: "点击上报:去合成")
     }
@@ -890,7 +940,7 @@ class PQStuckPointEditerController: PQBaseViewController {
         // 1,添加选择的视觉素材
         if projectModel.sData?.sections.count == 0 {
             let section: PQEditSectionModel = PQEditSectionModel()
-            selectedPhotoData?.forEach { model in
+            selectedMetarialData?.forEach { model in
 
                 let json = model.toJSONString(prettyPrint: false)
                 if json == nil {
@@ -998,7 +1048,8 @@ class PQStuckPointEditerController: PQBaseViewController {
             return
         }
 
-        let maxValue = max(videoSize.width, videoSize.height)
+        let maxValue = max(videoSize.width, videoSize.height ?? 0)
+
         if maxValue > 1920 {
             let maxRation = 1920 / maxValue
 
@@ -1236,7 +1287,6 @@ extension PQStuckPointEditerController {
                     if model == .createStickersModelPoint { // 跳跃卡点
                         // 第二种情况:有视频要进行分割
                         let clipFilters = clipVideoMerage(section: section, stuckPoints: finallyStuckPoints)
-                        
                         //数据不一致时要对数据进行二次处理,不是最好方案
                         if(clipFilters.count > finallyStuckPoints.count - 1){
                             clipPoint(clipNum: clipFilters.count - finallyStuckPoints.count, oldPoints: finallyStuckPoints)
@@ -1580,6 +1630,7 @@ extension PQStuckPointEditerController {
                                 BFLog(2, message: "finallyStuckPoints last ;\((finallyStuckPoints.last ?? 0.0) - (finallyStuckPoints.first ?? 0.0)), tmp:\(useAssestDurationTemp)")
     
                             }
+
                             // 2拼接要使用的卡点信息
                             sticker.clipCount = pointCount
                             if stuckPointsTemp.count < 1 {
@@ -1622,6 +1673,7 @@ extension PQStuckPointEditerController {
                                             BFLog(message: "条件不满足不用补位 删除多加的一位")
                                             finallyStuckPoints.removeLast()
                                         }
+
                                     }
                                 }
  */
@@ -1769,13 +1821,13 @@ extension PQStuckPointEditerController {
             exportSession.cancelExport()
         }
         var isHaveVideo: Bool = false
-        if selectedPhotoData != nil, (selectedPhotoData?.count ?? 0) > 0 {
+        if selectedMetarialData != nil, (selectedMetarialData?.count ?? 0) > 0 {
             if synchroMarskView.superview == nil {
                 UIApplication.shared.keyWindow?.addSubview(synchroMarskView)
             }
             let dispatchGroup = DispatchGroup()
 
-            for photo in selectedPhotoData! {
+            for photo in selectedMetarialData! {
                 if photo.asset != nil, photo.asset?.mediaType == .video {
                     if !isHaveVideo {
                         isHaveVideo = true
@@ -1789,11 +1841,11 @@ extension PQStuckPointEditerController {
                             let fileName = (avAsset as! AVURLAsset).url.absoluteString
 
                             BFLog(message: "video  fileName is\(fileName)")
-                            let tempPhoto = self.selectedPhotoData?.first(where: { material in
+                            let tempPhoto = self.selectedMetarialData?.first(where: { material in
                                 material.asset == photo.asset
                             })
 
-                            if (fileName.count) > 0 {
+                            if fileName.count > 0 {
                                 createDirectory(path: photoLibraryDirectory)
                                 let outFilePath = photoLibraryDirectory + fileName.md5 + ".mp4"
                                 // 文件存在先删除老文件

+ 26 - 20
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMaterialController.swift

@@ -7,8 +7,12 @@
 //
 
 import UIKit
+import Photos
+import BFCommonKit
+import BFMaterialKit
 
 public class PQStuckPointMaterialController: PQBaseViewController {
+    public var isToPublicHandle:((_ isReCreate:Bool,_ selectedTotalDuration: Float64,_ selectedDataCount:Int,_ selectedImageDataCount: Int,_ mStickers: [PQEditVisionTrackMaterialsModel]?,_ stuckPointMusicData: PQVoiceModel?,_ editProjectModel: PQEditProjectModel?) -> Void)?
     // 按钮高
     let choseBtnH: CGFloat = cDefaultMargin * 3
     // 按钮宽
@@ -31,8 +35,8 @@ public class PQStuckPointMaterialController: PQBaseViewController {
         changeCollecBtn.titleLabel?.lineBreakMode = .byTruncatingTail
         changeCollecBtn.tintColor = PQBFConfig.shared.styleTitleColor
         changeCollecBtn.setTitle("全部", for: .normal)
-        changeCollecBtn.setImage(UIImage().BF_Image(named: "icon_selected_down").withRenderingMode(.alwaysTemplate), for: .normal)
-        changeCollecBtn.setImage(UIImage().BF_Image(named: "icon_selected_up").withRenderingMode(.alwaysTemplate), for: .selected)
+        changeCollecBtn.setImage(UIImage.moduleImage(named: "icon_selected_down", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .normal)
+        changeCollecBtn.setImage(UIImage.moduleImage(named: "icon_selected_up", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .selected)
         changeCollecBtn.setTitleColor(PQBFConfig.shared.styleTitleColor, for: .normal)
         changeCollecBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .medium)
         changeCollecBtn.tag = 1
@@ -41,8 +45,8 @@ public class PQStuckPointMaterialController: PQBaseViewController {
         return changeCollecBtn
     }()
 
-    lazy var albumController: PQPhotoAlbumController = {
-        let albumController = PQPhotoAlbumController()
+    lazy var albumController: BFPhotoAlbumController = {
+        let albumController = BFPhotoAlbumController()
         albumController.isTopShow = true
         albumController.categoryH = cDefaultMargin * 40
         addChild(albumController)
@@ -138,14 +142,14 @@ public class PQStuckPointMaterialController: PQBaseViewController {
     }()
 
     /// 已选素材列表
-    lazy var materialListView: PQSelectedMaterialListView = {
-        let materialListView = PQSelectedMaterialListView(frame: CGRect(x: 0, y: cScreenHeigth, width: cScreenWidth, height: 88))
+    lazy var materialListView: BFSelectedMaterialListView = {
+        let materialListView = BFSelectedMaterialListView(frame: CGRect(x: 0, y: cScreenHeigth, width: cScreenWidth, height: 88))
         materialListView.deletedMaterialHandle = { [weak self] materialData, isDissmiss in
             /// 处理已经选择的数据
             self?.dealWithSelectedMaterials(isDissmiss: isDissmiss, isChose: false, materialData: materialData)
         }
         materialListView.detailMaterialHandle = { [weak self] _, materialData in
-            let detailVc: PQStuckPointMaterialDetailController = PQStuckPointMaterialDetailController()
+            let detailVc: BFMaterialDetailController = BFMaterialDetailController()
             detailVc.materialDetailClickHandle = { [weak self] isMaterialSelected, materialData in
                 if isMaterialSelected != materialData?.isSelected {
                     self?.photoMaterialVc.updateMaterials(isSelected:!(isMaterialSelected ?? false), materialData: materialData)
@@ -154,6 +158,7 @@ public class PQStuckPointMaterialController: PQBaseViewController {
             if !(materialData?.isSelected ?? false) {
                 materialData?.selectedIndex = (self?.selectedDataCount ?? 0) + 1
             }
+            detailVc.isStuckPoint = true
             detailVc.materialData = materialData
             self?.navigationController?.pushViewController(detailVc, animated: true)
         }
@@ -161,13 +166,12 @@ public class PQStuckPointMaterialController: PQBaseViewController {
     }()
 
     /// 图片加载视图
-    lazy var photoMaterialVc: PQPhotoMaterialController = {
-        let photoMaterialVc = PQPhotoMaterialController()
+    lazy var photoMaterialVc: BFPhotosMaterialController = {
+        let photoMaterialVc = BFPhotosMaterialController()
         photoMaterialVc.isShowMediaTag = false
         photoMaterialVc.imageDuration = 1.5
         addChild(photoMaterialVc)
         view.insertSubview(photoMaterialVc.view, belowSubview: bottomRemindView)
-//        photoMaterialVc.updateFrame(newFrame: CGRect(x: 0, y: materialHeadView.frame.maxY + margin / 2, width: view.frame.width, height: view.frame.height - (materialHeadView.frame.maxY + margin + bottomRemindView.frame.height)))
         photoMaterialVc.updateFrame(newFrame: CGRect(x: 0, y: (navHeadImageView?.frame.maxY ?? cDevice_iPhoneNavBarAndStatusBarHei) + margin / 2, width: view.frame.width, height: view.frame.height - ((navHeadImageView?.frame.maxY ?? cDevice_iPhoneNavBarAndStatusBarHei) + margin + bottomRemindView.frame.height)))
         photoMaterialVc.selectedMaterialHandle = { [weak self] currentMaterialData, selectedPhotoData, selectedTotalDuration, imageCount in
             self?.dealWithSelectedMaterial(materialData: currentMaterialData, selectedDatas: selectedPhotoData, totalDuration: selectedTotalDuration, imageCount: imageCount)
@@ -175,7 +179,8 @@ public class PQStuckPointMaterialController: PQBaseViewController {
             self?.dealWithSelectedMaterials(isDissmiss: selectedPhotoData.count <= 0, isChose: true, materialData: currentMaterialData)
         }
         photoMaterialVc.detailMaterialHandle = { [weak self] _, currentMaterialData in
-            let detailVc: PQStuckPointMaterialDetailController = PQStuckPointMaterialDetailController()
+            let detailVc: BFMaterialDetailController = BFMaterialDetailController()
+            detailVc.isStuckPoint = true
             detailVc.materialDetailClickHandle = { [weak self] isMaterialSelected, materialData in
                 if isMaterialSelected != materialData?.isSelected {
                     self?.photoMaterialVc.updateMaterials(isSelected:!(isMaterialSelected ?? false), materialData: materialData)
@@ -199,7 +204,7 @@ public class PQStuckPointMaterialController: PQBaseViewController {
 
     override public func viewDidLoad() {
         super.viewDidLoad()
-        leftButton(image: "upload_delete", tintColor: PQBFConfig.shared.styleTitleColor)
+        leftButton(image: UIImage.init(named: "upload_delete"), tintColor: PQBFConfig.shared.styleTitleColor)
         navHeadImageView?.addSubview(changeCollecBtn)
         navHeadImageView?.frame.size.height = cDevice_iPhoneNavBarAndStatusBarHei + margin * 2 + choseBtnH
         navHeadImageView?.addSubview(choseLocalAllBtn)
@@ -229,7 +234,6 @@ public class PQStuckPointMaterialController: PQBaseViewController {
             if sender?.isSelected ?? false {
                 albumController.showCategoryView()
             } else {
-                albumController.albaumCollectionView.reloadData()
                 albumController.dismissCategoryView()
             }
         case 10, 11, 12: // 筛选全部图库
@@ -291,21 +295,22 @@ public class PQStuckPointMaterialController: PQBaseViewController {
     /// 图库选择的回调
     /// - Parameter seletedData: <#seletedData description#>
     /// - Returns: <#description#>
-    func albumSelectedHandle(seletedData: PQUploadModel?) {
-        changeCollecBtn.isSelected = false
-        if seletedData == nil {
-            return
-        }
+    func albumSelectedHandle(seletedData: PHAsset?) {
         changeCollecBtn.setTitle(seletedData?.title ?? "全部", for: .normal)
+        changeCollecBtn.isSelected = false
         changeCollecBtn.imagePosition(at: .right, space: cDefaultMargin / 2)
         photoMaterialVc.assetCollection = seletedData?.assetCollection
         photoMaterialVc.msgType = photoMaterialVc.msgType
+//        photoMaterialVc.msgType = .video
+//        choseLocalAllBtn.isSelected = false
+//        choseLocalVideoBtn.isSelected = true
+//        choseLocalImageBtn.isSelected = false
     }
 
     /// 点击选择的回调
     /// - Parameter materialData: <#materialData description#>
     /// - Returns: <#description#>
-    func dealWithSelectedMaterial(materialData _: PQEditVisionTrackMaterialsModel?, selectedDatas: [PQEditVisionTrackMaterialsModel]?, totalDuration: Float64, imageCount: Int) {
+    func dealWithSelectedMaterial(materialData _: PHAsset?, selectedDatas: [PHAsset]?, totalDuration: Float64, imageCount: Int) {
         selectedDataCount = selectedDatas?.count ?? 0
         selectedImageDataCount = imageCount
         confirmBtn.isSelected = (selectedDataCount > 0 && (imageCount >= 2 || selectedDataCount > imageCount))
@@ -325,11 +330,12 @@ public class PQStuckPointMaterialController: PQBaseViewController {
             bottomRemindLab.attributedText = att
         }
         confirmBtn.setTitle(selectedDataCount > 0 ? "确定(\(selectedDataCount))" : "确定", for: .normal)
+
     }
 
     /// 处理已经选择的数据
     /// - Returns: <#description#>
-    func dealWithSelectedMaterials(isDissmiss: Bool, isChose: Bool, materialData: PQEditVisionTrackMaterialsModel?) {
+    func dealWithSelectedMaterials(isDissmiss: Bool, isChose: Bool, materialData: PHAsset?) {
         // 添加当前素材
         if materialData != nil {
             if isChose {

+ 0 - 384
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMaterialDetailController.swift

@@ -1,384 +0,0 @@
-//
-//  PQStuckPointMaterialDetailController.swift
-//  PQSpeed
-//
-//  Created by SanW on 2021/4/27.
-//  Copyright © 2021 BytesFlow. All rights reserved.
-//
-
-import Kingfisher
-import KingfisherWebP
-import UIKit
-
-class PQStuckPointMaterialDetailController: PQBaseViewController {
-    var materialData: PQEditVisionTrackMaterialsModel?
-    // 点击的回调
-    var materialDetailClickHandle: ((_ isMaterialSelected: Bool?, _ materialData: PQEditVisionTrackMaterialsModel?) -> Void)?
-    var isMaterialSelected: Bool?
-    var margin: CGFloat = 35 // 左右间距
-    // 最大的宽度
-    var maxWidth: CGFloat = cScreenWidth
-    // 最大的高度
-    var maxHeight: CGFloat = cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneStatusBarHei
-    // 预览区域宽度
-    var preViewWidth: CGFloat = cScreenWidth
-    // 预览区域高度
-    var preViewHeight: CGFloat = cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneStatusBarHei
-    lazy var preImageView: UIImageView = {
-        let preImageView = UIImageView(frame: CGRect(x: (maxWidth - preViewWidth) / 2, y: cDevice_iPhoneNavBarAndStatusBarHei + (maxHeight - preViewHeight) / 2, width: preViewWidth, height: preViewHeight))
-        preImageView.center.x = view.center.x
-        preImageView.backgroundColor = PQBFConfig.shared.styleBackGroundColor
-        preImageView.contentMode = .scaleAspectFit
-        preImageView.isUserInteractionEnabled = true
-        preImageView.clipsToBounds = true
-        // preImageView.image = UIImage.init(named: "cut_place")
-        return preImageView
-    }()
-
-    lazy var choseTitleBtn: UIButton = {
-        let choseTitleBtn = UIButton(type: .custom)
-        choseTitleBtn.frame = CGRect(x: cScreenWidth - cDefaultMargin * 6, y: 0, width: cDefaultMargin * 5, height: cDefaultMargin * 3)
-        choseTitleBtn.setTitleColor(UIColor.white, for: .normal)
-        choseTitleBtn.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
-        choseTitleBtn.setTitle("取消", for: .selected)
-        choseTitleBtn.setTitle("选择", for: .normal)
-        choseTitleBtn.tag = 2
-        choseTitleBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
-        return choseTitleBtn
-    }()
-
-    lazy var choseBtn: UIButton = {
-        let choseBtn = UIButton(type: .custom)
-        choseBtn.frame = CGRect(x: choseTitleBtn.frame.minX - cDefaultMargin * 3, y: 0, width: cDefaultMargin * 3, height: cDefaultMargin * 3)
-        choseBtn.setBackgroundImage(UIImage().BF_Image(named: "videomk_chose_nomal"), for: .normal)
-        choseBtn.setTitleColor(UIColor.white, for: .normal)
-        choseBtn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
-        choseBtn.tag = 1
-        choseBtn.addCorner(corner: 15)
-        choseBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
-        return choseBtn
-    }()
-
-    lazy var changeModeBtn: UIButton = {
-        let changeModeBtn = UIButton(type: .custom)
-        changeModeBtn.setImage(UIImage().BF_Image(named: "videomk_changeMode"), for: .normal)
-        changeModeBtn.frame = CGRect(x: 15, y: preImageView.frame.height - cDefaultMargin * 4 - 15, width: cDefaultMargin * 4, height: cDefaultMargin * 4)
-        changeModeBtn.tag = 3
-        changeModeBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
-        return changeModeBtn
-    }()
-
-    lazy var gifRemindLab: UILabel = {
-        let gifRemindLab = UILabel(frame: CGRect(x: (preImageView.frame.width - cDefaultMargin * 4) / 2, y: preImageView.frame.height - cDefaultMargin * 3 - 15, width: cDefaultMargin * 4, height: cDefaultMargin * 3))
-        gifRemindLab.textAlignment = .center
-        gifRemindLab.font = UIFont.systemFont(ofSize: 18)
-        gifRemindLab.textColor = UIColor.white
-        gifRemindLab.text = "GIF"
-        return gifRemindLab
-    }()
-
-    lazy var playBtn: UIButton = {
-        let playBtn = UIButton(type: .custom)
-        playBtn.frame = CGRect(x: (preImageView.frame.width - cDefaultMargin * 5) / 2, y: (preImageView.frame.height - cDefaultMargin * 5) / 2, width: cDefaultMargin * 5, height: cDefaultMargin * 5)
-        playBtn.setImage(UIImage().BF_Image(named: "icon_video_play"), for: .normal)
-        playBtn.isUserInteractionEnabled = false
-        playBtn.isHidden = true
-        // playBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
-        return playBtn
-    }()
-
-    lazy var avPlayer: AVPlayer = {
-        let avPlayer = AVPlayer()
-        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem, queue: .main) { [weak self] notify in
-            BFLog(message: "AVPlayerItemDidPlayToEndTime = \(notify)")
-            avPlayer.seek(to: CMTime(value: CMTimeValue((self?.materialData?.model_in ?? 0) * playerTimescale), timescale: CMTimeScale(playerTimescale)))
-            self?.playBtn.isHidden = false
-        }
-        NotificationCenter.default.addObserver(forName: .AVPlayerItemNewErrorLogEntry, object: avPlayer.currentItem, queue: .main) { notify in
-            BFLog(message: "AVPlayerItemNewErrorLogEntry = \(notify)")
-        }
-        NotificationCenter.default.addObserver(forName: .AVPlayerItemFailedToPlayToEndTime, object: avPlayer.currentItem, queue: .main) { notify in
-            BFLog(message: "AVPlayerItemFailedToPlayToEndTime = \(notify)")
-        }
-        NotificationCenter.default.addObserver(forName: .AVPlayerItemPlaybackStalled, object: avPlayer.currentItem, queue: .main) { notify in
-            BFLog(message: "AVPlayerItemPlaybackStalled = \(notify)")
-        }
-        avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: CMTimeScale(playerTimescale)), queue: .main) { [weak self] cmTime in
-            // let progress = CMTimeGetSeconds(avPlayer.currentItem?.currentTime() ?? CMTime.zero) / CMTimeGetSeconds(avPlayer.currentItem?.duration ?? CMTime.zero)
-            let delta = CMTimeGetSeconds(cmTime)
-            let start = CGFloat(delta - (self?.materialData?.model_in ?? 0.0))
-            var endTime: Float64 = self?.materialData?.out ?? 0
-            if endTime <= 0 {
-                endTime = self?.materialData?.duration ?? 0
-            }
-            let total = CGFloat(endTime - (self?.materialData?.model_in ?? 0.0))
-            let progress = start / total
-            if progress >= 1 {
-                self?.playBtn.isHidden = false
-            }
-            BFLog(message: "progress = \(progress)")
-        }
-        return avPlayer
-    }()
-
-    lazy var playerLayer: AVPlayerLayer = {
-        let playerLayer = AVPlayerLayer(player: avPlayer)
-        playerLayer.frame = CGRect(origin: CGPoint.zero, size: preImageView.frame.size)
-        return playerLayer
-    }()
-
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        leftButton(image: "icon_detail_back", tintColor: PQBFConfig.shared.styleTitleColor)
-        navHeadImageView?.backgroundColor = UIColor.clear
-        let width = CGFloat(materialData?.width ?? Float(preViewWidth))
-        let height = CGFloat(materialData?.height ?? Float(preViewHeight))
-        if width >= height {
-            preViewWidth = maxWidth
-            preViewHeight = preViewWidth * height / width
-        } else {
-            preViewHeight = maxHeight
-            preViewWidth = preViewHeight * width / height
-        }
-        lineView?.removeFromSuperview()
-        view.addSubview(preImageView)
-//        preImageView.addSubview(changeModeBtn)
-        if materialData?.type == StickerType.GIF.rawValue {
-            preImageView.addSubview(gifRemindLab)
-            setImageToPreImageView()
-        } else if materialData?.type == StickerType.IMAGE.rawValue {
-            setImageToPreImageView()
-        } else if materialData?.type == StickerType.VIDEO.rawValue {
-            preImageView.addSubview(playBtn)
-            preImageView.layer.insertSublayer(playerLayer, at: 0)
-            let ges = UITapGestureRecognizer(target: self, action: #selector(playPreVideo))
-            preImageView.addGestureRecognizer(ges)
-            // 设置播放内容
-            setPlayerItem()
-        }
-//        updateSelectedState()
-        isMaterialSelected = materialData?.isSelected
-    }
-
-    deinit {
-        if materialData?.type == StickerType.VIDEO.rawValue {
-            avPlayer.replaceCurrentItem(with: nil)
-            PQNotification.removeObserver(self)
-        }
-    }
-
-    /// 设置图片
-    /// - Returns: <#description#>
-    func setImageToPreImageView() {
-        if materialData?.asset != nil {
-            if materialData?.originalData == nil {
-                PQPHAssetVideoParaseUtil.requestAssetOringinImage(asset: (materialData?.asset)!) { [weak self] _, data, image, _ in
-                    if image == nil {
-                        BFLog(message: "图片数据为空!!!!!")
-                    }
-                    // 1,图片,gif的原文件数据,和视频的封面
-                    var newImage: UIImage?
-                    if image != nil {
-                        newImage = UIImage.nx_fixOrientation(image, isFront: false).nx_scaleWithMaxLength(maxLength: 1920)
-                    }
-                    self?.materialData?.coverImageUI = newImage
-                    self?.materialData?.originalData = data
-//                    if isGIF {
-//                        self?.materialData?.type = StickerType.GIF.rawValue
-//                        if self?.gifRemindLab.superview == nil {
-//                            self?.preImageView.addSubview(self!.gifRemindLab)
-//                        }
-//                        self?.preImageView.displayGIF(data: data)
-//                    } else {
-                    self?.preImageView.image = newImage
-//                    }
-                }
-            } else {
-                setNomarlImageToPreImageView()
-            }
-        } else {
-            setNomarlImageToPreImageView()
-        }
-    }
-
-    func setNomarlImageToPreImageView() {
-        if materialData?.type == StickerType.VIDEO.rawValue {
-            return
-        }
-        if materialData?.type == StickerType.GIF.rawValue && materialData?.originalData != nil {
-            preImageView.displayGIF(data: materialData?.originalData)
-        } else if preImageView.image != nil {
-            preImageView.image = preImageView.image
-        } else if preImageView.image == nil && materialData?.coverImageUI != nil {
-            if materialData?.type == StickerType.GIF.rawValue {
-                preImageView.displayGIF(data: kf_imageCacheData(originUrl: materialData?.netResCoverImageURL ?? ""))
-            } else {
-                preImageView.image = materialData?.coverImageUI
-            }
-        } else if materialData?.coverImageUI != nil {
-            preImageView.image = materialData?.coverImageUI
-        } else if materialData?.locationPath.count ?? 0 > 0 {
-            if materialData?.type == StickerType.GIF.rawValue {
-                let fileData: Data = try! Data(contentsOf: URL(fileURLWithPath: documensDirectory + (materialData?.locationPath)!))
-                materialData?.originalData = fileData
-                preImageView.displayGIF(data: materialData?.originalData)
-            } else {
-                var coverImage = UIImage(contentsOfFile: documensDirectory + (materialData?.locationPath)!)
-                if coverImage == nil {
-                    // 有可能是 WEBP
-                    let fileData: Data = try! Data(contentsOf: URL(fileURLWithPath: documensDirectory + (materialData?.locationPath)!))
-                    if fileData.count != 0, fileData.isWebPFormat {
-                        coverImage = WebPProcessor.default.process(item: ImageProcessItem.data(fileData), options: KingfisherParsedOptionsInfo([.onlyLoadFirstFrame, .scaleFactor(1)]))
-                    }
-                }
-                preImageView.image = coverImage
-                materialData?.coverImageUI = coverImage
-            }
-
-        } else if (materialData?.netResCoverImageURL != nil && ((materialData?.netResCoverImageURL?.count ?? 0) > 0)) || (materialData?.materialUrl != nil && ((materialData?.materialUrl.count ?? 0) > 0)) {
-            var url = materialData?.materialUrl
-            if url == nil || (url?.count ?? 0) <= 0 {
-                url = materialData?.netResCoverImageURL
-            }
-            ImageDownloader.default.downloadImage(with: URL(string: url ?? "")!, options: nil) { [weak self] result in
-                switch result {
-                case let .success(imageLoading):
-                    self?.materialData?.originalData = imageLoading.originalData
-                    self?.materialData?.coverImageUI = imageLoading.image
-                    if self?.materialData?.type == StickerType.GIF.rawValue {
-                        self?.preImageView.displayGIF(data: imageLoading.originalData)
-                    } else {
-                        self?.preImageView.image = imageLoading.image
-                    }
-                    let imageOrientation = UIImage.nx_fixOrientation(imageLoading.image, isFront: false).nx_scaleWithMaxLength(maxLength: 1024)
-                    // 下载器的原地址
-                    let diskCachePath = ImageCache.default.cachePath(forKey: url!)
-                    let imageCacheName = url!.md5
-                    let imageCachePath = downloadImagesDirectory + imageCacheName
-                    if !directoryIsExists(dicPath: downloadImagesDirectory) {
-                        BFLog(message: "文件夹不存在 \(downloadImagesDirectory)")
-                        createDirectory(path: downloadImagesDirectory)
-                    }
-                    if self?.materialData?.type != StickerType.GIF.rawValue {
-                        try! imageOrientation.pngData()?.write(to: URL(fileURLWithPath: imageCachePath))
-                    } else {
-                        try! imageLoading.originalData.write(to: URL(fileURLWithPath: imageCachePath))
-                    }
-                    if !FileManager.default.fileExists(atPath: imageCachePath) {
-                        try! FileManager.default.copyItem(atPath: diskCachePath, toPath: downloadImagesDirectory + imageCacheName)
-                    }
-                    if self?.materialData?.type != StickerType.VIDEO.rawValue {
-                        self?.materialData?.locationPath = imageCachePath.replacingOccurrences(of: documensDirectory, with: "")
-                    }
-                case let .failure(error):
-                    BFLog(message: "下载图片失败:\(error.localizedDescription)")
-                }
-            }
-        }
-    }
-
-    /// 预览视频
-    @objc func playPreVideo() {
-        playBtn.isHidden = !playBtn.isHidden
-        if avPlayer.currentItem == nil {
-            setPlayerItem()
-        }
-        if playBtn.isHidden {
-            if playerLayer.superlayer == nil {
-                preImageView.layer.insertSublayer(playerLayer, at: 0)
-            }
-            avPlayer.play()
-        } else {
-            avPlayer.pause()
-        }
-    }
-
-    /// 设置播放item
-    /// - Returns: <#description#>
-    func setPlayerItem() {
-        if materialData?.locationPath.count ?? 0 > 0 {
-            if materialData?.locationPath.contains("mobile/Media/DCIM") ?? false {
-                addPlayItem(playerItem: AVPlayerItem(url: URL(fileURLWithPath: materialData!.locationPath)))
-            } else {
-                addPlayItem(playerItem: AVPlayerItem(url: URL(fileURLWithPath: documensDirectory + materialData!.locationPath)))
-            }
-        } else if materialData?.locationPath.count == 0 && materialData?.asset != nil {
-            PQLoadingHUB.shared.showHUB()
-            PQPHAssetVideoParaseUtil.parasToAVPlayerItem(phAsset: (materialData?.asset)!) { [weak self] playerItem, _, _ in
-                PQLoadingHUB.shared.dismissHUB()
-//                self?.materialData?.locationPath = (playerItem?.asset as? AVURLAsset)?.url.absoluteString.replacingOccurrences(of: "file:///", with: "") ?? ""
-                self?.addPlayItem(playerItem: playerItem)
-            }
-        } else if isValidURL(url: materialData?.netResUrl) {
-            addPlayItem(playerItem: AVPlayerItem(url: URL(string: materialData?.netResUrl ?? "")!))
-        }
-    }
-
-    /// 添加播放
-    /// - Parameter playerItem: <#playerItem description#>
-    func addPlayItem(playerItem: AVPlayerItem?) {
-        avPlayer.replaceCurrentItem(with: playerItem)
-        avPlayer.play()
-        let startTime = materialData?.model_in ?? 0
-        var endTime = materialData?.out ?? 0
-        if endTime <= 0 {
-            endTime = Float64(materialData?.duration ?? 0.0)
-        }
-        avPlayer.seek(to: CMTime(value: CMTimeValue(startTime * playerTimescale), timescale: CMTimeScale(playerTimescale)))
-        avPlayer.currentItem?.forwardPlaybackEndTime = CMTime(value: CMTimeValue(endTime * playerTimescale), timescale: CMTimeScale(playerTimescale))
-    }
-
-    /// 按钮点击事件
-    /// - Parameter sender: <#sender description#>
-    @objc func btnClick(sender: UIButton) {
-        switch sender.tag {
-        case 1, 2:
-            let ratio = (materialData?.width ?? 0) / (materialData?.height ?? 1)
-            if ratio < 0.4 || ratio > 4.2 {
-                cShowHUB(superView: nil, msg: "暂不支持该比例的素材")
-                return
-            }
-            materialData?.isSelected = !(materialData?.isSelected ?? false)
-//            updateSelectedState()
-        default:
-            break
-        }
-    }
-
-    /// 更新选中状态
-    func updateSelectedState() {
-        if materialData?.isSelected ?? false {
-            choseBtn.setBackgroundImage(nil, for: .normal)
-            choseBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
-            if materialData?.selectedIndex == 0 {
-                choseBtn.setTitle("1", for: .normal)
-            } else {
-                choseBtn.setTitle("\(materialData?.selectedIndex ?? 1)", for: .normal)
-            }
-            choseTitleBtn.isSelected = true
-        } else {
-            choseBtn.setBackgroundImage(UIImage().BF_Image(named: "videomk_chose_nomal"), for: .normal)
-            choseBtn.backgroundColor = UIColor.clear
-            choseBtn.setTitle(nil, for: .normal)
-            choseTitleBtn.isSelected = false
-        }
-
-        if materialData?.originalData == nil {
-            materialData?.originalData = kf_imageCacheData(originUrl: materialData?.netResCoverImageURL ?? "")
-            if materialData?.originalData != nil {
-                if materialData?.type == StickerType.GIF.rawValue && materialData?.originalData != nil && (materialData?.duration ?? 0.0) <= 0 {
-                    PQPHAssetVideoParaseUtil.parasGIFImage(data: (materialData?.originalData)!) { [weak self] _, _, duration in
-                        self?.materialData?.duration = duration ?? 0.0
-                    }
-                }
-            }
-        }
-    }
-
-    override func backBtnClick() {
-        if materialDetailClickHandle != nil {
-            materialDetailClickHandle!(isMaterialSelected, materialData)
-        }
-        super.backBtnClick()
-    }
-}

+ 12 - 5
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicContentController.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQStuckPointMusicContentController: PQBaseViewController {
     var itemList: [Any] = Array<Any>.init() // 所有分类数据
@@ -32,11 +33,12 @@ class PQStuckPointMusicContentController: PQBaseViewController {
     var contentType: stuckPointMusicContentType = .catagery {
         didSet {
             if contentType == .page || contentType == .serach {
-                collectionView.addRefreshView(type: .REFRESH_TYPE_FOOTER) { [weak self] isRefresh in
-                    if self?.refreshHandle != nil {
-                        self?.refreshHandle!(isRefresh, self?.contentType ?? .catagery)
-                    }
-                }
+                // SanW - 待修改 - 
+//                collectionView.addRefreshView(type: .REFRESH_TYPE_FOOTER) { [weak self] isRefresh in
+//                    if self?.refreshHandle != nil {
+//                        self?.refreshHandle!(isRefresh, self?.contentType ?? .catagery)
+//                    }
+//                }
             } else {
                 lastIndexPath = IndexPath(item: 0, section: 0)
             }
@@ -86,6 +88,11 @@ class PQStuckPointMusicContentController: PQBaseViewController {
     var emptyData: PQEmptyModel? = {
         let emptyData = PQEmptyModel()
         emptyData.title = "暂无音乐"
+        emptyData.netDisRefreshBgColor = UIColor.hexColor(hexadecimal: "#FA6400")
+        emptyData.netDisTitle = "内容加载失败"
+        emptyData.netDisTitleColor = UIColor.hexColor(hexadecimal: "#333333")
+        emptyData.netemptyDisImage = UIImage.init(named: "empty_netDis_icon")
+        emptyData.netDisRefreshTitle = NSMutableAttributedString(string: "重新加载", attributes: [.font: UIFont.systemFont(ofSize: 16, weight: .medium), .foregroundColor: UIColor.white])
         return emptyData
     }()
 

+ 6 - 6
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicController.swift

@@ -9,7 +9,7 @@
 import AVFoundation
 import UIKit
 import Photos
-
+import BFCommonKit
 
 class PQStuckPointMusicController: PQBaseViewController {
     // 选中的总时长
@@ -21,7 +21,7 @@ class PQStuckPointMusicController: PQBaseViewController {
     weak var stuckPointEditVC : PQStuckPointEditerController?
     var firstFrameImage:UIImage?
     // 选中的素材数据
-    var selectedPhotoData: [PQEditVisionTrackMaterialsModel]?{
+    var selectedPhotoData: [PHAsset]?{
         didSet {
             if selectedPhotoData != nil && selectedPhotoData!.count > 0 {
                 let photo = selectedPhotoData!.first!
@@ -30,7 +30,7 @@ class PQStuckPointMusicController: PQBaseViewController {
                 option.resizeMode = .none
                 option.deliveryMode = .highQualityFormat
                 let startTime = Date()
-                PHImageManager.default().requestImage(for: photo.asset!,
+                PHImageManager.default().requestImage(for: photo!,
                                                       targetSize: CGSize(width: 1920, height: 1920),
                                                       contentMode: .aspectFit,
                                                       options: option)
@@ -101,7 +101,7 @@ class PQStuckPointMusicController: PQBaseViewController {
     // 输入框清空按钮
     lazy var clearBtn: UIButton = {
         let clearBtn = UIButton(type: .custom)
-        clearBtn.setImage(UIImage().BF_Image(named: "icon_search_delete"), for: .normal)
+        clearBtn.setImage(UIImage.moduleImage(named: "icon_search_delete", moduleName: "BFFramework",isAssets: false), for: .normal)
         clearBtn.frame = CGRect(x: 0, y: 0, width: 28, height: 32)
         clearBtn.tag = 1
         clearBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
@@ -120,7 +120,7 @@ class PQStuckPointMusicController: PQBaseViewController {
 
         searchTF.leftViewMode = .always
         let leftView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 32))
-        let imageView = UIImageView(image: UIImage().BF_Image(named: "icon_search_s"))
+        let imageView = UIImageView(image:UIImage.moduleImage(named: "icon_search_s", moduleName: "BFFramework",isAssets: false))
         imageView.frame = CGRect(x: 15, y: 8, width: 16, height: 16)
         leftView.addSubview(imageView)
         searchTF.leftView = leftView
@@ -256,7 +256,7 @@ class PQStuckPointMusicController: PQBaseViewController {
         disablePopGesture().popGestureHandle = { [weak self] in
             self?.backBtnClick()
         }
-        leftButton(image: "icon_detail_back", tintColor: PQBFConfig.shared.styleTitleColor)
+        leftButton(image: UIImage.init(named: "icon_detail_back"), tintColor: PQBFConfig.shared.styleTitleColor)
         setTitle(title: "选择音乐主题", color: PQBFConfig.shared.styleTitleColor)
         view.addSubview(searchTF)
       

+ 1 - 0
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointMusicSearchController.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQStuckPointMusicSearchController: PQStuckPointMusicContentController {
     // 选中的总时长

+ 26 - 16
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointPublicController.swift

@@ -11,6 +11,8 @@ import Photos
 import UIKit
 import WechatOpenSDK
 import Kingfisher
+import BFCommonKit
+
 class PQStuckPointPublicController: PQBaseViewController {
     private var isShared: Bool = false // 是否在分享
     private var isExportSuccess: Bool = false // 是否导出完成
@@ -185,7 +187,7 @@ class PQStuckPointPublicController: PQBaseViewController {
         playerHeaderCoverImageView.clipsToBounds = true
 
         let playBtn = UIButton(type: .custom)
-        playBtn.setImage(UIImage().BF_Image(named: "icon_video_play"), for: .normal)
+        playBtn.setImage(UIImage.moduleImage(named: "icon_video_play", moduleName: "BFFramework",isAssets: false), for: .normal)
         playBtn.tag = 4
         playBtn.isUserInteractionEnabled = false
         playerHeaderCoverImageView.addSubview(playBtn)
@@ -233,7 +235,7 @@ class PQStuckPointPublicController: PQBaseViewController {
     lazy var playBtn: UIButton = {
         let playBtn = UIButton(type: .custom)
         playBtn.frame = CGRect(x: (preViewSize.width - cDefaultMargin * 5) / 2, y: (preViewSize.height - cDefaultMargin * 5) / 2, width: cDefaultMargin * 5, height: cDefaultMargin * 5)
-        playBtn.setImage(UIImage().BF_Image(named: "icon_video_play"), for: .normal)
+        playBtn.setImage(UIImage.moduleImage(named: "icon_video_play", moduleName: "BFFramework",isAssets: false), for: .normal)
         playBtn.tag = 4
         playBtn.isHidden = true
         playBtn.isUserInteractionEnabled = false
@@ -288,7 +290,7 @@ class PQStuckPointPublicController: PQBaseViewController {
     // 手势提示
     lazy var pinView: UIImageView = {
         let pinView = UIImageView()
-        pinView.kf.setImage(with: URL(fileURLWithPath: Bundle().BF_mainbundle().path(forResource: "editCoverPin", ofType: ".gif")!))
+        pinView.kf.setImage(with: URL(fileURLWithPath: (Bundle.current(moduleName: "BFFramework",isAssets: false)?.path(forResource: "editCoverPin", ofType: ".gif")!)!))
         return pinView
     }()
 
@@ -368,7 +370,7 @@ class PQStuckPointPublicController: PQBaseViewController {
     lazy var shareWechatBtn: UIButton = {
         let shareWechatBtn = UIButton(type: .custom)
         shareWechatBtn.frame = CGRect(x: 0, y: 0, width: 70, height: 70)
-        shareWechatBtn.setImage(UIImage().BF_Image(named: "reCreate_opration_wechat"), for: .normal)
+        shareWechatBtn.setImage(UIImage.moduleImage(named: "reCreate_opration_wechat", moduleName: "BFFramework",isAssets: false), for: .normal)
         shareWechatBtn.backgroundColor = PQBFConfig.shared.styleBackGroundColor
         shareWechatBtn.addCorner(corner: 6)
         shareWechatBtn.tag = 2
@@ -380,7 +382,7 @@ class PQStuckPointPublicController: PQBaseViewController {
     lazy var shareFriendBtn: UIButton = {
         let shareFriendBtn = UIButton(type: .custom)
         shareFriendBtn.frame = CGRect(x: 0, y: 0, width: 70, height: 70)
-        shareFriendBtn.setImage(UIImage().BF_Image(named: "reCreate_opration_friend"), for: .normal)
+        shareFriendBtn.setImage(UIImage.moduleImage(named: "reCreate_opration_friend", moduleName: "BFFramework",isAssets: false), for: .normal)
         shareFriendBtn.backgroundColor = PQBFConfig.shared.styleBackGroundColor
         shareFriendBtn.addCorner(corner: 6)
         shareFriendBtn.tag = 1
@@ -448,7 +450,7 @@ class PQStuckPointPublicController: PQBaseViewController {
         // 注册上传成功的通知
         addNotification(self, selector: #selector(uploadSuccess(notify:)), name: cUploadSuccessKey, object: nil)
         PQNotification.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil)
-        leftButton(image: "icon_detail_back", tintColor: PQBFConfig.shared.styleTitleColor)
+        leftButton(image: UIImage.init(named: "icon_detail_back"), tintColor: PQBFConfig.shared.styleTitleColor)
         navHeadImageView?.backgroundColor = UIColor.clear
         lineView?.removeFromSuperview()
         view.addSubview(bgTopView)
@@ -593,9 +595,11 @@ class PQStuckPointPublicController: PQBaseViewController {
         super.viewWillAppear(animated)
         PQNotification.addObserver(self, selector: #selector(enterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
         PQNotification.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
-        UIApplication.shared.isIdleTimerDisabled = true
-
-        // 从相册选择一个照片后回调
+        
+        DispatchQueue.main.async {
+            UIApplication.shared.isIdleTimerDisabled = true
+        }
+        //从相册选择一个照片后回调
         addNotification(self, selector: #selector(imageSelectedImage(notify:)), name: cSelectedImageSuccessKey, object: nil)
 
         #if swift(>=4.2)
@@ -619,7 +623,9 @@ class PQStuckPointPublicController: PQBaseViewController {
 
     override func viewWillDisappear(_ animated: Bool) {
         super.viewWillDisappear(animated)
-        UIApplication.shared.isIdleTimerDisabled = false
+        DispatchQueue.main.async {
+            UIApplication.shared.isIdleTimerDisabled = false
+        }
     }
 
     deinit {
@@ -1132,7 +1138,7 @@ extension PQStuckPointPublicController {
         let tempModel = PQVideoListModel()
         tempModel.title = selectTitle
         tempModel.summary = ""
-        tempModel.duration = CGFloat(uploadData?.duration ?? 0)
+        tempModel.duration = Float64(uploadData?.duration ?? 0)
         tempModel.uplpadImage = uploadData?.image
         tempModel.uplpadBucketKey = uploadRequest?.objectKey
         tempModel.localPath = uploadData?.localPath
@@ -1426,6 +1432,7 @@ extension PQStuckPointPublicController {
         }
 
         PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_changeTitle, pageSource: .sp_stuck_publishSyncedUp, eventData: ["videoId": videoData?.uniqueId ?? "", "rootPageSource": isReCreate ? "shanyinApp-main-syncedUpMusicRecreate" : "shanyinApp-main-syncedUpMusic"], remindmsg: "")
+
     }
 
     @objc func settingCoverImage() {
@@ -1463,12 +1470,15 @@ extension PQStuckPointPublicController {
         }
 
         PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_changeCover, pageSource: .sp_stuck_publishSyncedUp, eventData: ["videoId": videoData?.uniqueId ?? "", "rootPageSource": isReCreate ? "shanyinApp-main-syncedUpMusicRecreate" : "shanyinApp-main-syncedUpMusic"], remindmsg: "")
+
     }
 
     // 更新标题或封面
     func updateCoverImagegOrTitle() {
         PQLoadingHUB.shared.showHUB(isMode: true)
-
+        // SanW - 待修改 -
+//        PQLoadingHUB.shared.showHUB(isMode: true)
+        
         PQBaseViewModel.ossTempToken { [weak self] response, msg in
             let image: UIImage = (self?.uploadData?.image)!
             let data = image.jpegData(compressionQuality: 1)
@@ -1487,9 +1497,10 @@ extension PQStuckPointPublicController {
                 )
                 .uploadObjectAsync(bucketName: bucketName, objectKey: objectKey, data: data!, fileExtensions: "png", imageUploadBlock: { _, code, ossObjectKey, _ in
                     if code == 1 && ossObjectKey == objectKey && ossObjectKey.count > 0 {
-                        // add by ak 这里会在服务器生成分享使用的图片到1-2S 时间
-                        PQUploadViewModel.updateVideo(title: self?.videoData?.title ?? "", videoId: self?.videoData?.uniqueId ?? "", coverImgPath: objectKey, descr: "") { newVideoData, msg in
 
+                        //add by ak 这里会在服务器生成分享使用的图片到1-2S 时间
+                        PQUploadViewModel.updateVideo(title: self?.videoData?.title ?? "", videoId: self?.videoData?.uniqueId ?? "", coverImgPath: objectKey, descr: "") {_, newVideoData, msg in
+                            
                             if newVideoData == nil {
                                 cShowHUB(superView: self?.view, msg: msg)
                                 // 可能有敏感词 要刷一组新标题并自动更新
@@ -1765,8 +1776,7 @@ extension PQStuckPointPublicController {
                 BFLog(message: "下载头像图片失败:\(error.localizedDescription)")
             }
         }
-    
-       
+
     }
     
     

+ 1 - 0
BFFramework/Classes/Stuckpoint/Model/PQStuckPointMusicTagsModel.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 public class PQStuckPointMusicTagsModel: NSObject {
     public var parentTagId: Int64? // 父级 ID(如果是第一层,值为 0) ,

+ 1 - 0
BFFramework/Classes/Stuckpoint/Model/PQVoiceModel.swift

@@ -7,6 +7,7 @@
 //
 
 import Foundation
+import BFCommonKit
 
 public enum voiceStatue: Int {
     case isLoading = 0 // 加载中

+ 1 - 0
BFFramework/Classes/Stuckpoint/View/PQCustomSwitchView.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQCustomSwitchView: UIView {
     /// 当前选中的item

+ 2 - 1
BFFramework/Classes/Stuckpoint/View/PQCuttingPointView.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQCuttingPointView: UIView {
     lazy var pointView: UIView = {
@@ -17,7 +18,7 @@ class PQCuttingPointView: UIView {
     }()
 
     lazy var dragingImageView: UIImageView = {
-        let dragingImageView = UIImageView(image: UIImage().BF_Image(named: "stuckPoint_dragingImage").withRenderingMode(.alwaysTemplate))
+        let dragingImageView = UIImageView(image:UIImage.moduleImage(named: "stuckPoint_dragingImage", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate))
         dragingImageView.tintColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
         return dragingImageView
     }()

+ 4 - 3
BFFramework/Classes/Stuckpoint/View/PQEditPublicCoverImageView.swift

@@ -6,6 +6,7 @@
 //  功能:选择封面
 
 import Foundation
+import BFCommonKit
 
 class PQEditPublicCoverImageView: UIView {
     
@@ -36,7 +37,7 @@ class PQEditPublicCoverImageView: UIView {
     lazy var compliteBtn: UIButton = {
         let compliteBtn = UIButton(type: .custom)
         compliteBtn.frame = CGRect(x: 0, y: 0, width: 70, height: 70)
-        compliteBtn.setImage(UIImage().BF_Image(named: "editCoverimageOk"), for: .normal)
+        compliteBtn.setImage(UIImage.moduleImage(named: "editCoverimageOk", moduleName: "BFFramework",isAssets: false), for: .normal)
         compliteBtn.backgroundColor = PQBFConfig.shared.styleBackGroundColor
         compliteBtn.adjustsImageWhenHighlighted = false
         compliteBtn.tag = 2
@@ -48,7 +49,7 @@ class PQEditPublicCoverImageView: UIView {
     lazy var selectPhotoBtn: UIButton = {
         let selectPhotoBtn = UIButton(type: .custom)
         selectPhotoBtn.frame = CGRect(x: 0, y: 0, width: 70, height: 70)
-        selectPhotoBtn.setImage(UIImage().BF_Image(named: "editCoverimageSelect"), for: .normal)
+        selectPhotoBtn.setImage(UIImage.moduleImage(named: "editCoverimageSelect", moduleName: "BFFramework",isAssets: false), for: .normal)
         selectPhotoBtn.adjustsImageWhenHighlighted = false
         selectPhotoBtn.backgroundColor = PQBFConfig.shared.styleBackGroundColor
         selectPhotoBtn.tag = 1
@@ -88,7 +89,7 @@ class PQEditPublicCoverImageView: UIView {
             coverImageBtn.addTarget(self, action: #selector(coverImageBtnClick(sender:)), for: .touchUpInside)
             //选中后的角标
             let iconView = UIImageView.init(frame: CGRect(x: frame.size.width  - 22.0 - 6, y: 6, width: 22, height: 22))
-            iconView.image = UIImage().BF_Image(named: "editCoverimageSelected")
+            iconView.image = UIImage.moduleImage(named: "editCoverimageSelected", moduleName: "BFFramework",isAssets: false)
           
             iconView.tag = 1000
             if(i == 0){

+ 4 - 2
BFFramework/Classes/Stuckpoint/View/PQEditPublicTitleView.swift

@@ -6,6 +6,7 @@
 //  功能:编辑标题
 
 import Foundation
+import BFCommonKit
 
 class PQEditPublicTitleView: UIView {
     
@@ -35,7 +36,8 @@ class PQEditPublicTitleView: UIView {
         inputTV.backgroundColor = .clear
         inputTV.textColor = .black
         inputTV.maxTextLength = 30
-        inputTV.placeHolderDefultPoint = CGPoint(x: 5, y: 0)
+        // SanW - 待修改
+//        inputTV.placeHolderDefultPoint = CGPoint(x: 5, y: 0)
         inputTV.tintColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
         inputTV.placeHolder = "我见过你眼中的春与秋,胜过我见过的所有山川河流"
         inputTV.showsVerticalScrollIndicator = false
@@ -240,7 +242,7 @@ class PQEditPublicTitleViewContentCell: UICollectionViewCell {
     lazy var iconView: UIImageView = {
         let iconView = UIImageView()
         iconView.backgroundColor = .clear
-        iconView.image = UIImage().BF_Image(named: "editTitleTips")
+        iconView.image = UIImage.moduleImage(named: "editTitleTips", moduleName: "BFFramework",isAssets: false)
         return iconView
     }()
 

+ 1 - 0
BFFramework/Classes/Stuckpoint/View/PQStuckPointCuttingView.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQStuckPointCuttingView: UIView {
     // 视频时长

+ 3 - 2
BFFramework/Classes/Stuckpoint/View/PQStuckPointLoadingView.swift

@@ -8,6 +8,7 @@
 
 import Kingfisher
 import UIKit
+import BFCommonKit
 
 class PQStuckPointLoadingView: UIView {
     var cancelHandle: ((_ sender: UIButton) -> Void)?
@@ -15,7 +16,7 @@ class PQStuckPointLoadingView: UIView {
     lazy var loadingView: UIImageView = {
         let loadingView = UIImageView()
         loadingView.tintColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
-        let data = try? Data(contentsOf: URL(fileURLWithPath: Bundle().BF_mainbundle().path(forResource: "stuckPoint_edit_loading", ofType: ".gif")!))
+        let data = try? Data(contentsOf: URL(fileURLWithPath: (Bundle.current(moduleName: "BFFramework",isAssets: false)?.path(forResource: "stuckPoint_edit_loading", ofType: ".gif")!)!))
         if data != nil {
             PQPHAssetVideoParaseUtil.parasGIFImage(data: data!, isRenderingColor: UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)) { _, images, duration in
                 loadingView.displayGIF(data: nil, images: images, repeatCount: .max, duration: duration ?? 2)
@@ -30,7 +31,7 @@ class PQStuckPointLoadingView: UIView {
         navBarLeftBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -5, right: 0)
         navBarLeftBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -5, right: 0)
         navBarLeftBtn.tintColor = PQBFConfig.shared.styleTitleColor
-        navBarLeftBtn.setImage(UIImage().BF_Image(named: "icon_detail_back").withRenderingMode(.alwaysTemplate), for: .normal)
+        navBarLeftBtn.setImage(UIImage.moduleImage(named: "icon_detail_back", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .normal)
         navBarLeftBtn.addTarget(self, action: #selector(cancelDownload(sender:)), for: .touchUpInside)
         return navBarLeftBtn
     }()

+ 3 - 1
BFFramework/Classes/Stuckpoint/View/PQStuckPointMaterialHeadView.swift

@@ -8,9 +8,11 @@
 
 import SnapKit
 import UIKit
+import BFCommonKit
+
 class PQStuckPointMaterialHeadView: UIView {
     lazy var iconImageView: UIImageView = {
-        let iconImageView = UIImageView(image: UIImage().BF_Image(named: "videomk_netMaterial_selected"))
+        let iconImageView = UIImageView(image:UIImage.moduleImage(named: "videomk_netMaterial_selected", moduleName: "BFFramework",isAssets: false))
         return iconImageView
     }()
 

+ 10 - 9
BFFramework/Classes/Stuckpoint/View/PQStuckPointMusicContentCell.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQStuckPointMusicContentCell: UICollectionViewCell {
     // 按钮点击的回调
@@ -14,7 +15,7 @@ class PQStuckPointMusicContentCell: UICollectionViewCell {
     var contentType: stuckPointMusicContentType = .catagery
 
     lazy var audioImageView: UIImageView = {
-        let audioImageView = UIImageView(image: UIImage().BF_Image(named: "videomk_music_default"))
+        let audioImageView = UIImageView(image:UIImage.moduleImage(named: "videomk_music_default", moduleName: "BFFramework",isAssets: false))
         audioImageView.addCorner(corner: 4)
         audioImageView.contentMode = .scaleAspectFill
         return audioImageView
@@ -29,7 +30,7 @@ class PQStuckPointMusicContentCell: UICollectionViewCell {
 
     lazy var playImageView: UIImageView = {
         let playImageView = UIImageView()
-        playImageView.image = UIImage().BF_Image(named: "stuckPoint_music_pause")
+        playImageView.image = UIImage.moduleImage(named: "stuckPoint_music_pause", moduleName: "BFFramework",isAssets: false)
         return playImageView
     }()
 
@@ -122,23 +123,23 @@ class PQStuckPointMusicContentCell: UICollectionViewCell {
         musicNameLab.isHidden = !(bgmData is PQVoiceModel)
         titleLab.isHidden = (bgmData is PQVoiceModel)
         if bgmData is PQVoiceModel {
-            audioImageView.setNetImage(url: "\((bgmData as? PQVoiceModel)?.avatarUrl ?? "")", placeholder: UIImage().BF_Image(named: "videomk_music_default"))
+            audioImageView.setNetImage(url: "\((bgmData as? PQVoiceModel)?.avatarUrl ?? "")", placeholder: UIImage.moduleImage(named: "videomk_music_default", moduleName: "BFFramework",isAssets: false)!)
             confirmContentView.isHidden = !((bgmData as? PQVoiceModel)?.isSelected ?? false)
             if (bgmData as? PQVoiceModel)?.isSelected ?? false {
                 imageMaskView.isHidden = false
                 playImageView.isHidden = false
                 if (bgmData as? PQVoiceModel)?.isPlaying ?? false {
-//                    if playImageView.image == nil ||  playImageView.image == UIImage().BF_Image(named: "stuckPoint_music_pause"){
+
                     if playImageView.image == nil {
                         playImageView.image = UIImage().BF_Image(named: "loading")
                         startLoadingAnimation()
                     }else {
-                        playImageView.kf.setImage(with: URL(fileURLWithPath: Bundle().BF_mainbundle().path(forResource: "stuckPoint_music_playing", ofType: ".gif")!))
-                    }
+                        playImageView.kf.setImage(with: URL(fileURLWithPath: (Bundle.current(moduleName: "BFFramework",isAssets: false)?.path(forResource: "stuckPoint_music_playing", ofType: ".gif")!)!))
 
+                    }
                     musicNameLab.move()
                 } else {
-                    playImageView.image = UIImage().BF_Image(named: "stuckPoint_music_pause")
+                    playImageView.image = UIImage.moduleImage(named: "stuckPoint_music_pause", moduleName: "BFFramework",isAssets: false)
                     musicNameLab.stop()
                 }
             } else {
@@ -148,9 +149,9 @@ class PQStuckPointMusicContentCell: UICollectionViewCell {
             }
         } else {
             if (bgmData as? PQStuckPointMusicTagsModel)?.tagEmoji != nil {
-                audioImageView.setNetImage(url: "\((bgmData as? PQStuckPointMusicTagsModel)?.tagEmoji ?? "")", placeholder: UIImage().BF_Image(named: "videomk_music_default"))
+                audioImageView.setNetImage(url: "\((bgmData as? PQStuckPointMusicTagsModel)?.tagEmoji ?? "")", placeholder:UIImage.moduleImage(named: "videomk_music_default", moduleName: "BFFramework",isAssets: false)!)
             } else {
-                audioImageView.image = UIImage().BF_Image(named: "videomk_music_default")
+                audioImageView.image = UIImage.moduleImage(named: "videomk_music_default", moduleName: "BFFramework",isAssets: false)
             }
             titleLab.text = " \((bgmData as? PQStuckPointMusicTagsModel)?.tagName ?? "")"
             if (titleLab.text?.count ?? 0) > 8 {

+ 1 - 0
BFFramework/Classes/Stuckpoint/View/PQStuckPointMusicTagsContentCell.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQStuckPointMusicTagsContentCell: UICollectionViewCell {
     lazy var titleLab: UILabel = {

+ 2 - 1
BFFramework/Classes/Stuckpoint/View/PQStuckPointSearchEmptyCell.swift

@@ -7,10 +7,11 @@
 //
 
 import UIKit
+import BFCommonKit
 
 class PQStuckPointSearchEmptyCell: UICollectionViewCell {
     lazy var emptyImageView: UIImageView = {
-        let emptyImageView = UIImageView(image: UIImage().BF_Image(named: "pic_search_empty"))
+        let emptyImageView = UIImageView(image:UIImage.moduleImage(named: "pic_search_empty", moduleName: "BFFramework",isAssets: false))
         emptyImageView.backgroundColor = UIColor.clear
         emptyImageView.contentMode = .scaleAspectFit
         return emptyImageView

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff