Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
dbfd6ed
remove broken shell script thing
morganchen12 Aug 4, 2016
218a38a
fix ignoring pod ldflags
morganchen12 Aug 4, 2016
1c44ad7
make database apis more idiomatic
morganchen12 Aug 4, 2016
0617d42
deintegrate pods
morganchen12 Aug 4, 2016
8a73485
partially add unit tests
morganchen12 Aug 4, 2016
1c39d2e
random file missing from pbxproj
morganchen12 Aug 4, 2016
88709f8
begin writing tests
morganchen12 Aug 5, 2016
2efcf35
finish FirebaseArray tests, kind of
morganchen12 Aug 5, 2016
bfd3b63
add firebase array delegate tests
morganchen12 Aug 5, 2016
a455819
make FirebaseArray remove only its own observers
morganchen12 Aug 8, 2016
6348024
use correct delegate methods
morganchen12 Aug 8, 2016
f29ce42
update comments
morganchen12 Aug 8, 2016
696d31b
make initializers for auth providers non-optional
morganchen12 Aug 8, 2016
0d01485
xcode writes to xibs when they're opened aaa
morganchen12 Aug 8, 2016
9d962c1
rename authUI to defaultAuthUI
morganchen12 Aug 8, 2016
c7da9ae
use correct google api scopes
morganchen12 Aug 8, 2016
e57e70b
make collection view data source test
morganchen12 Aug 9, 2016
bca666a
clean up comments and whitespace; get rid of bad swift name
morganchen12 Aug 9, 2016
82383bf
try to use actual collection view in tests, breaking everything
morganchen12 Aug 9, 2016
b7488f9
fix crash bug in tests
morganchen12 Aug 10, 2016
577a3d7
add table view data source tests
morganchen12 Aug 10, 2016
89efa98
use accessors in init
morganchen12 Aug 10, 2016
1be8364
don't test duplicate keys, use snapshot values in tests
morganchen12 Aug 11, 2016
e624ecf
deintegrate pods
morganchen12 Aug 11, 2016
2797943
add null_resettable to data sources
morganchen12 Aug 11, 2016
a2473da
make table view data source's populateCell readonly
morganchen12 Aug 11, 2016
fa2918a
rearrange property modifiers
morganchen12 Aug 12, 2016
a100271
properly copy init parameter
morganchen12 Aug 12, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
357 changes: 253 additions & 104 deletions FirebaseUI.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,32 @@ NS_ASSUME_NONNULL_BEGIN
/** @property appId
@brief The Facebook App ID.
*/
@property(nonatomic, copy, readonly) NSString *appID;
@property(nonatomic, readonly, copy) NSString *appID;

/** @property scopes
@brief The scopes to use with Facebook Login.
@remarks Defaults to using "email" scopes.
*/
@property(nonatomic, copy) NSArray<NSString *> *scopes;
@property(nonatomic, readonly, copy) NSArray<NSString *> *scopes;

/** @fn init
@brief Please use initWithAppId:
*/
- (nullable instancetype)init NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

/** @fn initWithAppID:
@brief Conevenience initializer. Uses a default permission of `@[ "email" ]`.
@param appID The Facebook App ID.
*/
- (nullable instancetype)initWithAppID:(NSString *)appID;
- (instancetype)initWithAppID:(NSString *)appID;

/** @fn initWithAppID:permissions:
@brief Designated initializer.
@param appID The Facebook App ID.
@param permissions The permissions of the app. This array must be an array of specific string values
as defined in https://developers.facebook.com/docs/facebook-login/permissions/
*/
- (nullable instancetype)initWithAppID:(NSString *)appID permissions:(NSArray *)permissions NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithAppID:(NSString *)appID permissions:(NSArray *)permissions NS_DESIGNATED_INITIALIZER;

@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ @implementation FIRFacebookAuthUI {
FIRAuthProviderSignInCompletionBlock _pendingSignInCallback;
}

- (nullable instancetype)init {
- (instancetype)init {
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer."
reason:@"Please call the designated initializer."
userInfo:nil];
}

