Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Commit

Permalink
Merge pull request #175 from vimeo/release/3.0.1
Browse files Browse the repository at this point in the history
Release/3.0.1
  • Loading branch information
mikew-personal authored Aug 15, 2017
2 parents 4faa513 + 0da675b commit 75cc4f9
Show file tree
Hide file tree
Showing 20 changed files with 609 additions and 316 deletions.
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ SPEC CHECKSUMS:
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
VimeoNetworking: 17f8d451e4a168044f619315d0cd821669676e67

PODFILE CHECKSUM: 1effa997066c11f594672c4411d368973a769d6f
PODFILE CHECKSUM: a8a935f97d6d50906dbff286cd02db46fdd6f52c

COCOAPODS: 1.1.1
2 changes: 1 addition & 1 deletion Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

586 changes: 311 additions & 275 deletions Pods/Pods.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# VimeoNetworking [![](https://circleci.com/gh/vimeo/VimeoNetworking.png?style=shield&circle-token=0443de366b231f05e3b1b1b3bf64a434b9ec1cfe)](https://circleci.com/gh/vimeo/VimeoNetworking)

**VimeoNetworking** is the authoritative Swift networking library for the Vimeo API. Fully designed and implemented with Swift in mind, **VimeoNetworking** is type-safe, well `enum`erated, and never, ever, *ever* force-unwrapped.
**VimeoNetworking** is the authoritative Swift networking library for the Vimeo API. Fully designed and implemented with Swift in mind, **VimeoNetworking** is type-safe, well `enum`erated, and never, ever, *ever* force-unwrapped.

##### Hey Creator, if you're primarily interested in uploading videos to Vimeo, you should also check out [VimeoUpload](https://github.com/vimeo/VimeoUpload).

Expand All @@ -9,15 +9,16 @@
- iOS (8.0+)
- tvOS (9.0+)

## Installing with CocoaPods
## Installing
At this stage of development VimeoNetworking is not yet available as a CocoaPod via the public Podspecs repo. For now we recommend including it in your project as a submodule. If you'd still like to work with VimeoNetworking as a development pod, simply configure your Podfile as shown below.

To get started integrating `VimeoNetworking`, add the following lines to your `Podfile` and run `pod install`:

```Ruby
use_frameworks! # required for Swift frameworks

target 'YourAppTargetName' do
pod 'VimeoNetworking', '1.0'
pod 'VimeoNetworking', './Submodules/VimeoNetworking'
end
```

Expand Down Expand Up @@ -52,15 +53,15 @@ Before we can actually start getting meaningful data from the API, there's one l

Client credentials allow you to see everything that's publicly available on Vimeo. This is essentially equivalent to visiting Vimeo.com without signing up for an account or logging in. This is the simplest authentication method to implement, just one function completes the grant.

```Swift
```Swift
let authenticationController = AuthenticationController(client: vimeoClient)

