Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
陈高翔
/
DreamSleep-iOS
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit eaf290ea
由
cgx
编写于
2022-08-13 18:07:54 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
优化白噪音(无缝播放、KTVHTTPCache)
1 个父辈
93cfbaff
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
157 行增加
和
172 行删除
DreamSleep/DreamSleep.xcodeproj/project.pbxproj
DreamSleep/DreamSleep/Basement/Network/DsCacheUtils.m
DreamSleep/DreamSleep/Class/HomeModule/WhiteNoise/Model/NoisePlayItem.m
DreamSleep/DreamSleep/Class/HomeModule/WhiteNoise/Model/NoisePlayerManager.h
DreamSleep/DreamSleep/Class/HomeModule/WhiteNoise/Model/NoisePlayerManager.m
DreamSleep/Podfile
DreamSleep/Podfile.lock
DreamSleep/DreamSleep.xcodeproj/project.pbxproj
查看文件 @
eaf290e
...
...
@@ -2003,9 +2003,9 @@
isa = PBXGroup;
children = (
D0B5ECB627F2D9E0003EDFE3 /* main.m */,
D0B5ECAD27F2D9DE003EDFE3 /* Main.storyboard */,
D0B5ECA427F2D9DE003EDFE3 /* AppDelegate.h */,
D0B5ECA527F2D9DE003EDFE3 /* AppDelegate.m */,
D0B5ECAD27F2D9DE003EDFE3 /* Main.storyboard */,
D0930F102801124E006B497A /* BaseNaviController.h */,
D0930F112801124E006B497A /* BaseNaviController.m */,
D04B3DA927F6EEB40022F8DF /* DSTabBarController.h */,
...
...
DreamSleep/DreamSleep/Basement/Network/DsCacheUtils.m
查看文件 @
eaf290e
...
...
@@ -6,6 +6,7 @@
//
#import "DsCacheUtils.h"
#import <KTVHTTPCache/KTVHTTPCache.h>
@implementation
DsCacheUtils
...
...
@@ -26,11 +27,16 @@
// size = size + [[SDImageCache sharedImageCache] totalDiskSize];
}
// YYImage缓存
YYImageCache
*
cache
=
[
YYWebImageManager
sharedManager
].
cache
;
NSInteger
discCache
=
cache
.
diskCache
.
totalCost
;
NSInteger
memoryCache
=
cache
.
memoryCache
.
totalCost
;
size
=
size
+
(
discCache
+
memoryCache
);
// 音频缓存
NSInteger
audioCacheSize
=
[
KTVHTTPCache
cacheTotalCacheLength
];
size
+=
audioCacheSize
;
if
(
size
<
0
)
{
return
@"0.0M"
;
}
double
returnSize
=
size
/
1024
.
0
/
1024
.
0
;
return
[
NSString
stringWithFormat
:
@"%.1fM"
,
returnSize
];
...
...
@@ -69,6 +75,9 @@
// }
// }];
}
// 清除音频缓存
[
KTVHTTPCache
cacheDeleteAllCaches
];
}
@end
DreamSleep/DreamSleep/Class/HomeModule/WhiteNoise/Model/NoisePlayItem.m
查看文件 @
eaf290e
...
...
@@ -6,61 +6,36 @@
//
#import "NoisePlayItem.h"
#import <AVFoundation/AVFoundation.h>
#import "NoisePlayerManager.h"
#import <AVFoundation/AVFoundation.h>
/*
播放器当前播放时刻距离完成时刻的时间间隔
即:需要开启循环播放器的时刻
*/
#define NEED_LOOP_PLAY_TIME 1.0
/*
播放器当前播放时刻距离完成时刻的时间间隔
即:需要停止播放器的时刻
*/
#define NEED_STOP_PLAY_TIME .5
@interface
NoisePlayItem
()
/// 系统播放器
@property
(
nonatomic
,
strong
)
AVPlayer
*
player
;
/// 无缝循环播放辅助播放器
@property
(
nonatomic
,
strong
)
AVPlayer
*
loopPlayer
;
/// 当前保存的音频播放器
@property
(
nonatomic
,
strong
)
NSMutableArray
*
allPlayers
;
@end
@implementation
NoisePlayItem
{
id
_timeObserve
;
id
_timeLoopObserve
;
}
-
(
instancetype
)
initWithUrl
:
(
NSString
*
)
url
volume
:
(
float
)
volume
{
if
(
self
=
[
super
init
])
{
self
.
url
=
url
;
self
.
volume
=
volume
;
}
return
self
;
}
-
(
NSArray
*
)
allPlayers
{
if
(
!
_allPlayers
)
{
_allPlayers
=
[
NSMutableArray
array
];
}
return
_allPlayers
;
}
-
(
void
)
setVolume
:
(
float
)
volume
{
_volume
=
volume
;
self
.
player
.
volume
=
volume
;
}
@implementation
NoisePlayItem
#pragma mark - pubilc
-
(
void
)
play
{
if
(
self
.
isSeamlessLoopPlayback
)
{
if
(
self
.
allPlayers
.
count
==
0
)
{
if
(
self
.
player
.
timeControlStatus
!=
AVPlayerTimeControlStatusPlaying
)
{
[
self
.
player
play
];
}
return
;
}
for
(
AVPlayer
*
player
in
self
.
allPlayers
)
{
if
(
player
.
timeControlStatus
!=
AVPlayerTimeControlStatusPlaying
)
{
[
player
play
];
}
}
}
if
(
self
.
isLoopPlayback
)
{
if
(
self
.
player
.
timeControlStatus
!=
AVPlayerTimeControlStatusPlaying
)
{
if
(
self
.
player
.
currentItem
.
error
)
{
[
self
initPlayer
];
}
[
self
.
player
play
];
}
}
...
...
@@ -68,49 +43,43 @@
-
(
void
)
pause
{
if
(
self
.
isSeamlessLoopPlayback
)
{
for
(
AVPlayer
*
player
in
self
.
allPlayers
)
{
if
(
player
.
timeControlStatus
==
AVPlayerTimeControlStatusPlaying
)
{
[
player
pause
];
}
}
}
if
(
self
.
isLoopPlayback
)
{
if
(
self
.
player
.
timeControlStatus
==
AVPlayerTimeControlStatusPlaying
)
{
[
self
.
player
pause
];
}
if
(
self
.
loopPlayer
.
timeControlStatus
==
AVPlayerTimeControlStatusPlaying
)
{
[
self
.
loopPlayer
pause
];
}
}
}
-
(
void
)
stop
{
if
(
self
.
isSeamlessLoopPlayback
)
{
for
(
__strong
AVPlayer
*
player
in
self
.
allPlayers
)
{
if
(
player
.
timeControlStatus
==
AVPlayerTimeControlStatusPlaying
)
{
[
player
pause
];
[
player
seekToTime
:
CMTimeMake
(
0
,
1
)];
if
(
player
==
_player
)
{
[
player
removeTimeObserver
:
_timeObserve
];
_timeObserve
=
nil
;
_player
=
nil
;
}
else
if
(
player
==
_loopPlayer
)
{
[
_loopPlayer
removeTimeObserver
:
_timeLoopObserve
];
_timeLoopObserve
=
nil
;
_loopPlayer
=
nil
;
}
}
}
[
self
.
allPlayers
removeAllObjects
];
}
if
(
self
.
isLoopPlayback
)
{
if
(
self
.
player
.
timeControlStatus
==
AVPlayerTimeControlStatusPlaying
)
{
[
self
.
player
pause
];
[
self
.
player
seekToTime
:
CMTimeMake
(
0
,
1
)];
[
_player
.
currentItem
removeObserver
:
self
forKeyPath
:
@"status"
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
_player
.
currentItem
];
_player
=
nil
;
}
if
(
self
.
loopPlayer
.
timeControlStatus
==
AVPlayerTimeControlStatusPlaying
)
{
[
self
.
loopPlayer
pause
];
[
self
.
loopPlayer
seekToTime
:
CMTimeMake
(
0
,
1
)];
[
_loopPlayer
.
currentItem
removeObserver
:
self
forKeyPath
:
@"status"
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
_loopPlayer
.
currentItem
];
_loopPlayer
=
nil
;
}
}
}
-
(
void
)
setVolume
:
(
float
)
volume
{
_volume
=
volume
;
self
.
player
.
volume
=
volume
;
self
.
loopPlayer
.
volume
=
volume
;
}
#pragma mark - observe
-
(
void
)
observeValueForKeyPath
:
(
NSString
*
)
keyPath
ofObject
:
(
id
)
object
change
:
(
NSDictionary
*
)
change
context
:
(
void
*
)
context
{
AVPlayerItem
*
item
=
object
;
if
([
keyPath
isEqualToString
:
@"status"
])
{
AVPlayerStatus
status
=
[[
change
objectForKey
:
@"new"
]
intValue
];
if
(
status
==
AVPlayerStatusReadyToPlay
)
{
...
...
@@ -118,125 +87,89 @@
[
NoisePlayerManager
sharedNoisePlayerManager
].
isPlaying
=
self
.
isPlaying
;
}
else
if
(
status
==
AVPlayerStatusFailed
)
{
self
.
isPlaying
=
NO
;
DSLog
(
@"AVPlayerStatusFailed"
);
NSError
*
error
=
item
.
error
;
if
(
error
)
{
DSLog
(
@"AVPlayerStatusFailed:%@"
,
item
.
error
);
[
DSProgressHUD
showToast
:
error
.
localizedDescription
];
}
}
else
{
self
.
isPlaying
=
NO
;
DSLog
(
@"AVPlayerStatusUnknown"
);
}
}
else
if
([
keyPath
isEqualToString
:
@"loadedTimeRanges"
])
{
DSLog
(
@"loadedTimeRanges:%@"
,
change
);
}
}
-
(
void
)
playbackFinished
:
(
NSNotification
*
)
notification
{
DSLog
(
@"音频播放完成通知:%@"
,
notification
.
object
);
AVPlayerItem
*
playerItem
=
[
notification
object
];
if
(
self
.
isSeamlessLoopPlayback
)
{
if
(
playerItem
==
_player
.
currentItem
)
{
if
([
self
.
allPlayers
containsObject
:
_player
])
{
[
self
.
allPlayers
removeObject
:
_player
];
}
[
_player
removeTimeObserver
:
_timeObserve
];
_timeObserve
=
nil
;
_player
=
nil
;
}
else
if
(
playerItem
==
_loopPlayer
.
currentItem
)
{
if
([
self
.
allPlayers
containsObject
:
_loopPlayer
])
{
[
self
.
allPlayers
removeObject
:
_loopPlayer
];
}
[
_loopPlayer
removeTimeObserver
:
_timeLoopObserve
];
_timeLoopObserve
=
nil
;
_loopPlayer
=
nil
;
}
}
if
(
self
.
isLoopPlayback
)
{
if
(
self
.
isLoopPlayback
)
{
[
playerItem
seekToTime
:
kCMTimeZero
completionHandler
:
nil
];
[
self
.
player
play
];
}
}
DSLog
(
@"白噪音播放完成:%@"
,
notification
.
object
);
}
-
(
void
)
dealloc
{
if
(
_player
)
{
[
_player
.
currentItem
removeObserver
:
self
forKeyPath
:
@"status"
context
:
nil
];
[
_player
.
currentItem
removeObserver
:
self
forKeyPath
:
@"loadedTimeRanges"
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
_player
.
currentItem
];
}
if
(
_loopPlayer
)
{
[
_loopPlayer
.
currentItem
removeObserver
:
self
forKeyPath
:
@"status"
context
:
nil
];
[
_loopPlayer
.
currentItem
removeObserver
:
self
forKeyPath
:
@"loadedTimeRanges"
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
_loopPlayer
.
currentItem
];
#pragma mark - 初始化
-
(
instancetype
)
initWithUrl
:
(
NSString
*
)
url
volume
:
(
float
)
volume
{
if
(
self
=
[
super
init
])
{
self
.
url
=
url
;
self
.
volume
=
volume
;
[
self
initPlayer
];
[
self
initLoopPlayer
];
}
return
self
;
}
#pragma mark - lazy
-
(
AVPlayer
*
)
player
{
if
(
!
_player
)
{
_player
=
[[
AVPlayer
alloc
]
initWithURL
:[
NSURL
URLWithString
:
self
.
url
]];
_player
.
volume
=
self
.
volume
;
if
(
!
[
self
.
allPlayers
containsObject
:
_player
])
{
[
self
.
allPlayers
addObject
:
_player
];
-
(
void
)
initPlayer
{
self
.
player
=
[
self
getPlayer
];
WS
(
weakSelf
);
[
self
.
player
addPeriodicTimeObserverForInterval
:
CMTimeMake
(
1
.
0
,
10
.
0
)
queue
:
dispatch_get_main_queue
()
usingBlock
:^
(
CMTime
time
)
{
float
current
=
CMTimeGetSeconds
(
time
);
float
duration
=
CMTimeGetSeconds
(
weakSelf
.
player
.
currentItem
.
duration
);
if
(
current
>=
duration
-
NEED_LOOP_PLAY_TIME
)
{
if
(
weakSelf
.
loopPlayer
)
{
[
weakSelf
.
loopPlayer
play
];
}
}
[
_player
.
currentItem
addObserver
:
self
forKeyPath
:
@"status"
options
:
(
NSKeyValueObservingOptionNew
)
context
:
nil
];
[
_player
.
currentItem
addObserver
:
self
forKeyPath
:
@"loadedTimeRanges"
options
:
(
NSKeyValueObservingOptionNew
)
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(
playbackFinished
:
)
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
_player
.
currentItem
];
WS
(
weakSelf
);
_timeObserve
=
[
_player
addPeriodicTimeObserverForInterval
:
CMTimeMake
(
1
.
0
,
10
.
0
)
queue
:
dispatch_get_main_queue
()
usingBlock
:^
(
CMTime
time
)
{
float
current
=
CMTimeGetSeconds
(
time
);
float
total
=
CMTimeGetSeconds
(
weakSelf
.
player
.
currentItem
.
duration
);
// 即将播放完成后,继续播放该音乐
if
(
current
>=
total
-
.
5
)
{
[
weakSelf
.
loopPlayer
play
];
}
}];
}
return
_player
;
if
(
current
>=
duration
-
NEED_STOP_PLAY_TIME
)
{
[
weakSelf
.
player
seekToTime
:
kCMTimeZero
completionHandler
:
^
(
BOOL
finished
)
{
if
(
finished
)
{
[
weakSelf
.
player
pause
];
[
weakSelf
.
player
seekToTime
:
kCMTimeZero
];
}
}];
}
}];
}
-
(
AVPlayer
*
)
loopPlayer
{
if
(
!
_loopPlayer
)
{
_loopPlayer
=
[[
AVPlayer
alloc
]
initWithURL
:[
NSURL
URLWithString
:
self
.
url
]];
_loopPlayer
.
volume
=
self
.
volume
;
if
(
!
[
self
.
allPlayers
containsObject
:
_loopPlayer
])
{
[
self
.
allPlayers
addObject
:
_loopPlayer
];
}
[
_loopPlayer
.
currentItem
addObserver
:
self
forKeyPath
:
@"status"
options
:
(
NSKeyValueObservingOptionNew
)
context
:
nil
];
[
_loopPlayer
.
currentItem
addObserver
:
self
forKeyPath
:
@"loadedTimeRanges"
options
:
(
NSKeyValueObservingOptionNew
)
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(
playbackFinished
:
)
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
_loopPlayer
.
currentItem
];
-
(
void
)
initLoopPlayer
{
self
.
loopPlayer
=
[
self
getPlayer
];
WS
(
weakSelf
);
[
self
.
loopPlayer
addPeriodicTimeObserverForInterval
:
CMTimeMake
(
1
.
0
,
10
.
0
)
queue
:
dispatch_get_main_queue
()
usingBlock
:^
(
CMTime
time
)
{
float
current
=
CMTimeGetSeconds
(
time
);
float
duration
=
CMTimeGetSeconds
(
weakSelf
.
loopPlayer
.
currentItem
.
duration
);
WS
(
weakSelf
);
_timeLoopObserve
=
[
_loopPlayer
addPeriodicTimeObserverForInterval
:
CMTimeMake
(
1
.
0
,
10
.
0
)
queue
:
dispatch_get_main_queue
()
usingBlock
:^
(
CMTime
time
)
{
float
current
=
CMTimeGetSeconds
(
time
);
float
total
=
CMTimeGetSeconds
(
weakSelf
.
loopPlayer
.
currentItem
.
duration
);
// 即将播放完成后,继续播放该音乐
if
(
current
>=
total
-
.
5
)
{
[
weakSelf
.
player
play
];
if
(
!
[
weakSelf
.
allPlayers
containsObject
:
weakSelf
.
player
])
{
[
weakSelf
.
allPlayers
addObject
:
weakSelf
.
player
];
if
(
current
>=
duration
-
NEED_LOOP_PLAY_TIME
)
{
if
(
weakSelf
.
player
)
{
[
weakSelf
.
player
play
];
}
}
if
(
current
>=
duration
-
NEED_STOP_PLAY_TIME
)
{
[
weakSelf
.
loopPlayer
seekToTime
:
kCMTimeZero
completionHandler
:
^
(
BOOL
finished
)
{
if
(
finished
)
{
[
weakSelf
.
loopPlayer
pause
];
[
weakSelf
.
loopPlayer
seekToTime
:
kCMTimeZero
];
}
}
}];
}
return
_loopPlayer
;
}
#pragma mark - others
-
(
void
)
resetMusicPlayer
{
if
(
self
.
player
)
{
[
self
.
player
removeTimeObserver
:
_timeObserve
];
_timeObserve
=
nil
;
}
self
.
player
=
nil
;
}];
}
}];
}
-
(
void
)
resetMusicLoopPlayer
{
if
(
self
.
loopPlayer
)
{
[
self
.
loopPlayer
removeTimeObserver
:
_timeLoopObserve
];
_timeLoopObserve
=
nil
;
}
self
.
loopPlayer
=
nil
;
-
(
AVPlayer
*
)
getPlayer
{
NSString
*
remoteStr
=
[
self
.
url
stringByAddingPercentEncodingWithAllowedCharacters
:[
NSCharacterSet
URLQueryAllowedCharacterSet
]];
NSURL
*
localURL
=
[
KTVHTTPCache
proxyURLWithOriginalURL
:[
NSURL
URLWithString
:
remoteStr
]];
AVPlayerItem
*
playerItem
=
[[
AVPlayerItem
alloc
]
initWithURL
:
localURL
];
[
playerItem
addObserver
:
self
forKeyPath
:
@"status"
options
:
(
NSKeyValueObservingOptionNew
)
context
:
nil
];
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(
playbackFinished
:
)
name
:
AVPlayerItemDidPlayToEndTimeNotification
object
:
playerItem
];
AVPlayer
*
player
=
[
AVPlayer
playerWithPlayerItem
:
playerItem
];
player
.
volume
=
self
.
volume
;
return
player
;
}
@end
DreamSleep/DreamSleep/Class/HomeModule/WhiteNoise/Model/NoisePlayerManager.h
查看文件 @
eaf290e
...
...
@@ -7,6 +7,7 @@
#import <Foundation/Foundation.h>
#import "NoisePlayItem.h"
#import <KTVHTTPCache/KTVHTTPCache.h>
NS_ASSUME_NONNULL_BEGIN
...
...
DreamSleep/DreamSleep/Class/HomeModule/WhiteNoise/Model/NoisePlayerManager.m
查看文件 @
eaf290e
...
...
@@ -15,6 +15,32 @@
@implementation
NoisePlayerManager
SingletonM
(
NoisePlayerManager
)
-
(
instancetype
)
init
{
if
(
self
=
[
super
init
])
{
[
self
setupHTTPCache
];
}
return
self
;
}
-
(
void
)
setupHTTPCache
{
[
KTVHTTPCache
logSetConsoleLogEnable
:
NO
];
NSError
*
error
=
nil
;
[
KTVHTTPCache
proxyStart
:
&
error
];
if
(
error
)
{
DSLog
(
@"Proxy Start Failure, %@"
,
error
);
}
else
{
DSLog
(
@"Proxy Start Success"
);
}
[
KTVHTTPCache
encodeSetURLConverter
:
^
NSURL
*
(
NSURL
*
URL
)
{
DSLog
(
@"URL Filter reviced URL : %@"
,
URL
);
return
URL
;
}];
[
KTVHTTPCache
downloadSetUnacceptableContentTypeDisposer
:
^
BOOL
(
NSURL
*
URL
,
NSString
*
contentType
)
{
DSLog
(
@"Unsupport Content-Type Filter reviced URL : %@, %@"
,
URL
,
contentType
);
return
NO
;
}];
}
#pragma mark - setter/getter
-
(
void
)
setIsPlaying
:
(
BOOL
)
isPlaying
{
_isPlaying
=
isPlaying
;
...
...
@@ -71,7 +97,9 @@ SingletonM(NoisePlayerManager)
BOOL
isPlaying
=
NO
;
for
(
NoisePlayItem
*
item
in
self
.
playItemList
)
{
// 该状态存在不及时
isPlaying
=
item
.
isPlaying
;
if
(
item
.
isPlaying
)
{
isPlaying
=
YES
;
}
[
item
play
];
}
self
.
isPlaying
=
isPlaying
;
...
...
DreamSleep/Podfile
查看文件 @
eaf290e
...
...
@@ -14,6 +14,7 @@ target 'DreamSleep' do
pod
'YYModel'
,
'~> 1.0.4'
pod
'FreeStreamer'
,
'~> 4.0.0'
pod
'IQKeyboardManager'
,
'~> 6.5.10'
pod
'KTVHTTPCache'
,
'~> 2.0.1'
end
# AFNetworking (4.0.1)
...
...
@@ -31,3 +32,4 @@ end
# FreeStreamer(4.0.0)
# IQKeyboardManager(6.5.10)
# JJException(0.2.12)
# KTVHTTPCache(2.0.1)
DreamSleep/Podfile.lock
查看文件 @
eaf290e
...
...
@@ -14,6 +14,7 @@ PODS:
- AFNetworking/Serialization (4.0.1)
- AFNetworking/UIKit (4.0.1):
- AFNetworking/NSURLSession
- CocoaAsyncSocket (7.6.5)
- DKNightVersion (2.4.3):
- DKNightVersion/Core (= 2.4.3)
- DKNightVersion/CoreAnimation (= 2.4.3)
...
...
@@ -31,6 +32,10 @@ PODS:
- FreeStreamer (4.0.0):
- Reachability (~> 3.0)
- IQKeyboardManager (6.5.10)
- KTVCocoaHTTPServer (1.0.0):
- CocoaAsyncSocket
- KTVHTTPCache (2.0.1):
- KTVCocoaHTTPServer
- lottie-ios (2.5.3)
- Masonry (1.1.0)
- MBProgressHUD (1.2.0)
...
...
@@ -53,6 +58,7 @@ DEPENDENCIES:
- DOUAudioStreamer (~> 0.2.16)
- FreeStreamer (~> 4.0.0)
- IQKeyboardManager (~> 6.5.10)
- KTVHTTPCache (~> 2.0.1)
- lottie-ios (~> 2.5.3)
- Masonry (~> 1.1.0)
- MBProgressHUD (~> 1.2.0)
...
...
@@ -64,10 +70,13 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- AFNetworking
- CocoaAsyncSocket
- DKNightVersion
- DOUAudioStreamer
- FreeStreamer
- IQKeyboardManager
- KTVCocoaHTTPServer
- KTVHTTPCache
- lottie-ios
- Masonry
- MBProgressHUD
...
...
@@ -80,10 +89,13 @@ SPEC REPOS:
SPEC CHECKSUMS:
AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DKNightVersion: eaa80cc4014b4bae7d4b535fd87ecc6a3c2767b3
DOUAudioStreamer: c503ba2ecb9a54ff7bda0eff66963ad224f3c7dc
FreeStreamer: 7e9c976045701ac2f7e9c14c17245203c37bf2ea
IQKeyboardManager: 45a1fa55c1a5b02c61ac0fd7fd5b62bb4ad20d97
KTVCocoaHTTPServer: df8d7b861e603ff8037e9b2138aca2563a6b768d
KTVHTTPCache: 588c3eb16f6bd1e6fde1e230dabfb7bd4e490a4d
lottie-ios: a50d5c0160425cd4b01b852bb9578963e6d92d31
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
...
...
@@ -94,6 +106,6 @@ SPEC CHECKSUMS:
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
PODFILE CHECKSUM:
e4359ec13a52ba4e49c7d0c1466b596eceaf7b77
PODFILE CHECKSUM:
b808024d124d43764129a7c9916691de21d3b921
COCOAPODS: 1.11.3
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论