Skip to content

Apple user details #1551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 12, 2020
4 changes: 1 addition & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ workflows:
jobs:
- ios
- macos
- carthage:
requires:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe removing this may allow Carthage to run before iOS (I think the jobs start randomly and the only thing that prevents it is "requires"). Also, Carthage takes the longest, so if the iOS build fails, no reason to run Carthage because it will likely fail. Better to find out quickly that iOS failed than wait until after Carthage

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I meant to explain myself here. My reasoning was that the iOS tests still fail randomly; that the tests fail doesn't mean the binary isn't good. And if there's been an issue with the Carthage build, working on getting it green is a crapshoot.

It's more of a hack to deal with what we've got, than the right solution.

- ios
- carthage
nightly:
jobs:
- carthage
Expand Down
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ Check the Rakefile and the circleci config for more information.

#### 5. Make sure your code follows the [style guide](#style-guide)

### Preparing for a new release

#### Update the version number

You can use the rake task in order to bump the version number, it's safe, and will properly update all version numbers

```
$ bundle exec rake package:set_version[X.X.X]
```

Note that zsh users (such as those using macOS >= 10.15) need to escape the brackets as follows:

```
$ bundle exec rake package:set_version\[X.X.X\]
```

Replace X.X.X by the version number and push to the repository.

## Bugs
Although we try to keep developing with the Parse Platform easy, you still may run into some issues. General questions should be asked on our [community forum](community-forum), technical questions should be asked on [Stack Overflow][stack-overflow], and for everything else we use GitHub issues.

Expand Down
9 changes: 9 additions & 0 deletions ParseUI/Classes/LogInViewController/PFLogInViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ shouldBeginLogInWithUsername:(NSString *)username
*/
- (void)logInViewControllerDidCancelLogIn:(PFLogInViewController *)logInController;

/**
Sent to the delegate when user data is received following successful login using Sign In With Apple.

@param logInController The login view controller that received the credentials
@param credential The ASAuthorizationAppleIDCredential object received
*/

-(void)logInViewController:(PFLogInViewController *)logInController didReceiveAppleCredential:(ASAuthorizationAppleIDCredential *)credential forUser:(PFUser *)user API_AVAILABLE(ios(13.0));

@end

NS_ASSUME_NONNULL_END
45 changes: 22 additions & 23 deletions ParseUI/Classes/LogInViewController/PFLogInViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#import "PFSignUpViewController.h"
#import "PFTextField.h"
#import "PFLogInView_Private.h"
#import "PFAppleUtils.h"

NSString *const PFLogInSuccessNotification = @"com.parse.ui.login.success";
NSString *const PFLogInFailureNotification = @"com.parse.ui.login.failure";
Expand Down Expand Up @@ -332,7 +333,7 @@ - (void)_requestPasswordResetWithEmail:(NSString *)email {

#pragma mark Sign in with Apple
-(void)_loginWithApple API_AVAILABLE(ios(13.0)){

if (self.loading) {
return;
}
Expand All @@ -344,28 +345,26 @@ -(void)_loginWithApple API_AVAILABLE(ios(13.0)){

__weak typeof(self) wself = self;

Class appleUtils = NSClassFromString(@"PFAppleUtils");
SEL selector = NSSelectorFromString(@"logInInBackground");
if ([appleUtils respondsToSelector:selector]) {
[[appleUtils logInInBackground] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
__strong typeof(wself) sself = wself;
dispatch_async(dispatch_get_main_queue(), ^{
sself.loading = NO;
if ([sself.logInView.appleButton isKindOfClass:[PFActionButton class]]) {
[(PFActionButton *)sself.logInView.appleButton setLoading:NO];
}
if (t.error) {
[sself _loginDidFailWithError:t.error];
}
else
{
PFUser *user = t.result[@"user"];
[sself _loginDidSucceedWithUser:user];
}
});
return nil;
}];
}
[[PFAppleUtils logInInBackground] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
__strong typeof(wself) sself = wself;
dispatch_async(dispatch_get_main_queue(), ^{
sself.loading = NO;
if ([sself.logInView.appleButton isKindOfClass:[PFActionButton class]]) {
[(PFActionButton *)sself.logInView.appleButton setLoading:NO];
}
if (t.error) {
[sself _loginDidFailWithError:t.error];
}
else
{
PFUser *user = t.result[PFAppleAuthUserKey];
ASAuthorizationAppleIDCredential *cred = t.result[PFAppleAuthCredentialKey];
[sself _loginDidSucceedWithUser:user];
[sself.delegate logInViewController:sself didReceiveAppleCredential:cred forUser:user];
}
});
return nil;
}];
}

