VIMUpload
是一个Objective-C库,它能够将视频上传到Vimeo。其核心组件是一个串行任务队列,执行组合任务(具有子任务的作业)。
上传系统使用配置的背景NSURLSession来管理视频上传的队列(即在应用在前台或后台时,上传都会继续)。如果您计划在应用内部以及扩展中初始化上传,则可以配置为管理两个后台会话。
上传队列可以暂停和恢复,当失去或恢复互联网连接时,它会自动暂停/恢复。它还可以配置为仅将上传限制在WiFi上。
队列被持久化到磁盘,以便在应用终止事件发生时能够重建到终止前的状态。
如果您想要与Vimeo API进行交互,但不仅是视频上传,请查看VIMNetworking。
查看Pegasus示例项目。
将VIMUpload
和AFNetworking
(版本2.5.4)添加为git仓库的子模块。
git submodule add [email protected]:vimeo/VIMUpload.git
git submodule add [email protected]:AFNetworking/AFNetworking.git
将每个子模块的类添加到您的项目/目标中。
如果您还包括VIMNetworking
在项目/目标中,请注意,VIMUpload
和VIMNetworking
都包含Certificate/digicert-sha2.cer
文件(此文件用于证书固定)。您需要从目标中删除一个digicert-sha2.cer
文件,以避免出现“为输出文件生成多个构建命令...”警告。
子类化 VIMTaskQueue
并实现单例对象
+ (instancetype)sharedAppQueue
{
static MYUploadTaskQueueSubclass *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// A background configuration with optional shared container identifier (if you plan on uploading from an extension)
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithID:@"your_session_identifier" sharedContainerID:@"your_optional_shared_container_identifier"];
VIMUploadSessionManager *sessionManager = [[VIMUploadSessionManager alloc] initWithSessionConfiguration:configuration];
sessionManager.requestSerializer = ...;
// Where client.requestSerializer is an AFJSONRequestSerializer subclass that serializes the following information on each request:
// [serializer setValue:@"application/vnd.vimeo.*+json; version=3.2" forHTTPHeaderField:@"Accept"];
// [serializer setValue:@"Bearer your_oauth_token" forHTTPHeaderField:@"Authorization"];
sharedInstance = [[self alloc] initWithSessionManager:sessionManager];
});
return sharedInstance;
}
如果您打算从扩展中开始上传,则将需要使用一个单独的 VIMUploadTaskQueue
实例,使用单独的 VIMNetworkTaskSessionManager
初始化,使用单独的后台会话标识符初始化。
在每次应用程序启动时加载您的 VIMUploadTaskQueue
(s)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
[MYUploadTaskQueueSubclass sharedAppQueue];
[MYUploadTaskQueueSubclass sharedExtensionQueue];
return YES;
}
在您的 AppDelegate 中实现 application:handleEventsForBackgroundURLSession:completionHandler:
方法
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
if ([identifier isEqualToString:[MYUploadTaskQueueSubclass sharedAppQueue].sessionManager.session.configuration.identifier])
{
[MYUploadTaskQueueSubclass sharedAppQueue].sessionManager.completionHandler = completionHandler;
}
else if ([identifier isEqualToString:[MYUploadTaskQueueSubclass sharedExtensionQueue].sessionManager.session.configuration.identifier])
{
[MYUploadTaskQueueSubclass sharedExtensionQueue].sessionManager.completionHandler = completionHandler;
}
}
为上传将 PHAsset
排队
PHAsset *asset = ...;
VIMVideoAsset *videoAsset = [[VIMVideoAsset alloc] initWithPHAsset:asset];
[[MYUploadTaskQueueSubclass sharedAppQueue] uploadVideoAssets:@[videoAsset]];
为上传将 AVURLAsset
排队
NSURL *URL = ...;
AVURLAsset *URLAsset = [AVURLAsset assetWithURL:URL];
BOOL canUploadFromSource = ...; // If the asset doesn't need to be copied to a tmp directory before upload, set this to YES
VIMVideoAsset *videoAsset = [[VIMVideoAsset alloc] initWithURLAsset:URLAsset canUploadFromSource:canUploadFromSource];
[[MYUploadTaskQueueSubclass sharedAppQueue] uploadVideoAssets:@[videoAsset]];
为上传将多个资源排队
NSArray *videoAssets = @[...];
[[MYUploadTaskQueueSubclass sharedAppQueue] uploadVideoAssets:videoAssets];
取消上传
VIMVideoAsset *videoAsset = ...;
[[MYUploadTaskQueueSubclass sharedAppQueue] cancelUploadForVideoAsset:videoAsset];
取消所有上传
[[MYUploadTaskQueueSubclass sharedAppQueue] cancelAllUploads];
暂停所有上传
[[MYUploadTaskQueueSubclass sharedAppQueue] pause];
恢复所有上传
[[MYUploadTaskQueueSubclass sharedAppQueue] resume];
确保仅在通过 Wi-Fi 连接...或否则上传发生。如果 cellularUploadEnabled
设置为 NO
,则在离开 Wi-Fi 时上传队列将自动暂停,并在进入 Wi-Fi 时自动恢复。(注意:当设备脱机/上线时,队列将自动暂停/恢复。)
[MYUploadTaskQueueSubclass sharedAppQueue].cellularUploadEnabled = NO;
向排队的或正在进行的上传添加视频元数据
VIMVideoAsset *videoAsset = ...;
VIMVideoMetadata *videoMetadata = [[VIMVideoMetadata alloc] init];
videoMetadata.videoTitle = @"Really cool title";
videoMetadata.videoDescription = @"Really cool description"";
videoMetadata.videoPrivacy = (NSString *)VIMPrivacyValue_Private;
[[MYUploadTaskQueueSubclass sharedAppQueue] addMetadata:videoMetadata toVideoAsset:videoAsset withCompletionBlock:^(BOOL didAdd) {
if (!didAdd)
{
// The upload has already finished,
// Set the metadata using the VIMAPIClient method updateVideoWithURI:title:description:privacy:completionHandler:
}
}];
如果您构建的 UI 支持暂停和恢复,请监听 VIMNetworkTaskQueue_DidSuspendOrResumeNotification
通知并根据您的 UI 更新
- (void)addObservers
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(uploadTaskQueueDidSuspendOrResume:) name:VIMNetworkTaskQueue_DidSuspendOrResumeNotification object:nil];
}
- (void)uploadTaskQueueDidSuspendOrResume:(NSNotification *)notification
{
BOOL isSuspended = [[MYUploadTaskQueueSubclass sharedAppQueue] isSuspended];
[self.pauseResumeButton setSelected:isSuspended];
}
使用 KVO 通过您的 UI 传达上传状态和上传进度。观察 VIMVideoAsset
的 uploadState
和 uploadProgressFraction
属性的变化。
static void *UploadStateContext = &UploadStateContext;
static void *UploadProgressContext = &UploadProgressContext;
- (void)addObservers
{
[self.videoAsset addObserver:self forKeyPath:NSStringFromSelector(@selector(uploadState)) options:NSKeyValueObservingOptionNew context:UploadStateContext];
[self.videoAsset addObserver:self forKeyPath:NSStringFromSelector(@selector(uploadProgressFraction)) options:NSKeyValueObservingOptionNew context:UploadProgressContext];
}
- (void)removeObservers
{
@try
{
[self.videoAsset removeObserver:self forKeyPath:NSStringFromSelector(@selector(uploadState)) context:UploadStateContext];
}
@catch (NSException *exception)
{
NSLog(@"Exception removing observer: %@", exception);
}
@try
{
[self.videoAsset removeObserver:self forKeyPath:NSStringFromSelector(@selector(uploadProgressFraction)) context:UploadProgressContext];
}
@catch (NSException *exception)
{
NSLog(@"Exception removing observer: %@", exception);
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (context == UploadStateContext)
{
if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadState))])
{
dispatch_async(dispatch_get_main_queue(), ^{
[self uploadStateDidChange];
});
}
}
else if (context == UploadProgressContext)
{
if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadProgressFraction))])
{
dispatch_async(dispatch_get_main_queue(), ^{
[self uploadProgressDidChange];
});
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
当您的 UI 加载或刷新时,将您刚创建的 VIMVideoAsset 对象与其上传任务对应物关联起来,以确保您的 UI 继续传达上传状态和进度。
NSArray *videoAssets = self.datasource.items; // For example
[[MYUploadTaskQueueSubclass sharedAppQueue] associateVideoAssetsWithUploads:videoAssets];
VIMUpload
可在 MIT 许可下使用。有关更多信息,请参阅 LICENSE 文件。
在这里给我们发推文:@vimeoapi
在带有 vimeo-ios
标记的 Stackoverflow 上发布
在这里联系:[链接]