authenticationController.clientCredentialsGrant { result in
authenticationController.clientCredentialsGrant { result in
switch result {
case .Success(let account):
print("Successfully authenticated with account: \(account)")
case .Failure(let error):
print("error authenticating: \(error)")
print("error authenticating: \(error)")
}
}
```
Expand Down Expand Up @@ -88,15 +89,15 @@ The user will be prompted to log in and grant permissions to your application.
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool
{
authenticationController.codeGrant(responseURL: url) { result in
switch result
switch result
{
case .Success(let account):
print("authenticated successfully: \(account)")
case .Failure(let error):
print("failure authenticating: \(error)")
}
}

return true
}
```
Expand All @@ -123,18 +124,18 @@ authenticationController.accessToken("your_access_tocken") { result in
`AuthenticationController` saves the accounts it successfully authenticates in the Keychain. The next time your application launches, you should first attempt to load a previously authenticated account before prompting the user to authenticate.

```Swift
do
do
{
if let account = try authenticationController.loadSavedAccount()
if let account = try authenticationController.loadSavedAccount()
{
print("account loaded successfully: \(account)"
}
else
}
else
{
print("no saved account found, authenticate...")
}
}
catch let error
catch let error
{
print("error loading account: \(error)")
}
Expand Down Expand Up @@ -163,7 +164,7 @@ By declaring the expected model object type, we can ensure that both the request
After we send that request, we'll get a `Result` enum back. This could be either a `.Success` or a `.Failure` value. `.Success` will contain a `Response` object, while `.Failure` will contain an `NSError`. Switch between these two cases to handle whichever is encountered:

```Swift
vimeoClient.request(videoRequest) { result in
vimeoClient.request(videoRequest) { result in
switch result {
case .Success(let response: Response):
let video: VIMVideo = response.model
Expand All @@ -182,12 +183,12 @@ One neat **ProTip**: Your `Request` model type doesn't just have to be a single
```Swift
let staffPickedVideosRequest = Request<[VIMVideo]>(path: "/channels/staffpicks/videos")

vimeoClient.request(staffPickedVideosRequest) { result in
switch result
vimeoClient.request(staffPickedVideosRequest) { result in
switch result
{
case .Success(let response: Response):
let videos: [VIMVideo] = response.model
for video in videos
for video in videos
{
print("retrieved video: \(video)")
}
Expand Down
12 changes: 9 additions & 3 deletions VimeoNetworking/Sources/Models/Subscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public class Subscription: VIMModelObject
/// Represents wether the user is subscribed to the `share` notification.
var share: NSNumber?

/// Represents wether the is subscribed to the `New video available from followed user` notification.
var followedUserVideoAvailable: NSNumber?

/// Represents the Subscription object as a Dictionary
public var toDictionary: [AnyHashable: Any]
{
Expand All @@ -55,7 +58,8 @@ public class Subscription: VIMModelObject
"follow": self.follow ?? false,
"vod_preorder_available": self.vodPreorderAvailable ?? false,
"video_available": self.videoAvailable ?? false,
"share": self.share ?? false]
"share": self.share ?? false,
"followed_user_video_available": self.followedUserVideoAvailable ?? false]

return dictionary
}
Expand All @@ -68,7 +72,8 @@ public class Subscription: VIMModelObject
"video_available": "videoAvailable",
"vod_preorder_available": "vodPreorderAvailable",
"vod_rental_expiration_warning": "vodRentalExpirationWarning",
"account_expiration_warning": "accountExpirationWarning"]
"account_expiration_warning": "accountExpirationWarning",
"followed_user_video_available": "followedUserVideoAvailable"]
}

// MARK: - Helpers
Expand All @@ -86,6 +91,7 @@ public class Subscription: VIMModelObject
self.follow == false &&
self.vodPreorderAvailable == false &&
self.videoAvailable == false &&
self.share == false)
self.share == false &&
self.followedUserVideoAvailable == false)
}
}
3 changes: 2 additions & 1 deletion VimeoNetworking/Sources/Models/VIMNotification.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ typedef NS_ENUM(NSUInteger, VIMNotificationType) {
VIMNotificationTypeFollow,
VIMNotificationTypeLike,
VIMNotificationTypeReply,
VIMNotificationTypeVideoAvailable
VIMNotificationTypeVideoAvailable, // User new video available
VIMNotificationTypeFollowedUserVideoAvailable // Followed user new video available
};

@interface VIMNotification : VIMModelObject
Expand Down
3 changes: 2 additions & 1 deletion VimeoNetworking/Sources/Models/VIMNotification.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ @implementation VIMNotification
@"follow" : @(VIMNotificationTypeFollow),
@"like" : @(VIMNotificationTypeLike),
@"reply" : @(VIMNotificationTypeReply),
@"video_available" : @(VIMNotificationTypeVideoAvailable)};
@"video_available" : @(VIMNotificationTypeVideoAvailable),
@"followed_user_video_available" : @(VIMNotificationTypeFollowedUserVideoAvailable)};
});

return _typeMap;
Expand Down
4 changes: 2 additions & 2 deletions VimeoNetworking/Sources/Models/VIMQuantityQuota.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ @implementation VIMQuantityQuota

- (void)didFinishMapping
{
self.canUploadHd = [self.hd boolValue];
self.canUploadSd = [self.sd boolValue];
self.canUploadHd = [self.hd respondsToSelector:@selector(boolValue)] ? [self.hd boolValue] : NO;
self.canUploadSd = [self.sd respondsToSelector:@selector(boolValue)] ? [self.sd boolValue] : NO;
}

@end
64 changes: 55 additions & 9 deletions VimeoNetworking/Sources/VimeoRequestSerializer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer
{
static let AcceptHeaderKey = "Accept"
static let AuthorizationHeaderKey = "Authorization"
static let UserAgentKey = "User-Agent"
}

public typealias AccessTokenProvider = (Void) -> String?
Expand Down Expand Up @@ -66,7 +67,7 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer

super.init()

self.setup(apiVersion: apiVersion)
self.configureDefaultHeaders(withAPIVersion: apiVersion)
}

/**
Expand All @@ -83,7 +84,7 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer

super.init()

self.setup(apiVersion: appConfiguration.apiVersion)
self.configureDefaultHeaders(withAPIVersion: appConfiguration.apiVersion)
}

/**
Expand All @@ -100,7 +101,7 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer
{
var request = super.request(withMethod: method, urlString: URLString, parameters: parameters, error: error) as URLRequest

request = self.requestWithAuthorizationHeader(fromRequest: request)
request = self.requestConfiguringHeaders(fromRequest: request)

return (request as NSURLRequest).mutableCopy() as! NSMutableURLRequest
}
Expand All @@ -109,7 +110,7 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer
{
var request = super.multipartFormRequest(withMethod: method, urlString: URLString, parameters: parameters, constructingBodyWith: block, error: error) as URLRequest

request = self.requestWithAuthorizationHeader(fromRequest: request)
request = self.requestConfiguringHeaders(fromRequest: request)

return (request as NSURLRequest).mutableCopy() as! NSMutableURLRequest
}
Expand All @@ -118,7 +119,7 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer
{
var request = super.request(withMultipartForm: request, writingStreamContentsToFile: fileURL, completionHandler: handler) as URLRequest

request = self.requestWithAuthorizationHeader(fromRequest: request)
request = self.requestConfiguringHeaders(fromRequest: request)

return (request as NSURLRequest).mutableCopy() as! NSMutableURLRequest
}
Expand All @@ -127,22 +128,32 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer
{
if var request = super.request(bySerializingRequest: request, withParameters: parameters, error: error)
{
request = self.requestWithAuthorizationHeader(fromRequest: request)
request = self.requestConfiguringHeaders(fromRequest: request)

return request
}

return nil
}

// MARK: Private API
// MARK: Header Helpers

private func setup(apiVersion: String)
private func configureDefaultHeaders(withAPIVersion apiVersion: String)
{
self.setValue("application/vnd.vimeo.*+json; version=\(apiVersion)", forHTTPHeaderField: Constants.AcceptHeaderKey)
}

private func requestWithAuthorizationHeader(fromRequest request: URLRequest) -> URLRequest
private func requestConfiguringHeaders(fromRequest request: URLRequest) -> URLRequest
{
var request = request

request = self.requestAddingAuthorizationHeader(fromRequest: request)
request = self.requestModifyingUserAgentHeader(fromRequest: request)

return request
}

private func requestAddingAuthorizationHeader(fromRequest request: URLRequest) -> URLRequest
{
var request = request

Expand All @@ -169,4 +180,39 @@ final public class VimeoRequestSerializer: AFJSONRequestSerializer

return request
}

private func requestModifyingUserAgentHeader(fromRequest request: URLRequest) -> URLRequest
{
guard let frameworkVersion = Bundle(for: type(of: self)).infoDictionary?["CFBundleShortVersionString"] as? String else
{
assertionFailure("Unable to get the framework version")

return request
}

var request = request

let frameworkString = "VimeoNetworking/\(frameworkVersion)"

guard let existingUserAgent = request.value(forHTTPHeaderField: Constants.UserAgentKey) else
{
// DISCUSSION: AFNetworking doesn't set a User Agent for tvOS (look at the init method in AFHTTPRequestSerializer.m).
// So, on tvOS the User Agent will only specify the framework. System information might be something we want to add
// in the future if AFNetworking isn't providing it. [ghking] 6/19/17

#if !os(tvOS)
assertionFailure("An existing user agent was not found")
#endif

request.setValue(frameworkString, forHTTPHeaderField: Constants.UserAgentKey)

return request
}

let modifiedUserAgent = existingUserAgent + " " + frameworkString

request.setValue(modifiedUserAgent, forHTTPHeaderField: Constants.UserAgentKey)

return request
}
}
Loading

0 comments on commit 75cc4f9

Please sign in to comment.