#pragma mark Log In With Facebook
Expand Down
20 changes: 16 additions & 4 deletions ParseUI/ParseUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,20 @@
B9DDA283243C322D0003061D /* ParseTwitterUtils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E4272027CC2D0066DE1A /* ParseTwitterUtils.framework */; };
B9DDA284243C32E50003061D /* ParseFacebookUtilsV4.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E4362027CC330066DE1A /* ParseFacebookUtilsV4.framework */; };
BC0632E023ABCC8F0089096D /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC0632DC23ABCB1D0089096D /* AuthenticationServices.framework */; };
BC0632E423AD005E0089096D /* PFAppleUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0632E323AD005E0089096D /* PFAppleUtils.m */; };
BC0632E823AD03B30089096D /* PFAppleAuthenticationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0632E723AD03B30089096D /* PFAppleAuthenticationProvider.m */; };
BC0632EA23AD3F050089096D /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A13523820282059000F5FD5 /* Bolts.framework */; };
BC488EA0246B196800947E3C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC488E9F246B196800947E3C /* ParseUI.framework */; };
BC488EA1246B196800947E3C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC488E9F246B196800947E3C /* ParseUI.framework */; };
BC488EA2246B196800947E3C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC488E9F246B196800947E3C /* ParseUI.framework */; };
BC8C2923246B1873000AEE3F /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A9497200D0329005D8F4B /* ParseUI.framework */; };
BCA5CC8523BFCFB8003BC0A0 /* SignInWithAppleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BCCBE8CB23BFB89D0044A79C /* SignInWithAppleTests.m */; };
BCB2A82E251D337E0030D987 /* PFAppleUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0632E223AD005E0089096D /* PFAppleUtils.h */; };
BCB2A82F251D337E0030D987 /* PFAppleUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0632E323AD005E0089096D /* PFAppleUtils.m */; };
BCB2A830251D337E0030D987 /* PFAppleAuthenticationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0632E623AD03B20089096D /* PFAppleAuthenticationProvider.h */; };
BCB2A831251D337E0030D987 /* PFAppleAuthenticationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0632E723AD03B30089096D /* PFAppleAuthenticationProvider.m */; };
BCB2A840251D337F0030D987 /* PFAppleUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0632E223AD005E0089096D /* PFAppleUtils.h */; };
BCB2A841251D337F0030D987 /* PFAppleUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0632E323AD005E0089096D /* PFAppleUtils.m */; };
BCB2A842251D337F0030D987 /* PFAppleAuthenticationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0632E623AD03B20089096D /* PFAppleAuthenticationProvider.h */; };
BCB2A843251D337F0030D987 /* PFAppleAuthenticationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0632E723AD03B30089096D /* PFAppleAuthenticationProvider.m */; };
BCCBE8CE23BFB89D0044A79C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A9497200D0329005D8F4B /* ParseUI.framework */; };
BCCBE8E023BFC8BF0044A79C /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCCBE8DF23BFC8BF0044A79C /* OCMock.framework */; };
F57F3D231B0C03D40087F60B /* DeletionCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F57F3D201B0C03C90087F60B /* DeletionCollectionViewController.m */; };
Expand Down Expand Up @@ -1332,6 +1338,7 @@
buildActionMask = 2147483647;
files = (
4A0ECC03200D8C0200BA84A3 /* PFLoadingView.h in Headers */,
BCB2A840251D337F0030D987 /* PFAppleUtils.h in Headers */,
4A0ECC04200D8C0200BA84A3 /* PFQueryCollectionViewController.h in Headers */,
4A0ECC05200D8C0200BA84A3 /* PFUIAlertView.h in Headers */,
4A0ECC06200D8C0200BA84A3 /* PFSignUpViewController.h in Headers */,
Expand All @@ -1344,6 +1351,7 @@
4A0ECC0D200D8C0200BA84A3 /* PFCollectionViewCell.h in Headers */,
4A0ECC0E200D8C0200BA84A3 /* PFDismissButton.h in Headers */,
4A0ECC0F200D8C0200BA84A3 /* PFActivityIndicatorCollectionReusableView.h in Headers */,
BCB2A842251D337F0030D987 /* PFAppleAuthenticationProvider.h in Headers */,
4A0ECC10200D8C0200BA84A3 /* PFQueryTableViewController.h in Headers */,
4A0ECC11200D8C0200BA84A3 /* PFLogInViewController.h in Headers */,
4A0ECC12200D8C0200BA84A3 /* PFPurchaseTableViewCell.h in Headers */,
Expand All @@ -1368,6 +1376,7 @@
buildActionMask = 2147483647;
files = (
4A9A94C6200D03BA005D8F4B /* PFLoadingView.h in Headers */,
BCB2A82E251D337E0030D987 /* PFAppleUtils.h in Headers */,
4A9A94C9200D03BE005D8F4B /* PFQueryCollectionViewController.h in Headers */,
4A9A94B6200D03B6005D8F4B /* PFUIAlertView.h in Headers */,
4A9A94AD200D03B6005D8F4B /* PFSignUpViewController.h in Headers */,
Expand All @@ -1380,6 +1389,7 @@
4A9A94A8200D03B6005D8F4B /* PFCollectionViewCell.h in Headers */,
4A9A94BE200D03BA005D8F4B /* PFDismissButton.h in Headers */,
4A9A94AF200D03B6005D8F4B /* PFActivityIndicatorCollectionReusableView.h in Headers */,
BCB2A830251D337E0030D987 /* PFAppleAuthenticationProvider.h in Headers */,
4A9A94CA200D03C8005D8F4B /* PFQueryTableViewController.h in Headers */,
4A9A94D3200D03C8005D8F4B /* PFLogInViewController.h in Headers */,
4A9A94A4200D03B6005D8F4B /* PFPurchaseTableViewCell.h in Headers */,
Expand Down Expand Up @@ -1826,7 +1836,9 @@
4A0ECBFC200D8C0200BA84A3 /* PFTableViewCell.m in Sources */,
4A0ECBFD200D8C0200BA84A3 /* PFLogInViewController.m in Sources */,
4A0ECBFE200D8C0200BA84A3 /* PFSignUpView.m in Sources */,
BCB2A843251D337F0030D987 /* PFAppleAuthenticationProvider.m in Sources */,
4A0ECBFF200D8C0200BA84A3 /* PFTextField.m in Sources */,
BCB2A841251D337F0030D987 /* PFAppleUtils.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1859,7 +1871,9 @@
4A9A94A9200D03B6005D8F4B /* PFTableViewCell.m in Sources */,
4A9A94D0200D03C8005D8F4B /* PFLogInViewController.m in Sources */,
4A9A94AC200D03B6005D8F4B /* PFSignUpView.m in Sources */,
BCB2A831251D337E0030D987 /* PFAppleAuthenticationProvider.m in Sources */,
4A9A94CE200D03C8005D8F4B /* PFTextField.m in Sources */,
BCB2A82F251D337E0030D987 /* PFAppleUtils.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1894,13 +1908,11 @@
81C5993F1A64346000F574E8 /* SimpleCollectionViewController.m in Sources */,
81472FBB1A1AB37500FD6EED /* main.m in Sources */,
81C599421A6454C900F574E8 /* PaginatedCollectionViewController.m in Sources */,
BC0632E423AD005E0089096D /* PFAppleUtils.m in Sources */,
81472FB31A1AB37500FD6EED /* CustomSignUpViewController.m in Sources */,
81472FB41A1AB37500FD6EED /* CustomLogInViewController.m in Sources */,
81472FB91A1AB37500FD6EED /* CustomProductTableViewController.m in Sources */,
819A4B3A1A6808EA00D01241 /* SubtitleImageCollectionViewController.m in Sources */,
F57F3D241B0C03DB0087F60B /* DeletionTableViewController.m in Sources */,
BC0632E823AD03B30089096D /* PFAppleAuthenticationProvider.m in Sources */,
812E5C041A7A8EFB000FBDE1 /* StoryboardCollectionViewController.m in Sources */,
81472FB51A1AB37500FD6EED /* SimpleTableViewController.m in Sources */,
F57F3D231B0C03D40087F60B /* DeletionCollectionViewController.m in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions ParseUI/Sign In With Apple/PFAppleUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
NS_ASSUME_NONNULL_BEGIN

extern NSString *const PFAppleUserAuthenticationType;
extern NSString *const PFAppleAuthUserKey;
extern NSString *const PFAppleAuthCredentialKey;

API_AVAILABLE(ios(13.0))
@interface PFAppleLoginManager : NSObject <ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding>
Expand Down
11 changes: 6 additions & 5 deletions ParseUI/Sign In With Apple/PFAppleUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

#import "PFAppleUtils.h"
#import "PFAppleAuthenticationProvider.h"
@import AuthenticationServices;
#import <AuthenticationServices/AuthenticationServices.h>
#import <Bolts/Bolts.h>

NSString *const PFAppleUserAuthenticationType = @"apple";
NSString *const PFAppleAuthUserKey = @"user";
NSString *const PFAppleAuthCredentialKey = @"credential";

API_AVAILABLE(ios(13.0))
@interface PFAppleLoginManager ()
Expand Down Expand Up @@ -46,17 +48,16 @@ - (nonnull ASPresentationAnchor)presentationAnchorForAuthorizationController:(no
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization {
ASAuthorizationAppleIDCredential *cred = authorization.credential;
NSString *userId = cred.user;
NSPersonNameComponents *fullName = cred.fullName;
NSData *token = cred.identityToken;
NSString *tokenString = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];

__weak typeof(self) wself = self;

[[[PFUser logInWithAuthTypeInBackground:@"apple"
[[[PFUser logInWithAuthTypeInBackground:PFAppleUserAuthenticationType
authData:@{@"token" : tokenString, @"id" : userId}] continueWithSuccessBlock:^id _Nullable(BFTask<__kindof PFUser *> * _Nonnull t) {
__strong typeof(wself) sself = wself;
[sself.completionSource setResult:@{@"user" : t.result,
@"name" : fullName}];
[sself.completionSource setResult:@{PFAppleAuthUserKey : t.result,
PFAppleAuthCredentialKey : cred}];
sself.strongSelf = nil;
return t;
}] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
Expand Down
44 changes: 15 additions & 29 deletions ParseUI/SignInWithAppleTests/SignInWithAppleTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

#import <XCTest/XCTest.h>
#import "PFAppleUtils.h"
#import "Parse/PFUser.h"
#import "PFLoginViewController.h"

@import OCMock;

@interface SignInWithAppleTests : XCTestCase
Expand Down Expand Up @@ -59,7 +62,7 @@ - (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

- (void)testLoginSuccess {
- (void)testAppleUtilsLoginSuccess {

// Create test ASAuthorization and ASAuthorizationAppleIDCredential
FakeAuth *fakeAuth = [FakeAuth new];
Expand All @@ -78,29 +81,33 @@ - (void)testLoginSuccess {
id mockUser = OCMClassMock([PFUser class]);
NSDictionary *authData = @{@"token" : aString,
@"id" : aString };
NSDictionary *result = @{ @"user" : aString,
@"name" : name };
OCMStub(ClassMethod([mockUser logInWithAuthTypeInBackground:@"apple" authData:authData])).andReturn([BFTask taskWithResult:result]);
PFUser *loggedInUser = [PFUser new];
OCMStub(ClassMethod([mockUser logInWithAuthTypeInBackground:@"apple" authData:authData])).andReturn([BFTask taskWithResult:loggedInUser]);

// Create the login task
PFAppleLoginManager *manager = [PFAppleLoginManager new];
BFTask<NSDictionary *> *logInTask = [PFAppleUtils logInInBackgroundWithManager:manager];

XCTestExpectation *expect = [self expectationWithDescription:@"Task should complete."];
XCTestExpectation *expectLoginSuccess = [self expectationWithDescription:@"Login should complete."];
[logInTask continueWithSuccessBlock:^id _Nullable(BFTask<NSDictionary *> * _Nonnull t) {
[expect fulfill];
XCTAssert(t.result[@"user"] == loggedInUser);
ASAuthorizationAppleIDCredential *credential = t.result[@"credential"];
XCTAssert([credential.fullName isEqual:cred.fullName]);
XCTAssert([credential.identityToken isEqual:cred.identityToken]);
XCTAssert([credential.user isEqual:cred.user]);
[expectLoginSuccess fulfill];
return nil;
}];

// Call the success callback as Apple would
[manager authorizationController:manager.controller didCompleteWithAuthorization:(ASAuthorization *)fakeAuth];
[self waitForExpectations:@[expect] timeout:2];
[self waitForExpectations:@[expectLoginSuccess] timeout:2];

[mockUser stopMocking];

}

- (void)testPFUserLoginFails {
- (void)testAppleUtilsLoginFailure {
// Create test ASAuthorization and ASAuthorizationAppleIDCredential
FakeAuth *fakeAuth = [FakeAuth new];
FakeCredential *cred = [FakeCredential new];
Expand Down Expand Up @@ -140,25 +147,4 @@ - (void)testPFUserLoginFails {
[mockUser stopMocking];
}

- (void)testAppleAuthCompletesWithError {

// Create the login task
PFAppleLoginManager *manager = [PFAppleLoginManager new];
BFTask<NSDictionary *> *logInTask = [PFAppleUtils logInInBackgroundWithManager:manager];

XCTestExpectation *expect = [self expectationWithDescription:@"Task should fail."];
[logInTask continueWithBlock:^id _Nullable(BFTask<NSDictionary *> * _Nonnull t) {
if (t.error) {
[expect fulfill];
}
return nil;
}];

// Call the failure callback as Apple would
NSError *err = [[NSError alloc] initWithDomain:@"org.parseplatform.error" code:1337 userInfo:nil];
[manager authorizationController:manager.controller didCompleteWithError:err];
[self waitForExpectations:@[expect] timeout:2];

}

@end
Loading