Skip to content
This repository has been archived by the owner on Nov 2, 2019. It is now read-only.

Commit

Permalink
Add ability to fetch and refresh UserProfile.
Browse files Browse the repository at this point in the history
  • Loading branch information
nlutsenko committed Jul 27, 2016
1 parent e41ee3a commit 3048f23
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 3 deletions.
4 changes: 4 additions & 0 deletions FacebookSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
816B75A71D07AEB70012AC43 /* GraphRequestDataAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 816B75A61D07AEB70012AC43 /* GraphRequestDataAttachment.swift */; };
817021AE1D18DE1500ECE7AC /* UserProfile.PictureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 817021AD1D18DE1500ECE7AC /* UserProfile.PictureView.swift */; };
817A0A0E1D07CE8A00FD423A /* GraphRequestResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 817A0A0D1D07CE8A00FD423A /* GraphRequestResult.swift */; };
819E34C61D495A9A000D33E8 /* UserProfile.FetchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81E3C0CB1D48196900C927ED /* UserProfile.FetchResult.swift */; };
81AB8A871D36D43100066F63 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81AB8A3D1D36D41700066F63 /* FBSDKCoreKit.framework */; };
81AB8A941D36D44C00066F63 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81AB8A3D1D36D41700066F63 /* FBSDKCoreKit.framework */; };
81AB8A951D36D44C00066F63 /* FBSDKLoginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81AB8A4B1D36D41700066F63 /* FBSDKLoginKit.framework */; };
Expand Down Expand Up @@ -429,6 +430,7 @@
81D646871D2C8D7800690609 /* LikeControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LikeControl.swift; sourceTree = "<group>"; };
81D646881D2C8D7800690609 /* SendButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendButton.swift; sourceTree = "<group>"; };
81D646891D2C8D7800690609 /* ShareButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareButton.swift; sourceTree = "<group>"; };
81E3C0CB1D48196900C927ED /* UserProfile.FetchResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserProfile.FetchResult.swift; sourceTree = "<group>"; };
81FC4B5F1D064F68003F3A46 /* LoginManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginManager.swift; sourceTree = "<group>"; };
81FC4B721D064F8B003F3A46 /* LoginDefaultAudience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginDefaultAudience.swift; sourceTree = "<group>"; };
81FC4B7A1D065059003F3A46 /* LoginBehavior.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginBehavior.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -906,6 +908,7 @@
isa = PBXGroup;
children = (
81FC4EF11D068564003F3A46 /* UserProfile.swift */,
81E3C0CB1D48196900C927ED /* UserProfile.FetchResult.swift */,
817021AD1D18DE1500ECE7AC /* UserProfile.PictureView.swift */,
);
path = UserProfile;
Expand Down Expand Up @@ -1292,6 +1295,7 @@
810192AE1D01305400B9E881 /* AppEvent.Builtin.swift in Sources */,
810192AF1D01305400B9E881 /* AppEvent.swift in Sources */,
810192B41D01305400B9E881 /* AccessToken.swift in Sources */,
819E34C61D495A9A000D33E8 /* UserProfile.FetchResult.swift in Sources */,
81FC4CAB1D067490003F3A46 /* ReadPermission.swift in Sources */,
810192CA1D0139CF00B9E881 /* GraphRequestConnection.Delegate.swift in Sources */,
816B75A71D07AEB70012AC43 /* GraphRequestDataAttachment.swift in Sources */,
Expand Down
47 changes: 47 additions & 0 deletions Sources/Core/UserProfile/UserProfile.FetchResult.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import FBSDKCoreKit

extension UserProfile {
/**
Describes the result of a fetch of `UserProfile`.
*/
public enum FetchResult {
/// Profile was succesfully fetched.
case Success(UserProfile)
/// Profile fetch failed.
case Failed(ErrorType)
}
}

extension UserProfile.FetchResult {

internal init(sdkProfile: FBSDKProfile?, error: NSError?) {
if let error = error {
self = .Failed(error)
} else if let sdkProfile = sdkProfile {
let profile = UserProfile(sdkProfile: sdkProfile)
self = .Success(profile)
} else {
//FIXME: (nlutsenko) Use a good error type here.
let error = NSError(domain: "", code: 42, userInfo: nil)
self = .Failed(error)
}
}
}
71 changes: 68 additions & 3 deletions Sources/Core/UserProfile/UserProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,68 @@ public struct UserProfile {
}
}

//--------------------------------------
// MARK: - Loading Profile
//--------------------------------------

extension UserProfile {

/// Convenience alias for type of closure that is used as a completion for fetching `UserProfile`.
public typealias Completion = (FetchResult) -> Void

/**
Fetches a user profile by userId.
If the `current` profile is set, and it has the same `userId`,
calling method will reset the current profile with the newly fetched one.
- parameter userId: Facebook user id of the profile to fetch.
- parameter completion: The closure to be executed once the profile is refreshed.
*/
public static func fetch(userId userId: String, completion: Completion) {
let request = GraphRequest(graphPath: userId,
parameters: ["fields" : "first_name,middle_name,last_name,name,link"],
httpMethod: .GET)
request.start { (httpResponse, result) in
switch result {
case .Success(let response):
let responseDictionary = response.dictionaryValue

let profile = UserProfile(userId: userId,
firstName: responseDictionary?["first_name"] as? String,
middleName: responseDictionary?["middle_name"] as? String,
lastName: responseDictionary?["last_name"] as? String,
fullName: responseDictionary?["name"] as? String,
profileURL: (responseDictionary?["link"] as? String).flatMap({ NSURL(string: $0) }),
refreshDate: NSDate())

// Reset the current profile if userId matches
if AccessToken.current?.userId == userId {
UserProfile.current = profile
}
completion(.Success(profile))

case .Failed(let error):
completion(.Failed(error))
}
}
}

/**
Refreshes the existing user profile.
If the `current` profile is set, and receiver has the same `userId`,
calling method will reset the current profile with the newly fetched one.
- parameter completion: Optional closure to be executed once the profile is refreshed. Default: `nil`.
*/
public func refresh(completion: Completion? = nil) {
UserProfile.fetch(userId: userId) { result in
completion?(result)
}
}
}

//--------------------------------------
// MARK: - Current Profile
//--------------------------------------
Expand All @@ -111,9 +173,12 @@ extension UserProfile {
- parameter completion: The closure to be executed once the profile is loaded.
*/
public static func loadCurrent(completion: ((UserProfile?, ErrorType?) -> Void)?) {
FBSDKProfile.loadCurrentProfileWithCompletion { (profile: FBSDKProfile?, error: NSError?) in
completion?(profile.map(UserProfile.init), error)
public static func loadCurrent(completion: Completion?) {
FBSDKProfile.loadCurrentProfileWithCompletion { (sdkProfile: FBSDKProfile?, error: NSError?) in
if let completion = completion {
let result = FetchResult(sdkProfile: sdkProfile, error: error)
completion(result)
}
}
}

Expand Down

0 comments on commit 3048f23

Please sign in to comment.