- (nullable instancetype)initWithAppID:(NSString *)appID permissions:(NSArray *)permissions {
- (instancetype)initWithAppID:(NSString *)appID permissions:(NSArray *)permissions {
self = [super init];
if (self != nil) {
_scopes = permissions;
Expand All @@ -65,7 +65,7 @@ - (nullable instancetype)initWithAppID:(NSString *)appID permissions:(NSArray *)
return self;
}

- (nullable instancetype)initWithAppID:(NSString *)appID {
- (instancetype)initWithAppID:(NSString *)appID {
return [self initWithAppID:appID permissions:@[ @"email" ]];
}

Expand Down
20 changes: 15 additions & 5 deletions FirebaseUI/Auth/AuthProviderUI/Google/Source/FIRGoogleAuthUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,30 @@ NS_ASSUME_NONNULL_BEGIN

/** @property scopes
@brief The scopes to use with Google Sign In.
@remarks Defaults to using "email" and "profile" scopes.
@remarks Defaults to using email and profile scopes. For a list of all scopes
see https://developers.google.com/identity/protocols/googlescopes
*/
@property(nonatomic, copy) NSArray<NSString *> *scopes;
@property(nonatomic, copy, readonly) NSArray<NSString *> *scopes;

/** @fn init
@brief Please use initWithClientId:
*/
- (nullable instancetype)init NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

/** @fn initWithClientID:
@brief Designated initializer.
@brief Convenience initializer. Calls designated init with default
scopes of "email" and "profile".
@param clientId The Google Sign In client ID.
*/
- (nullable instancetype)initWithClientID:(NSString *)clientID NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithClientID:(NSString *)clientID;

/** @fn initWithClientID:scopes:
@brief Designated initializer.
@param clientId The Google Sign In client ID.
@param scopes The user account scopes required by the app. A list of possible scopes can be
found at https://developers.google.com/identity/protocols/googlescopes
*/
- (instancetype)initWithClientID:(NSString *)clientID scopes:(NSArray <NSString *> *)scopes NS_DESIGNATED_INITIALIZER;

@end

Expand Down
22 changes: 16 additions & 6 deletions FirebaseUI/Auth/AuthProviderUI/Google/Source/FIRGoogleAuthUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@
*/
static NSString *const kGooglePlusMeScope = @"https://www.googleapis.com/auth/plus.me";

/** @var kGooglePlusScopesPrefix
@brief The OAuth scope string prefix for all scopes starting with "plus.".
/** @var kGooglePlusMeScope
@brief The OAuth scope string for the user's email scope.
*/
static NSString *const kGoogleUserInfoEmailScope = @"https://www.googleapis.com/auth/userinfo.email";

/** @var kGooglePlusMeScope
@brief The OAuth scope string for the basic G+ profile information scope.
*/
static NSString *const kGooglePlusScopesPrefix = @"https://www.googleapis.com/auth/plus.";
static NSString *const kGoogleUserInfoProfileScope = @"https://www.googleapis.com/auth/userinfo.profile";
Copy link
Contributor

Choose a reason for hiding this comment

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

This one is a behavior change I think, though the effective difference between those scopes is slight, an upgrade may cause a reconsent. At the least we should flag this in changelog.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The prefix has been deleted because it was defined before but never used.


/** @var kTableName
@brief The name of the strings table to search for localized strings.
Expand All @@ -60,17 +65,22 @@ @implementation FIRGoogleAuthUI {
FIRAuthProviderSignInCompletionBlock _pendingSignInCallback;
}

- (nullable instancetype)init {
- (instancetype)init {
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer."
reason:@"Please call the designated initializer."
userInfo:nil];
}

- (nullable instancetype)initWithClientID:(NSString *)clientID {
- (instancetype)initWithClientID:(NSString *)clientID {
return [self initWithClientID:clientID
scopes:@[kGoogleUserInfoEmailScope, kGoogleUserInfoProfileScope]];
}

- (instancetype)initWithClientID:(NSString *)clientID scopes:(NSArray *)scopes {
self = [super init];
if (self) {
_clientID = [clientID copy];
_scopes = @[ @"email", @"profile" ];
_scopes = [scopes copy];
}
return self;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<objects>
Expand Down
2 changes: 1 addition & 1 deletion FirebaseUI/Auth/AuthUI/Source/FIRAuthUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ typedef void (^FIRAuthUIResultCallback)(FIRUser *_Nullable user, NSError *_Nulla
@brief Gets the @c FIRAuthUI object for the default FirebaseApp.
@remarks Thread safe.
*/
+ (nullable FIRAuthUI *)authUI NS_SWIFT_NAME(authUI());
+ (nullable FIRAuthUI *)defaultAuthUI;

/** @fn authUIWithAuth:
@brief Gets the @c FIRAuthUI instance for a @c FIRAuth.
Expand Down
5 changes: 3 additions & 2 deletions FirebaseUI/Auth/AuthUI/Source/FIRAuthUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ - (nullable instancetype)initWithAuth:(FIRAuth *)auth NS_DESIGNATED_INITIALIZER;

@implementation FIRAuthUI

+ (nullable FIRAuthUI *)authUI {
+ (nullable FIRAuthUI *)defaultAuthUI {
FIRAuth *defaultAuth = [FIRAuth auth];
if (!defaultAuth) {
return nil;
Expand All @@ -54,6 +54,7 @@ + (nullable FIRAuthUI *)authUI {
}

+ (nullable FIRAuthUI *)authUIWithAuth:(FIRAuth *)auth {
NSParameterAssert(auth != nil);
@synchronized (self) {
// Let the FIRAuth instance retain the FIRAuthUI instance.
FIRAuthUI *authUI = objc_getAssociatedObject(auth, &kAuthAssociationKey);
Expand All @@ -66,7 +67,7 @@ + (nullable FIRAuthUI *)authUIWithAuth:(FIRAuth *)auth {
}
}

- (nullable instancetype)initWithAuth:(FIRAuth *)auth {
- (instancetype)initWithAuth:(FIRAuth *)auth {
self = [super init];
if (self) {
_auth = auth;
Expand Down
2 changes: 1 addition & 1 deletion FirebaseUI/Auth/AuthUI/Source/FIRAuthUIStrings.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ @implementation FIRAuthUIStrings
@return Localized value of the string identified by the key.
*/
+ (NSString *)localizedStringForKey:(nonnull NSString *)key {
NSBundle *customStringsBundle = [FIRAuthUI authUI].customStringsBundle;
NSBundle *customStringsBundle = [FIRAuthUI defaultAuthUI].customStringsBundle;
if (customStringsBundle) {
NSString *localizedString = [customStringsBundle localizedStringForKey:key
value:kKeyNotFound
Expand Down
68 changes: 33 additions & 35 deletions FirebaseUI/Database/API/FirebaseArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,25 @@

// clang-format on

#import <Foundation/Foundation.h>
@import Firebase;

#import "FirebaseArrayDelegate.h"

NS_ASSUME_NONNULL_BEGIN

@class FIRDatabaseQuery;
@class FIRDatabaseReference;
@class FIRDataSnapshot;
@protocol FIRDataObservable
@required

- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType
andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block
withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;

- (void)removeObserverWithHandle:(FIRDatabaseHandle)handle;

@end

@interface FIRDatabaseQuery (FIRDataObservable) <FIRDataObservable>
@end

/**
* FirebaseArray provides an array structure that is synchronized with a Firebase reference or
Expand All @@ -39,43 +49,36 @@ NS_ASSUME_NONNULL_BEGIN
* The delegate object that array changes are surfaced to, which conforms to the
* [FirebaseArrayDelegate Protocol](FirebaseArrayDelegate).
*/
@property(weak, nonatomic) id<FirebaseArrayDelegate> delegate;
@property(weak, nonatomic, nullable) id<FirebaseArrayDelegate> delegate;

/**
* The query on a Firebase reference that provides data to populate the instance of FirebaseArray.
*/
@property(strong, nonatomic) FIRDatabaseQuery *query;
@property(strong, nonatomic) id<FIRDataObservable> query;

/**
* The delegate object that array changes are surfaced to.
* The number of objects in the FirebaseArray.
*/
@property(strong, nonatomic) NSMutableArray<FIRDataSnapshot *> * snapshots;

#pragma mark -
#pragma mark Initializer methods
@property(nonatomic, readonly) NSUInteger count;

/**
* Intitalizes FirebaseArray with a standard Firebase reference.
* @param ref The Firebase reference which provides data to FirebaseArray
* @return The instance of FirebaseArray
* The items currently in the FirebaseArray.
*/
- (instancetype)initWithRef:(FIRDatabaseReference *)ref;
@property(nonatomic, readonly, copy) NSArray *items;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does copy make sense here with readonly? I notice you have the same set of params earlier as well, but in a different order: reorder one set. May be worth checking the Google objective C style guide to see if there is an ordering recommendation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it makes sense to keep copy since it'll copy on reads. Our style guide doesn't say anything about property annotations, and in general for an open source project that we'll be breaking/changing a lot I think it's healthier to disregard internal style guides and agree on whatever style we'll use with the community.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't believe copy copies on read, only write.

Regarding the style, but in the absence of a known community opinion we should prefer existing style guides. If we diverge from that, we should note that we are, and document our own style variations.

Regardless of what we choose, we should be consistent - so either change this one to match the order in https://github.com/firebase/FirebaseUI-iOS/pull/108/files#diff-13a906499860a93cf34277f908dfb0b7R37 or vice versa.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The implementation manually copies on read, since the backing array is mutable. I guess I could just delete copy since it doesn't do anything here.


#pragma mark - Initializer methods

/**
* Intitalizes FirebaseArray with a Firebase query (FIRDatabaseQuery).
* @param query A query on a Firebase reference which provides filtered data to FirebaseArray
* @return The instance of FirebaseArray
* Initalizes FirebaseArray with a Firebase query (FIRDatabaseQuery) or database reference
* (FIRDatabaseReference).
* @param query A query or Firebase database reference
* @return A FirebaseArray instance
*/
- (instancetype)initWithQuery:(FIRDatabaseQuery *)query;
- (instancetype)initWithQuery:(id<FIRDataObservable>)query NS_DESIGNATED_INITIALIZER;

#pragma mark -
#pragma mark Public API methods
- (instancetype)init NS_UNAVAILABLE;

/**
* Returns the count of objects in the FirebaseArray.
* @return The count of objects in the FirebaseArray
*/
- (NSUInteger)count;
#pragma mark - Public API methods

/**
* Returns an object at a specific index in the FirebaseArray.
Expand All @@ -100,21 +103,16 @@ NS_ASSUME_NONNULL_BEGIN

/**
* Support for subscripting. This method is unused and trying to write directly to the
* array using subscripting will cause an assertion.
* array using subscripting will cause an assertion failure.
*/
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;

#pragma mark -
#pragma mark Private API methods
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx NS_UNAVAILABLE;

/**
* Returns an index for a given object's key (that matches the object's key in the corresponding
* Firebase reference).
* @param key The key of the desired object
* @return The index of the object for which the key matches or -1 if the key is null
* @exception FirebaseArrayKeyNotFoundException Thrown when the desired key is not in the
* FirebaseArray, likely indicating that the FirebaseArray is no longer being properly synchronized
* with the Firebase database.
* @return The index of the object for which the key matches or NSNotFound if the key is not found
* @exception NSInvalidArgumentException Thrown when the `key` parameter is `nil`.
*/
- (NSUInteger)indexForKey:(NSString *)key;

Expand Down
12 changes: 7 additions & 5 deletions FirebaseUI/Database/API/FirebaseArrayDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

// clang-format on

@class FirebaseArray;

/**
* A protocol to allow instances of FirebaseArray to raise events through a
* delegate. Raises all
Expand All @@ -36,7 +38,7 @@
* @param object The object added to the FirebaseArray
* @param index The index the child was added at
*/
- (void)childAdded:(id)object atIndex:(NSUInteger)index;
- (void)array:(FirebaseArray *)array didAddObject:(id)object atIndex:(NSUInteger)index;
Copy link
Contributor

@ianbarber ianbarber Aug 9, 2016

Choose a reason for hiding this comment

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

These changes are pretty impactful I think, people do use FirebaseArray directly. We may want a migration cheat sheet - replace X with Y kind of thing.

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW we consider FirebaseArray to be a "private API" even though some are accessing it. So we can flag it in the changelog but we don't have to worry too much.

On Android it's not possible to use FirebaseArray directly due to the access modifiers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In our source comments we suggest users use FirebaseArray to build on top of, so I think it's worth treating as public. Also it's extremely confusing to tell users that something exposed by the module as public is actually not supposed to be public.


/**
* Delegate method which is called whenever an object is chinged in a
Expand All @@ -47,7 +49,7 @@
* @param object The object that changed in the FirebaseArray
* @param index The index the child was changed at
*/
- (void)childChanged:(id)object atIndex:(NSUInteger)index;
- (void)array:(FirebaseArray *)array didChangeObject:(id)object atIndex:(NSUInteger)index;

/**
* Delegate method which is called whenever an object is removed from a
Expand All @@ -58,7 +60,7 @@
* @param object The object removed from the FirebaseArray
* @param index The index the child was removed at
*/
- (void)childRemoved:(id)object atIndex:(NSUInteger)index;
- (void)array:(FirebaseArray *)array didRemoveObject:(id)object atIndex:(NSUInteger)index;

/**
* Delegate method which is called whenever an object is moved within a
Expand All @@ -70,12 +72,12 @@
* @param fromIndex The index the child is being moved from
* @param toIndex The index the child is being moved to
*/
- (void)childMoved:(id)object fromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;
- (void)array:(FirebaseArray *)array didMoveObject:(id)object fromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;

/**
* Delegate method which is called whenever the backing query is canceled.
* @param error the error that was raised
*/
- (void)canceledWithError:(NSError *)error;
- (void)array:(FirebaseArray *)array queryCancelledWithError:(NSError *)error;

@end
Loading