Task Master 1.0 Code Pull

This commit is contained in:
2018-12-26 23:51:35 +00:00
parent e8d59db292
commit b920f3742b
284 changed files with 22772 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
#import <FirebaseAnalytics/FirebaseAnalytics.h>
#import <FirebaseCore/FirebaseCore.h>
#if !defined(__has_include)
#error "Firebase.h won't import anything if your compiler doesn't support __has_include. Please \
import the headers individually."
#else
#if __has_include(<FirebaseAppIndexing/FirebaseAppIndexing.h>)
#import <FirebaseAppIndexing/FirebaseAppIndexing.h>
#endif
#if __has_include(<FirebaseAuth/FirebaseAuth.h>)
#import <FirebaseAuth/FirebaseAuth.h>
#endif
#if __has_include(<FirebaseCrash/FirebaseCrash.h>)
#import <FirebaseCrash/FirebaseCrash.h>
#endif
#if __has_include(<FirebaseDatabase/FirebaseDatabase.h>)
#import <FirebaseDatabase/FirebaseDatabase.h>
#endif
#if __has_include(<FirebaseDynamicLinks/FirebaseDynamicLinks.h>)
#import <FirebaseDynamicLinks/FirebaseDynamicLinks.h>
#endif
#if __has_include(<FirebaseInstanceID/FirebaseInstanceID.h>)
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#endif
#if __has_include(<FirebaseInvites/FirebaseInvites.h>)
#import <FirebaseInvites/FirebaseInvites.h>
#endif
#if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)
#import <FirebaseMessaging/FirebaseMessaging.h>
#endif
#if __has_include(<FirebaseRemoteConfig/FirebaseRemoteConfig.h>)
#import <FirebaseRemoteConfig/FirebaseRemoteConfig.h>
#endif
#if __has_include(<FirebaseStorage/FirebaseStorage.h>)
#import <FirebaseStorage/FirebaseStorage.h>
#endif
#if __has_include(<GoogleMobileAds/GoogleMobileAds.h>)
#import <GoogleMobileAds/GoogleMobileAds.h>
#endif
#endif // defined(__has_include)

View File

@@ -0,0 +1,4 @@
module Firebase {
export *
header "Firebase.h"
}

76
Task Master/Pods/Firebase/README.md generated Executable file
View File

@@ -0,0 +1,76 @@
# Firebase APIs for iOS
Simplify your iOS development, grow your user base, and monetize more
effectively with Firebase services.
Much more information can be found at [https://firebase.google.com](https://firebase.google.com).
## Install a Firebase SDK using CocoaPods
Firebase distributes several iOS specific APIs and SDKs via CocoaPods.
You can install the CocoaPods tool on OS X by running the following command from
the terminal. Detailed information is available in the [Getting Started
guide](https://guides.cocoapods.org/using/getting-started.html#getting-started).
```
$ sudo gem install cocoapods
```
## Try out an SDK
You can try any of the SDKs with `pod try`. Run the following command and select
the SDK you are interested in when prompted:
```
$ pod try Firebase
```
Note that some SDKs may require credentials. More information is available in
the SDK-specific documentation at [https://firebase.google.com/docs/](https://firebase.google.com/docs/).
## Add a Firebase SDK to your iOS app
CocoaPods is used to install and manage dependencies in existing Xcode projects.
1. Create an Xcode project, and save it to your local machine.
2. Create a file named `Podfile` in your project directory. This file defines
your project's dependencies, and is commonly referred to as a Podspec.
3. Open `Podfile`, and add your dependencies. A simple Podspec is shown here:
```
platform :ios, '7.0'
pod 'Firebase'
```
4. Save the file.
5. Open a terminal and `cd` to the directory containing the Podfile.
```
$ cd <path-to-project>/project/
```
6. Run the `pod install` command. This will install the SDKs specified in the
Podspec, along with any dependencies they may have.
```
$ pod install
```
7. Open your app's `.xcworkspace` file to launch Xcode.
Use this file for all development on your app.
8. You can also install other Firebase SDKs by adding the subspecs in the
Podfile.
```
pod 'Firebase/AdMob'
pod 'Firebase/Analytics'
pod 'Firebase/AppIndexing'
pod 'Firebase/Auth'
pod 'Firebase/Crash'
pod 'Firebase/Database'
pod 'Firebase/DynamicLinks'
pod 'Firebase/Invites'
pod 'Firebase/Messaging'
pod 'Firebase/RemoteConfig'
pod 'Firebase/Storage'
```

View File

@@ -0,0 +1,57 @@
#import <Foundation/Foundation.h>
#import "FIRAnalytics.h"
/**
* Provides App Delegate handlers to be used in your App Delegate.
*
* To save time integrating Firebase Analytics in an application, Firebase Analytics does not
* require delegation implementation from the AppDelegate. Instead this is automatically done by
* Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App
* Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting
* it to NO, and adding the methods in this category to corresponding delegation handlers.
*
* To handle Universal Links, you must return YES in
* [UIApplicationDelegate application:didFinishLaunchingWithOptions:].
*/
@interface FIRAnalytics (AppDelegate)
/**
* Handles events related to a URL session that are waiting to be processed.
*
* For optimal use of Firebase Analytics, call this method from the
* [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler]
* method of the app delegate in your app.
*
* @param identifier The identifier of the URL session requiring attention.
* @param completionHandler The completion handler to call when you finish processing the events.
* Calling this completion handler lets the system know that your app's user interface is
* updated and a new snapshot can be taken.
*/
+ (void)handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)(void))completionHandler;
/**
* Handles the event when the app is launched by a URL.
*
* Call this method from [UIApplicationDelegate application:openURL:options:] (on iOS 9.0 and
* above), or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] (on iOS 8.x
* and below) in your app.
*
* @param url The URL resource to open. This resource can be a network resource or a file.
*/
+ (void)handleOpenURL:(NSURL *)url;
/**
* Handles the event when the app receives data associated with user activity that includes a
* Universal Link (on iOS 9.0 and above).
*
* Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app
* delegate (on iOS 9.0 and above).
*
* @param userActivity The activity object containing the data associated with the task the user
* was performing.
*/
+ (void)handleUserActivity:(id)userActivity;
@end

View File

@@ -0,0 +1,102 @@
#import <Foundation/Foundation.h>
#import "FIREventNames.h"
#import "FIRParameterNames.h"
#import "FIRUserPropertyNames.h"
NS_ASSUME_NONNULL_BEGIN
/// The top level Firebase Analytics singleton that provides methods for logging events and setting
/// user properties. See <a href="http://goo.gl/gz8SLz">the developer guides</a> for general
/// information on using Firebase Analytics in your apps.
@interface FIRAnalytics : NSObject
/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have
/// the same parameters. Up to 500 event names are supported. Using predefined events and/or
/// parameters is recommended for optimal reporting.
///
/// The following event names are reserved and cannot be used:
/// <ul>
/// <li>app_clear_data</li>
/// <li>app_remove</li>
/// <li>app_update</li>
/// <li>error</li>
/// <li>first_open</li>
/// <li>in_app_purchase</li>
/// <li>notification_dismiss</li>
/// <li>notification_foreground</li>
/// <li>notification_open</li>
/// <li>notification_receive</li>
/// <li>os_update</li>
/// <li>session_start</li>
/// <li>user_engagement</li>
/// </ul>
///
/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or
/// underscores. The name must start with an alphabetic character. Some event names are
/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_" prefix
/// is reserved and should not be used. Note that event names are case-sensitive and that
/// logging two events whose names differ only in case will result in two distinct events.
/// @param parameters The dictionary of event parameters. Passing nil indicates that the event has
/// no parameters. Parameter names can be up to 40 characters long and must start with an
/// alphabetic character and contain only alphanumeric characters and underscores. Only NSString
/// and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are
/// supported. NSString parameter values can be up to 100 characters long. The "firebase_"
/// prefix is reserved and should not be used for parameter names.
+ (void)logEventWithName:(NSString *)name
parameters:(nullable NSDictionary<NSString *, NSObject *> *)parameters;
/// Sets a user property to a given value. Up to 25 user property names are supported. Once set,
/// user property values persist throughout the app lifecycle and across sessions.
///
/// The following user property names are reserved and cannot be used:
/// <ul>
/// <li>first_open_time</li>
/// <li>last_deep_link_referrer</li>
/// <li>user_id</li>
/// </ul>
///
/// @param value The value of the user property. Values can be up to 36 characters long. Setting the
/// value to nil removes the user property.
/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters
/// or underscores and must start with an alphabetic character. The "firebase_" prefix is
/// reserved and should not be used for user property names.
+ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name;
/// Sets the user ID property. This feature must be used in accordance with
/// <a href="https://www.google.com/policies/privacy">Google's Privacy Policy</a>
///
/// @param userID The user ID to ascribe to the user of this app on this device, which must be
/// non-empty and no more than 36 characters long. Setting userID to nil removes the user ID.
+ (void)setUserID:(nullable NSString *)userID;
/// Sets the current screen name, which specifies the current visual context in your app. This helps
/// identify the areas in your app where users spend their time and how they interact with your app.
///
/// Note that screen reporting is enabled automatically and records the class name of the current
/// UIViewController for you without requiring you to call this method. If you implement
/// viewDidAppear in your UIViewController but do not call [super viewDidAppear:], that screen class
/// will not be automatically tracked. The class name can optionally be overridden by calling this
/// method in the viewDidAppear callback of your UIViewController and specifying the
/// screenClassOverride parameter.
///
/// If your app does not use a distinct UIViewController for each screen, you should call this
/// method and specify a distinct screenName each time a new screen is presented to the user.
///
/// The screen name and screen class remain in effect until the current UIViewController changes or
/// a new call to setScreenName:screenClass: is made.
///
/// @param screenName The name of the current screen. Should contain 1 to 100 characters. Set to nil
/// to clear the current screen name.
/// @param screenClassOverride The name of the screen class. Should contain 1 to 100 characters. By
/// default this is the class name of the current UIViewController. Set to nil to revert to the
/// default class name.
+ (void)setScreenName:(nullable NSString *)screenName
screenClass:(nullable NSString *)screenClassOverride;
/// The unique ID for this instance of the application.
+ (NSString *)appInstanceID;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1 @@
#import <FirebaseCore/FIRAnalyticsConfiguration.h>

View File

@@ -0,0 +1 @@
#import <FirebaseCore/FIRApp.h>

View File

@@ -0,0 +1 @@
#import <FirebaseCore/FIRConfiguration.h>

View File

@@ -0,0 +1,336 @@
/// @file FIREventNames.h
///
/// Predefined event names.
///
/// An Event is an important occurrence in your app that you want to measure. You can report up to
/// 500 different types of Events per app and you can associate up to 25 unique parameters with each
/// Event type. Some common events are suggested below, but you may also choose to specify custom
/// Event types that are associated with your specific app. Each event type is identified by a
/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric
/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_"
/// prefix is reserved and should not be used.
/// Add Payment Info event. This event signifies that a user has submitted their payment information
/// to your app.
static NSString *const kFIREventAddPaymentInfo = @"add_payment_info";
/// E-Commerce Add To Cart event. This event signifies that an item was added to a cart for
/// purchase. Add this event to a funnel with kFIREventEcommercePurchase to gauge the effectiveness
/// of your checkout process. Note: If you supply the @c kFIRParameterValue parameter, you must
/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed
/// accurately. Params:
///
/// <ul>
/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li>
/// <li>@c kFIRParameterItemID (NSString)</li>
/// <li>@c kFIRParameterItemName (NSString)</li>
/// <li>@c kFIRParameterItemCategory (NSString)</li>
/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li>
/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterOrigin (NSString) (optional)</li>
/// <li>@c kFIRParameterDestination (NSString) (optional)</li>
/// <li>@c kFIRParameterStartDate (NSString) (optional)</li>
/// <li>@c kFIRParameterEndDate (NSString) (optional)</li>
/// </ul>
static NSString *const kFIREventAddToCart = @"add_to_cart";
/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist.
/// Use this event to identify popular gift items in your app. Note: If you supply the
/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency
/// parameter so that revenue metrics can be computed accurately. Params:
///
/// <ul>
/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li>
/// <li>@c kFIRParameterItemID (NSString)</li>
/// <li>@c kFIRParameterItemName (NSString)</li>
/// <li>@c kFIRParameterItemCategory (NSString)</li>
/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li>
/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// </ul>
static NSString *const kFIREventAddToWishlist = @"add_to_wishlist";
/// App Open event. By logging this event when an App is moved to the foreground, developers can
/// understand how often users leave and return during the course of a Session. Although Sessions
/// are automatically reported, this event can provide further clarification around the continuous
/// engagement of app-users.
static NSString *const kFIREventAppOpen = @"app_open";
/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of
/// checking out. Add this event to a funnel with your kFIREventEcommercePurchase event to gauge the
/// effectiveness of your checkout process. Note: If you supply the @c kFIRParameterValue
/// parameter, you must also supply the @c kFIRParameterCurrency parameter so that revenue
/// metrics can be computed accurately. Params:
///
/// <ul>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterTransactionID (NSString) (optional)</li>
/// <li>@c kFIRParameterStartDate (NSString) (optional)</li>
/// <li>@c kFIRParameterEndDate (NSString) (optional)</li>
/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for
/// hotel bookings</li>
/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for
/// hotel bookings</li>
/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)
/// for travel bookings</li>
/// <li>@c kFIRParameterOrigin (NSString) (optional)</li>
/// <li>@c kFIRParameterDestination (NSString) (optional)</li>
/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>
/// </ul>
static NSString *const kFIREventBeginCheckout = @"begin_checkout";
/// Campaign Detail event. Log this event to supply the referral details of a re-engagement
/// campaign. Note: you must supply at least one of the required parameters kFIRParameterSource,
/// kFIRParameterMedium or kFIRParameterCampaign. Params:
///
/// <ul>
/// <li>@c kFIRParameterSource (NSString)</li>
/// <li>@c kFIRParameterMedium (NSString)</li>
/// <li>@c kFIRParameterCampaign (NSString)</li>
/// <li>@c kFIRParameterTerm (NSString) (optional)</li>
/// <li>@c kFIRParameterContent (NSString) (optional)</li>
/// <li>@c kFIRParameterAdNetworkClickID (NSString) (optional)</li>
/// <li>@c kFIRParameterCP1 (NSString) (optional)</li>
/// </ul>
static NSString *const kFIREventCampaignDetails = @"campaign_details";
/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log
/// this along with @c kFIREventSpendVirtualCurrency to better understand your virtual economy.
/// Params:
///
/// <ul>
/// <li>@c kFIRParameterVirtualCurrencyName (NSString)</li>
/// <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li>
/// </ul>
static NSString *const kFIREventEarnVirtualCurrency = @"earn_virtual_currency";
/// E-Commerce Purchase event. This event signifies that an item was purchased by a user. Note:
/// This is different from the in-app purchase event, which is reported automatically for App
/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also
/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed
/// accurately. Params:
///
/// <ul>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterTransactionID (NSString) (optional)</li>
/// <li>@c kFIRParameterTax (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCoupon (NSString) (optional)</li>
/// <li>@c kFIRParameterLocation (NSString) (optional)</li>
/// <li>@c kFIRParameterStartDate (NSString) (optional)</li>
/// <li>@c kFIRParameterEndDate (NSString) (optional)</li>
/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for
/// hotel bookings</li>
/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for
/// hotel bookings</li>
/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)
/// for travel bookings</li>
/// <li>@c kFIRParameterOrigin (NSString) (optional)</li>
/// <li>@c kFIRParameterDestination (NSString) (optional)</li>
/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>
/// </ul>
static NSString *const kFIREventEcommercePurchase = @"ecommerce_purchase";
/// Generate Lead event. Log this event when a lead has been generated in the app to understand the
/// efficacy of your install and re-engagement campaigns. Note: If you supply the
/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency
/// parameter so that revenue metrics can be computed accurately. Params:
///
/// <ul>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// </ul>
static NSString *const kFIREventGenerateLead = @"generate_lead";
/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use
/// this event to analyze how popular certain groups or social features are in your app. Params:
///
/// <ul>
/// <li>@c kFIRParameterGroupID (NSString)</li>
/// </ul>
static NSString *const kFIREventJoinGroup = @"join_group";
/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can
/// help you gauge the level distribution of your userbase and help you identify certain levels that
/// are difficult to pass. Params:
///
/// <ul>
/// <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber)</li>
/// <li>@c kFIRParameterCharacter (NSString) (optional)</li>
/// </ul>
static NSString *const kFIREventLevelUp = @"level_up";
/// Login event. Apps with a login feature can report this event to signify that a user has logged
/// in.
static NSString *const kFIREventLogin = @"login";
/// Post Score event. Log this event when the user posts a score in your gaming app. This event can
/// help you understand how users are actually performing in your game and it can help you correlate
/// high scores with certain audiences or behaviors. Params:
///
/// <ul>
/// <li>@c kFIRParameterScore (signed 64-bit integer as NSNumber)</li>
/// <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCharacter (NSString) (optional)</li>
/// </ul>
static NSString *const kFIREventPostScore = @"post_score";
/// Present Offer event. This event signifies that the app has presented a purchase offer to a user.
/// Add this event to a funnel with the kFIREventAddToCart and kFIREventEcommercePurchase to gauge
/// your conversion process. Note: If you supply the @c kFIRParameterValue parameter, you must
/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed
/// accurately. Params:
///
/// <ul>
/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li>
/// <li>@c kFIRParameterItemID (NSString)</li>
/// <li>@c kFIRParameterItemName (NSString)</li>
/// <li>@c kFIRParameterItemCategory (NSString)</li>
/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li>
/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// </ul>
static NSString *const kFIREventPresentOffer = @"present_offer";
/// E-Commerce Purchase Refund event. This event signifies that an item purchase was refunded.
/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the
/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately.
/// Params:
///
/// <ul>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterTransactionID (NSString) (optional)</li>
/// </ul>
static NSString *const kFIREventPurchaseRefund = @"purchase_refund";
/// Search event. Apps that support search features can use this event to contextualize search
/// operations by supplying the appropriate, corresponding parameters. This event can help you
/// identify the most popular content in your app. Params:
///
/// <ul>
/// <li>@c kFIRParameterSearchTerm (NSString)</li>
/// <li>@c kFIRParameterStartDate (NSString) (optional)</li>
/// <li>@c kFIRParameterEndDate (NSString) (optional)</li>
/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for
/// hotel bookings</li>
/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for
/// hotel bookings</li>
/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)
/// for travel bookings</li>
/// <li>@c kFIRParameterOrigin (NSString) (optional)</li>
/// <li>@c kFIRParameterDestination (NSString) (optional)</li>
/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>
/// </ul>
static NSString *const kFIREventSearch = @"search";
/// Select Content event. This general purpose event signifies that a user has selected some content
/// of a certain type in an app. The content can be any object in your app. This event can help you
/// identify popular content and categories of content in your app. Params:
///
/// <ul>
/// <li>@c kFIRParameterContentType (NSString)</li>
/// <li>@c kFIRParameterItemID (NSString)</li>
/// </ul>
static NSString *const kFIREventSelectContent = @"select_content";
/// Share event. Apps with social features can log the Share event to identify the most viral
/// content. Params:
///
/// <ul>
/// <li>@c kFIRParameterContentType (NSString)</li>
/// <li>@c kFIRParameterItemID (NSString)</li>
/// </ul>
static NSString *const kFIREventShare = @"share";
/// Sign Up event. This event indicates that a user has signed up for an account in your app. The
/// parameter signifies the method by which the user signed up. Use this event to understand the
/// different behaviors between logged in and logged out users. Params:
///
/// <ul>
/// <li>@c kFIRParameterSignUpMethod (NSString)</li>
/// </ul>
static NSString *const kFIREventSignUp = @"sign_up";
/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can
/// help you identify which virtual goods are the most popular objects of purchase. Params:
///
/// <ul>
/// <li>@c kFIRParameterItemName (NSString)</li>
/// <li>@c kFIRParameterVirtualCurrencyName (NSString)</li>
/// <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li>
/// </ul>
static NSString *const kFIREventSpendVirtualCurrency = @"spend_virtual_currency";
/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use
/// this in a funnel with kFIREventTutorialComplete to understand how many users complete this
/// process and move on to the full app experience.
static NSString *const kFIREventTutorialBegin = @"tutorial_begin";
/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding
/// process. Add this to a funnel with kFIREventTutorialBegin to gauge the completion rate of your
/// on-boarding process.
static NSString *const kFIREventTutorialComplete = @"tutorial_complete";
/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your
/// game. Since achievements generally represent the breadth of a gaming experience, this event can
/// help you understand how many users are experiencing all that your game has to offer. Params:
///
/// <ul>
/// <li>@c kFIRParameterAchievementID (NSString)</li>
/// </ul>
static NSString *const kFIREventUnlockAchievement = @"unlock_achievement";
/// View Item event. This event signifies that some content was shown to the user. This content may
/// be a product, a webpage or just a simple image or text. Use the appropriate parameters to
/// contextualize the event. Use this event to discover the most popular items viewed in your app.
/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the
/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately.
/// Params:
///
/// <ul>
/// <li>@c kFIRParameterItemID (NSString)</li>
/// <li>@c kFIRParameterItemName (NSString)</li>
/// <li>@c kFIRParameterItemCategory (NSString)</li>
/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li>
/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber) (optional)</li>
/// <li>@c kFIRParameterCurrency (NSString) (optional)</li>
/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li>
/// <li>@c kFIRParameterStartDate (NSString) (optional)</li>
/// <li>@c kFIRParameterEndDate (NSString) (optional)</li>
/// <li>@c kFIRParameterFlightNumber (NSString) (optional) for travel bookings</li>
/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional)
/// for travel bookings</li>
/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for
/// travel bookings</li>
/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for
/// travel bookings</li>
/// <li>@c kFIRParameterOrigin (NSString) (optional)</li>
/// <li>@c kFIRParameterDestination (NSString) (optional)</li>
/// <li>@c kFIRParameterSearchTerm (NSString) (optional) for travel bookings</li>
/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li>
/// </ul>
static NSString *const kFIREventViewItem = @"view_item";
/// View Item List event. Log this event when the user has been presented with a list of items of a
/// certain category. Params:
///
/// <ul>
/// <li>@c kFIRParameterItemCategory (NSString)</li>
/// </ul>
static NSString *const kFIREventViewItemList = @"view_item_list";
/// View Search Results event. Log this event when the user has been presented with the results of a
/// search. Params:
///
/// <ul>
/// <li>@c kFIRParameterSearchTerm (NSString)</li>
/// </ul>
static NSString *const kFIREventViewSearchResults = @"view_search_results";

View File

@@ -0,0 +1 @@
#import <FirebaseCore/FIROptions.h>

View File

@@ -0,0 +1,369 @@
/// @file FIRParameterNames.h
///
/// Predefined event parameter names.
///
/// Params supply information that contextualize Events. You can associate up to 25 unique Params
/// with each Event type. Some Params are suggested below for certain common Events, but you are
/// not limited to these. You may supply extra Params for suggested Events or custom Params for
/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric
/// characters and underscores ("_"), and must start with an alphabetic character. Param values can
/// be up to 100 characters long. The "firebase_" prefix is reserved and should not be used.
/// Game achievement ID (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterAchievementID : @"10_matches_won",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterAchievementID = @"achievement_id";
/// Ad Network Click ID (NSString). Used for network-specific click IDs which vary in format.
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterAdNetworkClickID : @"1234567",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterAdNetworkClickID = @"aclid";
/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to
/// capture campaign information, otherwise can be populated by developer. Highly Recommended
/// (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterCampaign : @"winter_promotion",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterCampaign = @"campaign";
/// Character used in game (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterCharacter : @"beat_boss",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterCharacter = @"character";
/// Campaign content (NSString).
static NSString *const kFIRParameterContent = @"content";
/// Type of content selected (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterContentType : @"news article",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterContentType = @"content_type";
/// Coupon code for a purchasable item (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterCoupon : @"zz123",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterCoupon = @"coupon";
/// Campaign custom parameter (NSString). Used as a method of capturing custom data in a campaign.
/// Use varies by network.
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterCP1 : @"custom_data",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterCP1 = @"cp1";
/// Purchase currency in 3-letter <a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes">
/// ISO_4217</a> format (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterCurrency : @"USD",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterCurrency = @"currency";
/// Flight or Travel destination (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterDestination : @"Mountain View, CA",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterDestination = @"destination";
/// The arrival date, check-out date or rental end date for the item. This should be in
/// YYYY-MM-DD format (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterEndDate : @"2015-09-14",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterEndDate = @"end_date";
/// Flight number for travel events (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterFlightNumber : @"ZZ800",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterFlightNumber = @"flight_number";
/// Group/clan/guild ID (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterGroupID : @"g1",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterGroupID = @"group_id";
/// Item category (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterItemCategory : @"t-shirts",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterItemCategory = @"item_category";
/// Item ID (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterItemID : @"p7654",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterItemID = @"item_id";
/// The Google <a href="https://developers.google.com/places/place-id">Place ID</a> (NSString) that
/// corresponds to the associated item. Alternatively, you can supply your own custom Location ID.
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterItemLocationID : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterItemLocationID = @"item_location_id";
/// Item name (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterItemName : @"abc",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterItemName = @"item_name";
/// Level in game (signed 64-bit integer as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterLevel : @(42),
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterLevel = @"level";
/// Location (NSString). The Google <a href="https://developers.google.com/places/place-id">Place ID
/// </a> that corresponds to the associated event. Alternatively, you can supply your own custom
/// Location ID.
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterLocation : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterLocation = @"location";
/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended
/// (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterMedium : @"email",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterMedium = @"medium";
/// Number of nights staying at hotel (signed 64-bit integer as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterNumberOfNights : @(3),
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterNumberOfNights = @"number_of_nights";
/// Number of passengers traveling (signed 64-bit integer as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterNumberOfPassengers : @(11),
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterNumberOfPassengers = @"number_of_passengers";
/// Number of rooms for travel events (signed 64-bit integer as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterNumberOfRooms : @(2),
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterNumberOfRooms = @"number_of_rooms";
/// Flight or Travel origin (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterOrigin : @"Mountain View, CA",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterOrigin = @"origin";
/// Purchase price (double as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterPrice : @(1.0),
/// kFIRParameterCurrency : @"USD", // e.g. $1.00 USD
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterPrice = @"price";
/// Purchase quantity (signed 64-bit integer as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterQuantity : @(1),
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterQuantity = @"quantity";
/// Score in game (signed 64-bit integer as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterScore : @(4200),
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterScore = @"score";
/// The search string/keywords used (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterSearchTerm : @"periodic table",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterSearchTerm = @"search_term";
/// Shipping cost (double as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterShipping : @(9.50),
/// kFIRParameterCurrency : @"USD", // e.g. $9.50 USD
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterShipping = @"shipping";
/// Sign up method (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterSignUpMethod : @"google",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterSignUpMethod = @"sign_up_method";
/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban
/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your
/// property. Highly recommended (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterSource : @"InMobi",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterSource = @"source";
/// The departure date, check-in date or rental start date for the item. This should be in
/// YYYY-MM-DD format (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterStartDate : @"2015-09-14",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterStartDate = @"start_date";
/// Tax amount (double as NSNumber).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterTax : @(1.0),
/// kFIRParameterCurrency : @"USD", // e.g. $1.00 USD
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterTax = @"tax";
/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword
/// (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterTerm : @"game",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterTerm = @"term";
/// A single ID for a ecommerce group transaction (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterTransactionID : @"ab7236dd9823",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterTransactionID = @"transaction_id";
/// Travel class (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterTravelClass : @"business",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterTravelClass = @"travel_class";
/// A context-specific numeric value which is accumulated automatically for each event type. This is
/// a general purpose parameter that is useful for accumulating a key metric that pertains to an
/// event. Examples include revenue, distance, time and points. Value should be specified as signed
/// 64-bit integer or double as NSNumber. Notes: Values for pre-defined currency-related events
/// (such as @c kFIREventAddToCart) should be supplied using double as NSNumber and must be
/// accompanied by a @c kFIRParameterCurrency parameter. The valid range of accumulated values is
/// [-9,223,372,036,854.77, 9,223,372,036,854.77].
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterValue : @(3.99),
/// kFIRParameterCurrency : @"USD", // e.g. $3.99 USD
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterValue = @"value";
/// Name of virtual currency type (NSString).
/// <pre>
/// NSDictionary *params = @{
/// kFIRParameterVirtualCurrencyName : @"virtual_currency_name",
/// // ...
/// };
/// </pre>
static NSString *const kFIRParameterVirtualCurrencyName = @"virtual_currency_name";

View File

@@ -0,0 +1,13 @@
/// @file FIRUserPropertyNames.h
///
/// Predefined user property names.
///
/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can
/// later analyze different behaviors of various segments of your userbase. You may supply up to 25
/// unique UserProperties per app, and you can use the name and value of your choosing for each one.
/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and
/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to
/// 36 characters long. The "firebase_" prefix is reserved and should not be used.
/// The method used to sign in. For example, "google", "facebook" or "twitter".
static NSString *const kFIRUserPropertySignUpMethod = @"sign_up_method";

View File

@@ -0,0 +1,9 @@
#import "FIRAnalyticsConfiguration.h"
#import "FIRApp.h"
#import "FIRConfiguration.h"
#import "FIROptions.h"
#import "FIRAnalytics+AppDelegate.h"
#import "FIRAnalytics.h"
#import "FIREventNames.h"
#import "FIRParameterNames.h"
#import "FIRUserPropertyNames.h"

View File

@@ -0,0 +1,8 @@
framework module FirebaseAnalytics {
umbrella header "FirebaseAnalytics.h"
export *
module * { export *}
link "sqlite3"
link "z"
link framework "UIKit"
}

38
Task Master/Pods/FirebaseAuth/CHANGELOG.md generated Executable file
View File

@@ -0,0 +1,38 @@
# 2017-02-06 -- v3.1.1
- Allows handling of additional errors when sending OOB action emails. The
server can respond with the following new error messages:
INVALID_MESSAGE_PAYLOAD,INVALID_SENDER and INVALID_RECIPIENT_EMAIL.
- Removes incorrect reference to FIRAuthErrorCodeCredentialTooOld in FIRUser.h.
- Provides additional error information from server if available.
# 2016-12-13 -- v3.1.0
- Adds FIRAuth methods that enable the app to follow up with user actions
delivered by email, such as verifying email address or reset password.
- No longer applies the keychain workaround introduced in v3.0.5 on iOS 10.2
simulator or above since the issue has been fixed.
- Fixes nullability compilation warnings when used in Swift.
- Better reports missing password error.
# 2016-10-24 -- v3.0.6
- Switches to depend on open sourced GoogleToolboxForMac and GTMSessionFetcher.
- Improves logging of keychain error when initializing.
# 2016-09-14 -- v3.0.5
- Works around a keychain issue in iOS 10 simulator.
- Reports the correct error for invalid email when signing in with email and
password.
# 2016-07-18 -- v3.0.4
- Fixes a race condition bug that could crash the app with an exception from
NSURLSession on iOS 9.
# 2016-06-20 -- v3.0.3
- Adds documentation for all possible errors returned by each method.
- Improves error handling and messages for a variety of error conditions.
- Whether or not an user is considered anonymous is now consistent with other
platforms.
- A saved signed in user is now siloed between different Firebase projects
within the same app.
# 2016-05-18 -- v3.0.2
- Initial public release.

View File

@@ -0,0 +1,488 @@
/** @file FIRAuth.h
@brief Firebase Auth SDK
@copyright Copyright 2015 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
#import "FIRAuthErrors.h"
@class FIRApp;
@class FIRAuth;
@class FIRAuthCredential;
@class FIRUser;
@protocol FIRAuthStateListener;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthStateDidChangeListenerHandle
@brief The type of handle returned by @c FIRAuth.addAuthStateDidChangeListener:.
*/
typedef id<NSObject> FIRAuthStateDidChangeListenerHandle;
/** @typedef FIRAuthStateDidChangeListenerBlock
@brief The type of block which can be registered as a listener for auth state did change events.
@param auth The FIRAuth object on which state changes occurred.
@param user Optionally; the current signed in user, if any.
*/
typedef void(^FIRAuthStateDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nullable user);
/**
@brief The name of the @c NSNotificationCenter notification which is posted when the auth state
changes (for example, a new token has been produced, a user signs in or signs out). The
object parameter of the notification is the sender @c FIRAuth instance.
*/
extern NSString *const FIRAuthStateDidChangeNotification;
/** @typedef FIRAuthResultCallback
@brief The type of block invoked when sign-in related events complete.
@param user Optionally; the signed in user, if any.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRAuthResultCallback)(FIRUser *_Nullable user, NSError *_Nullable error);
/** @typedef FIRProviderQueryCallback
@brief The type of block invoked when a list of identity providers for a given email address is
requested.
@param providers Optionally; a list of provider identifiers, if any.
@see FIRGoogleAuthProviderID etc.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRProviderQueryCallback)(NSArray<NSString *> *_Nullable providers,
NSError *_Nullable error);
/** @typedef FIRSendPasswordResetCallback
@brief The type of block invoked when sending a password reset email.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRSendPasswordResetCallback)(NSError *_Nullable error);
/** @typedef FIRConfirmPasswordResetCallback
@brief The type of block invoked when performing a password reset.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRConfirmPasswordResetCallback)(NSError *_Nullable error);
/** @typedef FIRVerifyPasswordResetCodeCallback
@brief The type of block invoked when verifying that an out of band code should be used to
perform password reset.
@param email Optionally; the email address of the user for which the out of band code applies.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRVerifyPasswordResetCodeCallback)(NSString *_Nullable email,
NSError *_Nullable error);
/** @typedef FIRApplyActionCodeCallback
@brief The type of block invoked when applying an action code.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRApplyActionCodeCallback)(NSError *_Nullable error);
/**
@brief Keys used to retrieve operation data from a @c FIRActionCodeInfo object by the @c
dataForKey method.
*/
typedef NS_ENUM(NSInteger, FIRActionDataKey) {
/**
* The email address to which the code was sent.
* For FIRActionCodeOperationRecoverEmail, the new email address for the account.
*/
FIRActionCodeEmailKey = 0,
/** For FIRActionCodeOperationRecoverEmail, the current email address for the account. */
FIRActionCodeFromEmailKey = 1
};
/** @class FIRActionCodeInfo
@brief Manages information regarding action codes.
*/
@interface FIRActionCodeInfo : NSObject
/**
@brief Operations which can be performed with action codes.
*/
typedef NS_ENUM(NSInteger, FIRActionCodeOperation) {
/** Action code for unknown operation. */
FIRActionCodeOperationUnknown = 0,
/** Action code for password reset operation. */
FIRActionCodeOperationPasswordReset = 1,
/** Action code for verify email operation. */
FIRActionCodeOperationVerifyEmail = 2
};
/**
@brief The operation being performed.
*/
@property(nonatomic, readonly) FIRActionCodeOperation operation;
/** @fn dataForKey:
@brief The operation being performed.
@param key The FIRActionDataKey value used to retrieve the operation data.
@return The operation data pertaining to the provided action code key.
*/
- (NSString *)dataForKey:(FIRActionDataKey)key;
/** @fn init
@brief please use initWithOperation: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
/** @typedef FIRCheckActionCodeCallBack
@brief The type of block invoked when performing a check action code operation.
@param info Metadata corresponding to the action code.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRCheckActionCodeCallBack)(FIRActionCodeInfo *_Nullable info,
NSError *_Nullable error);
/** @class FIRAuth
@brief Manages authentication for Firebase apps.
@remarks This class is thread-safe.
*/
@interface FIRAuth : NSObject
/** @fn auth
@brief Gets the auth object for the default Firebase app.
@remarks Thread safe.
*/
+ (nullable FIRAuth *)auth NS_SWIFT_NAME(auth());
/** @fn authWithApp:
@brief Gets the auth object for a @c FIRApp.
@param app The FIRApp for which to retrieve the associated FIRAuth instance.
@return The FIRAuth instance associated with the given FIRApp.
*/
+ (nullable FIRAuth *)authWithApp:(FIRApp *)app;
/** @property app
@brief Gets the @c FIRApp object that this auth object is connected to.
*/
@property(nonatomic, weak, readonly, nullable) FIRApp *app;
/** @property currentUser
@brief Synchronously gets the cached current user, or null if there is none.
*/
@property(nonatomic, strong, readonly, nullable) FIRUser *currentUser;
/** @fn init
@brief Please access auth instances using @c FIRAuth.auth and @c FIRAuth.authForApp:.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn fetchProvidersForEmail:completion:
@brief Fetches the list of IdPs that can be used for signing in with the provided email address.
Useful for an "identifier-first" sign-in flow.
@param email The email address for which to obtain a list of identity providers.
@param completion Optionally; a block which is invoked when the list of providers for the
specified email address is ready or an error was encountered. Invoked asynchronously on the
main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)fetchProvidersForEmail:(NSString *)email
completion:(nullable FIRProviderQueryCallback)completion;
/** @fn signInWithEmail:password:completion:
@brief Signs in using an email address and password.
@param email The user's email address.
@param password The user's password.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password
accounts are not enabled. Enable them in the Auth section of the
Firebase console.
</li>
<li>@c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled.
</li>
<li>@c FIRAuthErrorCodeWrongPassword - Indicates the user attempted
sign in with an incorrect password.
</li>
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)signInWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthResultCallback)completion;
/** @fn signInWithCredential:completion:
@brief Asynchronously signs in to Firebase with the given 3rd-party credentials (e.g. a Facebook
login Access Token, a Google ID Token/Access Token pair, etc.)
@param credential The credential supplied by the IdP.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidCredential - Indicates the supplied credential is invalid.
This could happen if it has expired or it is malformed.
</li>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts
with the identity provider represented by the credential are not enabled.
Enable them in the Auth section of the Firebase console.
</li>
<li>@c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email asserted by the credential
(e.g. the email in a Facebook access token) is already in use by an existing account,
that cannot be authenticated with this sign-in method. Call fetchProvidersForEmail for
this users email and then prompt them to sign in with any of the sign-in providers
returned. This error will only be thrown if the "One account per email address"
setting is enabled in the Firebase console, under Auth settings. Please note that the
error code raised in this specific situation may not be the same on
Web and Android.
</li>
<li>@c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled.
</li>
<li>@c FIRAuthErrorCodeWrongPassword - Indicates the user attempted sign in with an
incorrect password, if credential is of the type EmailPasswordAuthCredential.
</li>
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)signInWithCredential:(FIRAuthCredential *)credential
completion:(nullable FIRAuthResultCallback)completion;
/** @fn signInAnonymouslyWithCompletion:
@brief Asynchronously creates and becomes an anonymous user.
@param completion Optionally; a block which is invoked when the sign in finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks If there is already an anonymous user signed in, that user will be returned instead.
If there is any other existing user signed in, that user will be signed out.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that anonymous accounts are
not enabled. Enable them in the Auth section of the Firebase console.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)signInAnonymouslyWithCompletion:(nullable FIRAuthResultCallback)completion;
/** @fn signInWithCustomToken:completion:
@brief Asynchronously signs in to Firebase with the given Auth token.
@param token A self-signed custom auth token.
@param completion Optionally; a block which is invoked when the sign in finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidCustomToken - Indicates a validation error with
the custom token.
</li>
<li>@c FIRAuthErrorCodeCustomTokenMismatch - Indicates the service account and the API key
belong to different projects.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)signInWithCustomToken:(NSString *)token
completion:(nullable FIRAuthResultCallback)completion;
/** @fn createUserWithEmail:password:completion:
@brief Creates and, on success, signs in a user with the given email address and password.
@param email The user's email address.
@param password The user's desired password.
@param completion Optionally; a block which is invoked when the sign up flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
</li>
<li>@c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email used to attempt sign up
already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user
used, and prompt the user to sign in with one of those.
</li>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password accounts
are not enabled. Enable them in the Auth section of the Firebase console.
</li>
<li>@c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is
considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo
dictionary object will contain more detailed explanation that can be shown to the user.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)createUserWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthResultCallback)completion;
/** @fn confirmPasswordResetWithCode:newPassword:completion:
@brief Resets the password given a code sent to the user outside of the app and a new password
for the user.
@param newPassword The new password.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is
considered too weak.
</li>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates the administrator disabled sign
in with the specified identity provider.
</li>
<li>@c FIRAuthErrorCodeExpiredActionCode - Indicates the OOB code is expired.
</li>
<li>@c FIRAuthErrorCodeInvalidActionCode - Indicates the OOB code is invalid.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)confirmPasswordResetWithCode:(NSString *)code
newPassword:(NSString *)newPassword
completion:(FIRConfirmPasswordResetCallback)completion;
/** @fn checkActionCode:completion:
@brief Checks the validity of an out of band code.
@param code The out of band code to check validity.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
*/
- (void)checkActionCode:(NSString *)code completion:(FIRCheckActionCodeCallBack)completion;
/** @fn verifyPasswordResetCode:completion:
@brief Checks the validity of a verify password reset code.
@param code The password reset code to be verified.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
*/
- (void)verifyPasswordResetCode:(NSString *)code
completion:(FIRVerifyPasswordResetCodeCallback)completion;
/** @fn applyActionCode:completion:
@brief Applies out of band code.
@param code The out of band code to be applied.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks This method will not work for out of band codes which require an additional parameter,
such as password reset code.
*/
- (void)applyActionCode:(NSString *)code
completion:(FIRApplyActionCodeCallback)completion;
/** @fn sendPasswordResetWithEmail:completion:
@brief Initiates a password reset for the given email address.
@param email The email address of the user.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was
sent in the request.
</li>
<li>@c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in
the console for this action.
</li>
<li>@c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for
sending update email.
</li>
</ul>
*/
- (void)sendPasswordResetWithEmail:(NSString *)email
completion:(nullable FIRSendPasswordResetCallback)completion;
/** @fn signOut:
@brief Signs out the current user.
@param error Optionally; if an error occurs, upon return contains an NSError object that
describes the problem; is nil otherwise.
@return @YES when the sign out request was successful. @NO otherwise.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeKeychainError - Indicates an error occurred when accessing the
keychain. The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo
dictionary will contain more information about the error encountered.
</li>
</ul>
*/
- (BOOL)signOut:(NSError *_Nullable *_Nullable)error;
/** @fn addAuthStateDidChangeListener:
@brief Registers a block as an "auth state did change" listener. To be invoked when:
+ The block is registered as a listener,
+ The current user changes, or,
+ The current user's access token changes.
@param listener The block to be invoked. The block is always invoked asynchronously on the main
thread, even for it's initial invocation after having been added as a listener.
@remarks The block is invoked immediately after adding it according to it's standard invocation
semantics, asynchronously on the main thread. Users should pay special attention to
making sure the block does not inadvertently retain objects which should not be retained by
the long-lived block. The block itself will be retained by @c FIRAuth until it is
unregistered or until the @c FIRAuth instance is otherwise deallocated.
@return A handle useful for manually unregistering the block as a listener.
*/
- (FIRAuthStateDidChangeListenerHandle)addAuthStateDidChangeListener:
(FIRAuthStateDidChangeListenerBlock)listener;
/** @fn removeAuthStateDidChangeListener:
@brief Unregisters a block as an "auth state did change" listener.
@param listenerHandle The handle for the listener.
*/
- (void)removeAuthStateDidChangeListener:(FIRAuthStateDidChangeListenerHandle)listenerHandle;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,31 @@
/** @file FIRAuthCredential.h
@brief Firebase Auth SDK
@copyright Copyright 2015 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthCredential
@brief Represents a credential.
*/
@interface FIRAuthCredential : NSObject
/** @property provider
@brief Gets the name of the identity provider for the credential.
*/
@property(nonatomic, copy, readonly) NSString *provider;
/** @fn init
@brief This is an abstract base class. Concrete instances should be created via factory
methods available in the various authentication provider libraries (like the Facebook
provider or the Google provider libraries.)
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,176 @@
/** @file FIRAuthErrors.h
@brief Firebase Auth SDK
@copyright Copyright 2015 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
/** @class FIRAuthErrors
@remarks Error Codes common to all API Methods:
<ul>
<li>@c FIRAuthErrorCodeNetworkError</li>
<li>@c FIRAuthErrorCodeUserNotFound</li>
<li>@c FIRAuthErrorCodeUserTokenExpired</li>
<li>@c FIRAuthErrorCodeTooManyRequests</li>
<li>@c FIRAuthErrorCodeInvalidAPIKey</li>
<li>@c FIRAuthErrorCodeAppNotAuthorized</li>
<li>@c FIRAuthErrorCodeKeychainError</li>
<li>@c FIRAuthErrorCodeInternalError</li>
</ul>
@remarks Common error codes for @c FIRUser operations:
<ul>
<li>@c FIRAuthErrorCodeInvalidUserToken</li>
<li>@c FIRAuthErrorCodeUserDisabled</li>
</ul>
*/
@interface FIRAuthErrors
/**
@brief The Firebase Auth error domain.
*/
extern NSString *const FIRAuthErrorDomain;
/**
@brief The name of the key for the "error_name" string in the NSError userinfo dictionary.
*/
extern NSString *const FIRAuthErrorNameKey;
/**
@brief Error codes used by Firebase Auth.
*/
typedef NS_ENUM(NSInteger, FIRAuthErrorCode) {
/** Indicates a validation error with the custom token.
*/
FIRAuthErrorCodeInvalidCustomToken = 17000,
/** Indicates the service account and the API key belong to different projects.
*/
FIRAuthErrorCodeCustomTokenMismatch = 17002,
/** Indicates the IDP token or requestUri is invalid.
*/
FIRAuthErrorCodeInvalidCredential = 17004,
/** Indicates the user's account is disabled on the server.
*/
FIRAuthErrorCodeUserDisabled = 17005,
/** Indicates the administrator disabled sign in with the specified identity provider.
*/
FIRAuthErrorCodeOperationNotAllowed = 17006,
/** Indicates the email used to attempt a sign up is already in use.
*/
FIRAuthErrorCodeEmailAlreadyInUse = 17007,
/** Indicates the email is invalid.
*/
FIRAuthErrorCodeInvalidEmail = 17008,
/** Indicates the user attempted sign in with a wrong password.
*/
FIRAuthErrorCodeWrongPassword = 17009,
/** Indicates that too many requests were made to a server method.
*/
FIRAuthErrorCodeTooManyRequests = 17010,
/** Indicates the user account was not found.
*/
FIRAuthErrorCodeUserNotFound = 17011,
/** Indicates account linking is required.
*/
FIRAuthErrorCodeAccountExistsWithDifferentCredential = 17012,
/** Same enum as @c FIRAuthErrorCodeAccountExistsWithDifferentCredential ,
but with incorrect spelling. Only exists for backwards compatiblity.
*/
FIRAuthErrrorCodeAccountExistsWithDifferentCredential = 17012,
/** Indicates the user has attemped to change email or password more than 5 minutes after
signing in.
*/
FIRAuthErrorCodeRequiresRecentLogin = 17014,
/** Indicates an attempt to link a provider to which the account is already linked.
*/
FIRAuthErrorCodeProviderAlreadyLinked = 17015,
/** Indicates an attempt to unlink a provider that is not linked.
*/
FIRAuthErrorCodeNoSuchProvider = 17016,
/** Indicates user's saved auth credential is invalid, the user needs to sign in again.
*/
FIRAuthErrorCodeInvalidUserToken = 17017,
/** Indicates a network error occurred (such as a timeout, interrupted connection, or
unreachable host). These types of errors are often recoverable with a retry. The @c
NSUnderlyingError field in the @c NSError.userInfo dictionary will contain the error
encountered.
*/
FIRAuthErrorCodeNetworkError = 17020,
/** Indicates the saved token has expired, for example, the user may have changed account
password on another device. The user needs to sign in again on the device that made this
request.
*/
FIRAuthErrorCodeUserTokenExpired = 17021,
/** Indicates an invalid API key was supplied in the request.
*/
FIRAuthErrorCodeInvalidAPIKey = 17023,
/** Indicates that an attempt was made to reauthenticate with a user which is not the current
user.
*/
FIRAuthErrorCodeUserMismatch = 17024,
/** Indicates an attempt to link with a credential that has already been linked with a
different Firebase account
*/
FIRAuthErrorCodeCredentialAlreadyInUse = 17025,
/** Indicates an attempt to set a password that is considered too weak.
*/
FIRAuthErrorCodeWeakPassword = 17026,
/** Indicates the App is not authorized to use Firebase Authentication with the
provided API Key.
*/
FIRAuthErrorCodeAppNotAuthorized = 17028,
/** Indicates the OOB code is expired.
*/
FIRAuthErrorCodeExpiredActionCode = 17029,
/** Indicates the OOB code is invalid.
*/
FIRAuthErrorCodeInvalidActionCode = 17030,
/** Indicates that there are invalid parameters in the payload during a "send password reset
* email" attempt.
*/
FIRAuthErrorCodeInvalidMessagePayload = 17031,
/** Indicates that the sender email is invalid during a "send password reset email" attempt.
*/
FIRAuthErrorCodeInvalidSender = 17032,
/** Indicates that the recipient email is invalid.
*/
FIRAuthErrorCodeInvalidRecipientEmail = 17033,
/** Indicates an error occurred while attempting to access the keychain.
*/
FIRAuthErrorCodeKeychainError = 17995,
/** Indicates an internal error occurred.
*/
FIRAuthErrorCodeInternalError = 17999,
};
@end

View File

@@ -0,0 +1,40 @@
/** @file FIREmailPasswordAuthProvider.h
@brief Firebase Auth SDK
@copyright Copyright 2016 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the email & password identity provider.
*/
extern NSString *const FIREmailPasswordAuthProviderID;
/** @class FIREmailPasswordAuthProvider
@brief A concrete implementation of @c FIRAuthProvider for Email & Password Sign In.
*/
@interface FIREmailPasswordAuthProvider : NSObject
/** @fn credentialWithEmail:password:
@brief Creates an @c FIRAuthCredential for an email & password sign in.
@param email The user's email address.
@param password The user's password.
@return A FIRAuthCredential containing the email & password credential.
*/
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password;
/** @fn init
@brief This class is not meant to be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,39 @@
/** @file FIRFacebookAuthProvider.h
@brief Firebase Auth SDK
@copyright Copyright 2016 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the Facebook identity provider.
*/
extern NSString *const FIRFacebookAuthProviderID;
/** @class FIRFacebookAuthProvider
@brief Utility class for constructing Facebook credentials.
*/
@interface FIRFacebookAuthProvider : NSObject
/** @fn credentialWithAccessToken:
@brief Creates an @c FIRAuthCredential for a Facebook sign in.
@param accessToken The Access Token from Facebook.
@return A FIRAuthCredential containing the Facebook credentials.
*/
+ (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken;
/** @fn init
@brief This class should not be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,39 @@
/** @file FIRGitHubAuthProvider.h
@brief Firebase Auth SDK
@copyright Copyright 2016 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the GitHub identity provider.
*/
extern NSString *const FIRGitHubAuthProviderID;
/** @class FIRGitHubAuthProvider
@brief Utility class for constructing GitHub credentials.
*/
@interface FIRGitHubAuthProvider : NSObject
/** @fn credentialWithToken:
@brief Creates an @c FIRAuthCredential for a GitHub sign in.
@param token The GitHub OAuth access token.
@return A FIRAuthCredential containing the GitHub credential.
*/
+ (FIRAuthCredential *)credentialWithToken:(NSString *)token;
/** @fn init
@brief This class is not meant to be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,41 @@
/** @file FIRGoogleAuthProvider.h
@brief Firebase Auth SDK
@copyright Copyright 2016 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the Google identity provider.
*/
extern NSString *const FIRGoogleAuthProviderID;
/** @class FIRGoogleAuthProvider
@brief Utility class for constructing Google Sign In credentials.
*/
@interface FIRGoogleAuthProvider : NSObject
/** @fn credentialWithIDToken:accessToken:
@brief Creates an @c FIRAuthCredential for a Google sign in.
@param IDToken The ID Token from Google.
@param accessToken The Access Token from Google.
@return A FIRAuthCredential containing the Google credentials.
*/
+ (FIRAuthCredential *)credentialWithIDToken:(NSString *)IDToken
accessToken:(NSString *)accessToken;
/** @fn init
@brief This class should not be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,40 @@
/** @file FIRTwitterAuthProvider.h
@brief Firebase Auth SDK
@copyright Copyright 2016 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the Twitter identity provider.
*/
extern NSString *const FIRTwitterAuthProviderID;
/** @class FIRTwitterAuthProvider
@brief Utility class for constructing Twitter credentials.
*/
@interface FIRTwitterAuthProvider : NSObject
/** @fn credentialWithToken:secret:
@brief Creates an @c FIRAuthCredential for a Twitter sign in.
@param token The Twitter OAuth token.
@param secret The Twitter OAuth secret.
@return A FIRAuthCredential containing the Twitter credential.
*/
+ (FIRAuthCredential *)credentialWithToken:(NSString *)token secret:(NSString *)secret;
/** @fn init
@brief This class is not meant to be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,376 @@
/** @file FIRUser.h
@brief Firebase Auth SDK
@copyright Copyright 2015 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
#import "FIRAuth.h"
#import "FIRUserInfo.h"
@class FIRUserProfileChangeRequest;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthTokenCallback
@brief The type of block called when a token is ready for use.
@see FIRUser.getTokenWithCompletion:
@see FIRUser.getTokenForcingRefresh:withCompletion:
@param token Optionally; an access token if the request was successful.
@param error Optionally; the error which occurred - or nil if the request was successful.
@remarks One of: @c token or @c error will always be non-nil.
*/
typedef void (^FIRAuthTokenCallback)(NSString *_Nullable token, NSError *_Nullable error);
/** @typedef FIRUserProfileChangeCallback
@brief The type of block called when a user profile change has finished.
@param error Optionally; the error which occurred - or nil if the request was successful.
*/
typedef void (^FIRUserProfileChangeCallback)(NSError *_Nullable error);
/** @typedef FIRSendEmailVerificationCallback
@brief The type of block called when a request to send an email verification has finished.
@param error Optionally; the error which occurred - or nil if the request was successful.
*/
typedef void (^FIRSendEmailVerificationCallback)(NSError *_Nullable error);
/** @class FIRUser
@brief Represents a user.
@remarks This class is thread-safe.
*/
@interface FIRUser : NSObject <FIRUserInfo>
/** @property anonymous
@brief Indicates the user represents an anonymous user.
*/
@property(nonatomic, readonly, getter=isAnonymous) BOOL anonymous;
/** @property emailVerified
@brief Indicates the email address associated with this user has been verified.
*/
@property(nonatomic, readonly, getter=isEmailVerified) BOOL emailVerified;
/** @property refreshToken
@brief A refresh token; useful for obtaining new access tokens independently.
@remarks This property should only be used for advanced scenarios, and is not typically needed.
*/
@property(nonatomic, readonly, nullable) NSString *refreshToken;
/** @property providerData
@brief Profile data for each identity provider, if any.
@remarks This data is cached on sign-in and updated when linking or unlinking.
*/
@property(nonatomic, readonly, nonnull) NSArray<id<FIRUserInfo>> *providerData;
/** @fn init
@brief This class should not be instantiated.
@remarks To retrieve the current user, use @c FIRAuth.currentUser. To sign a user
in or out, use the methods on @c FIRAuth.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn updateEmail:completion:
@brief Updates the email address for the user. On success, the cached user profile data is
updated.
@remarks May fail if there is already an account with this email address that was created using
email and password authentication.
@param email The email address for the user.
@param completion Optionally; the block invoked when the user profile change has finished.
Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was
sent in the request.
</li>
<li>@c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in
the console for this action.
</li>
<li>@c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for
sending update email.
</li>
<li>@c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email is already in use by another
account.
</li>
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
</li>
<li>@c FIRAuthErrorCodeRequiresRecentLogin - Updating a users email is a security
sensitive operation that requires a recent login from the user. This error indicates
the user has not signed in recently enough. To resolve, reauthenticate the user by
invoking reauthenticateWithCredential:completion: on FIRUser.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods.
*/
- (void)updateEmail:(NSString *)email completion:(nullable FIRUserProfileChangeCallback)completion;
/** @fn updatePassword:completion:
@brief Updates the password for the user. On success, the cached user profile data is updated.
@param password The new password for the user.
@param completion Optionally; the block invoked when the user profile change has finished.
Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates the administrator disabled
sign in with the specified identity provider.
</li>
<li>@c FIRAuthErrorCodeRequiresRecentLogin - Updating a users password is a security
sensitive operation that requires a recent login from the user. This error indicates
the user has not signed in recently enough. To resolve, reauthenticate the user by
invoking reauthenticateWithCredential:completion: on FIRUser.
</li>
<li>@c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is
considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo
dictionary object will contain more detailed explanation that can be shown to the user.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods.
*/
- (void)updatePassword:(NSString *)password
completion:(nullable FIRUserProfileChangeCallback)completion;
/** @fn profileChangeRequest
@brief Creates an object which may be used to change the user's profile data.
@remarks Set the properties of the returned object, then call
@c FIRUserProfileChangeRequest.commitChangesWithCallback: to perform the updates atomically.
@return An object which may be used to change the user's profile data atomically.
*/
- (FIRUserProfileChangeRequest *)profileChangeRequest;
/** @fn reloadWithCompletion:
@brief Reloads the user's profile data from the server.
@param completion Optionally; the block invoked when the reload has finished. Invoked
asynchronously on the main thread in the future.
@remarks May fail with a @c FIRAuthErrorCodeRequiresRecentLogin error code. In this case
you should call @c FIRUser.reauthenticateWithCredential:completion: before re-invoking
@c FIRUser.updateEmail:completion:.
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)reloadWithCompletion:(nullable FIRUserProfileChangeCallback)completion;
/** @fn reauthenticateWithCredential:completion:
@brief Renews the user's authentication tokens by validating a fresh set of credentials supplied
by the user.
@param credential A user-supplied credential, which will be validated by the server. This can be
a successful third-party identity provider sign-in, or an email address and password.
@param completion Optionally; the block invoked when the re-authentication operation has
finished. Invoked asynchronously on the main thread in the future.
@remarks If the user associated with the supplied credential is different from the current user,
or if the validation of the supplied credentials fails; an error is returned and the current
user remains signed in.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidCredential - Indicates the supplied credential is invalid.
This could happen if it has expired or it is malformed.
</li>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts with the
identity provider represented by the credential are not enabled. Enable them in the
Auth section of the Firebase console.
</li>
<li>@c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email asserted by the credential
(e.g. the email in a Facebook access token) is already in use by an existing account,
that cannot be authenticated with this method. Call fetchProvidersForEmail for
this users email and then prompt them to sign in with any of the sign-in providers
returned. This error will only be thrown if the "One account per email address"
setting is enabled in the Firebase console, under Auth settings. Please note that the
error code raised in this specific situation may not be the same on Web and Android.
</li>
<li>@c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled.
</li>
<li>@c FIRAuthErrorCodeWrongPassword - Indicates the user attempted reauthentication with
an incorrect password, if credential is of the type EmailPasswordAuthCredential.
</li>
<li>@c FIRAuthErrorCodeUserMismatch - Indicates that an attempt was made to
reauthenticate with a user which is not the current user.
</li>
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)reauthenticateWithCredential:(FIRAuthCredential *)credential
completion:(nullable FIRUserProfileChangeCallback)completion;
/** @fn getTokenWithCompletion:
@brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired.
@param completion Optionally; the block invoked when the token is available. Invoked
asynchronously on the main thread in the future.
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)getTokenWithCompletion:(nullable FIRAuthTokenCallback)completion;
/** @fn getTokenForcingRefresh:completion:
@brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired.
@param forceRefresh Forces a token refresh. Useful if the token becomes invalid for some reason
other than an expiration.
@param completion Optionally; the block invoked when the token is available. Invoked
asynchronously on the main thread in the future.
@remarks The authentication token will be refreshed (by making a network request) if it has
expired, or if @c forceRefresh is YES.
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)getTokenForcingRefresh:(BOOL)forceRefresh
completion:(nullable FIRAuthTokenCallback)completion;
/** @fn linkWithCredential:completion:
@brief Associates a user account from a third-party identity provider with this user.
@param credential The credential for the identity provider.
@param completion Optionally; the block invoked when the unlinking is complete, or fails.
Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeProviderAlreadyLinked - Indicates an attempt to link a provider of a
type already linked to this account.
</li>
<li>@c FIRAuthErrorCodeCredentialAlreadyInUse - Indicates an attempt to link with a
credential
that has already been linked with a different Firebase account.
</li>
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts with the identity
provider represented by the credential are not enabled. Enable them in the Auth section
of the Firebase console.
</li>
</ul>
@remarks This method may also return error codes associated with updateEmail:completion: and
updatePassword:completion: on FIRUser.
@remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods.
*/
- (void)linkWithCredential:(FIRAuthCredential *)credential
completion:(nullable FIRAuthResultCallback)completion;
/** @fn unlinkFromProvider:completion:
@brief Disassociates a user account from a third-party identity provider with this user.
@param provider The provider ID of the provider to unlink.
@param completion Optionally; the block invoked when the unlinking is complete, or fails.
Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeNoSuchProvider - Indicates an attempt to unlink a provider
that is not linked to the account.
</li>
<li>@c FIRAuthErrorCodeRequiresRecentLogin - Updating email is a security sensitive
operation that requires a recent login from the user. This error indicates the user
has not signed in recently enough. To resolve, reauthenticate the user by invoking
reauthenticateWithCredential:completion: on FIRUser.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods.
*/
- (void)unlinkFromProvider:(NSString *)provider
completion:(nullable FIRAuthResultCallback)completion;
/** @fn sendEmailVerificationWithCompletion:
@brief Initiates email verification for the user.
@param completion Optionally; the block invoked when the request to send an email verification
is complete, or fails. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidRecipientEmail - Indicates an invalid recipient email was
sent in the request.
</li>
<li>@c FIRAuthErrorCodeInvalidSender - Indicates an invalid sender email is set in
the console for this action.
</li>
<li>@c FIRAuthErrorCodeInvalidMessagePayload - Indicates an invalid email template for
sending update email.
</li>
<li>@c FIRAuthErrorCodeUserNotFound - Indicates the user account was not found.</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods.
*/
- (void)sendEmailVerificationWithCompletion:(nullable FIRSendEmailVerificationCallback)completion;
/** @fn deleteWithCompletion:
@brief Deletes the user account (also signs out the user, if this was the current user).
@param completion Optionally; the block invoked when the request to delete the account is
complete, or fails. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeRequiresRecentLogin - Updating email is a security sensitive
operation that requires a recent login from the user. This error indicates the user
has not signed in recently enough. To resolve, reauthenticate the user by invoking
reauthenticateWithCredential:completion: on FIRUser.
</li>
</ul>
@remarks See @c FIRAuthErrors for a list of error codes that are common to all FIRUser methods.
*/
- (void)deleteWithCompletion:(nullable FIRUserProfileChangeCallback)completion;
@end
/** @class FIRUserProfileChangeRequest
@brief Represents an object capable of updating a user's profile data.
@remarks Properties are marked as being part of a profile update when they are set. Setting a
property value to nil is not the same as leaving the property unassigned.
*/
@interface FIRUserProfileChangeRequest : NSObject
/** @fn init
@brief Please use @c FIRUser.profileChangeRequest
*/
- (instancetype)init NS_UNAVAILABLE;
/** @property displayName
@brief The user's display name.
@remarks It is an error to set this property after calling
@c FIRUserProfileChangeRequest.commitChangesWithCallback:
*/
@property(nonatomic, copy, nullable) NSString *displayName;
/** @property photoURL
@brief The user's photo URL.
@remarks It is an error to set this property after calling
@c FIRUserProfileChangeRequest.commitChangesWithCallback:
*/
@property(nonatomic, copy, nullable) NSURL *photoURL;
/** @fn commitChangesWithCompletion:
@brief Commits any pending changes.
@remarks This method should only be called once. Once called, property values should not be
changed.
@param completion Optionally; the block invoked when the user profile change has been applied.
Invoked asynchronously on the main thread in the future.
*/
- (void)commitChangesWithCompletion:(nullable FIRUserProfileChangeCallback)completion;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,44 @@
/** @file FIRUserInfo.h
@brief Firebase Auth SDK
@copyright Copyright 2015 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
@brief Represents user data returned from an identity provider.
*/
@protocol FIRUserInfo <NSObject>
/** @property providerID
@brief The provider identifier.
*/
@property(nonatomic, copy, readonly) NSString *providerID;
/** @property uid
@brief The provider's user ID for the user.
*/
@property(nonatomic, copy, readonly) NSString *uid;
/** @property displayName
@brief The name of the user.
*/
@property(nonatomic, copy, readonly, nullable) NSString *displayName;
/** @property photoURL
@brief The URL of the user's profile photo.
*/
@property(nonatomic, copy, readonly, nullable) NSURL *photoURL;
/** @property email
@brief The user's email address.
*/
@property(nonatomic, copy, readonly, nullable) NSString *email;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,11 @@
#import "FIREmailPasswordAuthProvider.h"
#import "FIRFacebookAuthProvider.h"
#import "FIRGitHubAuthProvider.h"
#import "FIRGoogleAuthProvider.h"
#import "FIRTwitterAuthProvider.h"
#import "FIRAuth.h"
#import "FIRAuthCredential.h"
#import "FIRAuthErrors.h"
#import "FIRUser.h"
#import "FIRUserInfo.h"
#import "FirebaseAuthVersion.h"

View File

@@ -0,0 +1,18 @@
/*! @file FirebaseAuthVersion.h
@brief Firebase SDK
@copyright Copyright 2016 Google Inc.
@remarks Use of this SDK is subject to the Google APIs Terms of Service:
https://developers.google.com/terms/
*/
#import <Foundation/Foundation.h>
/**
Version number for FirebaseAuth.
*/
extern const double FirebaseAuthVersionNumber;
/**
Version string for FirebaseAuth.
*/
extern const unsigned char *const FirebaseAuthVersionString;

View File

@@ -0,0 +1,10 @@
framework module FirebaseAuth {
umbrella header "FirebaseAuth.h"
export *
module * { export *}
link "z"
link framework "CoreGraphics"
link framework "Foundation"
link framework "Security"
link framework "UIKit"
}

8
Task Master/Pods/FirebaseAuth/README.md generated Executable file
View File

@@ -0,0 +1,8 @@
# Firebase Auth for iOS
Firebase Auth enables apps to easily support multiple authentication options
for their end users.
Please visit [our developer site](https://developers.google.com/) for
integration instructions, documentation, support information, and terms of
service.

View File

@@ -0,0 +1,38 @@
#import <Foundation/Foundation.h>
/**
* This class provides configuration fields for Firebase Analytics.
*/
@interface FIRAnalyticsConfiguration : NSObject
/**
* Returns the shared instance of FIRAnalyticsConfiguration.
*/
+ (FIRAnalyticsConfiguration *)sharedInstance;
/**
* Sets the minimum engagement time in seconds required to start a new session. The default value
* is 10 seconds.
*/
- (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval;
/**
* Sets the interval of inactivity in seconds that terminates the current session. The default
* value is 1800 seconds (30 minutes).
*/
- (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval;
/**
* Sets whether analytics collection is enabled for this app on this device. This setting is
* persisted across app sessions. By default it is enabled.
*/
- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled;
/**
* Deprecated. Sets whether measurement and reporting are enabled for this app on this device. By
* default they are enabled.
*/
- (void)setIsEnabled:(BOOL)isEnabled
DEPRECATED_MSG_ATTRIBUTE("Use setAnalyticsCollectionEnabled: instead.");
@end

View File

@@ -0,0 +1,98 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class FIROptions;
NS_ASSUME_NONNULL_BEGIN
/** A block that takes a BOOL and has no return value. */
typedef void (^FIRAppVoidBoolCallback)(BOOL success);
/**
* The entry point of Firebase SDKs.
*
* Initialize and configure FIRApp using +[FIRApp configure]
* or other customized ways as shown below.
*
* The logging system has two modes: default mode and debug mode. In default mode, only logs with
* log level Notice, Warning and Error will be sent to device. In debug mode, all logs will be sent
* to device. The log levels that Firebase uses are consistent with the ASL log levels.
*
* Enable debug mode by passing the -FIRDebugEnabled argument to the application. You can add this
* argument in the application's Xcode scheme. When debug mode is enabled via -FIRDebugEnabled,
* further executions of the application will also be in debug mode. In order to return to default
* mode, you must explicitly disable the debug mode with the application argument -FIRDebugDisabled.
*
* It is also possible to change the default logging level in code by calling setLoggerLevel: on
* the FIRConfiguration interface.
*/
@interface FIRApp : NSObject
/**
* Configures a default Firebase app. Raises an exception if any configuration step fails. The
* default app is named "__FIRAPP_DEFAULT". This method should be called after the app is launched
* and before using Firebase services. This method is thread safe.
*/
+ (void)configure;
/**
* Configures the default Firebase app with the provided options. The default app is named
* "__FIRAPP_DEFAULT". Raises an exception if any configuration step fails. This method is thread
* safe.
*
* @param options The Firebase application options used to configure the service.
*/
+ (void)configureWithOptions:(FIROptions *)options;
/**
* Configures a Firebase app with the given name and options. Raises an exception if any
* configuration step fails. This method is thread safe.
*
* @param name The application's name given by the developer. The name should should only contain
Letters, Numbers and Underscore.
* @param options The Firebase application options used to configure the services.
*/
+ (void)configureWithName:(NSString *)name options:(FIROptions *)options;
/**
* Returns the default app, or nil if the default app does not exist.
*/
+ (nullable FIRApp *)defaultApp NS_SWIFT_NAME(defaultApp());
/**
* Returns a previously created FIRApp instance with the given name, or nil if no such app exists.
* This method is thread safe.
*/
+ (nullable FIRApp *)appNamed:(NSString *)name;
/**
* Returns the set of all extant FIRApp instances, or nil if there are no FIRApp instances. This
* method is thread safe.
*/
+ (nullable NSDictionary *)allApps;
/**
* Cleans up the current FIRApp, freeing associated data and returning its name to the pool for
* future use. This method is thread safe.
*/
- (void)deleteApp:(FIRAppVoidBoolCallback)completion;
/**
* FIRApp instances should not be initialized directly. Call +[FIRApp configure],
* +[FIRApp configureWithOptions:], or +[FIRApp configureWithNames:options:] directly.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
* Gets the name of this app.
*/
@property(nonatomic, copy, readonly) NSString *name;
/**
* Gets the options for this app.
*/
@property(nonatomic, readonly) FIROptions *options;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,52 @@
#import <Foundation/Foundation.h>
#import "FIRAnalyticsConfiguration.h"
#import "FIRLoggerLevel.h"
/**
* The log levels used by FIRConfiguration.
*/
typedef NS_ENUM(NSInteger, FIRLogLevel) {
/** Error */
kFIRLogLevelError __deprecated = 0,
/** Warning */
kFIRLogLevelWarning __deprecated,
/** Info */
kFIRLogLevelInfo __deprecated,
/** Debug */
kFIRLogLevelDebug __deprecated,
/** Assert */
kFIRLogLevelAssert __deprecated,
/** Max */
kFIRLogLevelMax __deprecated = kFIRLogLevelAssert
} DEPRECATED_MSG_ATTRIBUTE(
"Use -FIRDebugEnabled and -FIRDebugDisabled or setLoggerLevel. See FIRApp.h for more details.");
/**
* This interface provides global level properties that the developer can tweak, and the singleton
* of the Firebase Analytics configuration class.
*/
@interface FIRConfiguration : NSObject
/** Returns the shared configuration object. */
+ (FIRConfiguration *)sharedInstance;
/** The configuration class for Firebase Analytics. */
@property(nonatomic, readwrite) FIRAnalyticsConfiguration *analyticsConfiguration;
/** Global log level. Defaults to kFIRLogLevelError. */
@property(nonatomic, readwrite, assign) FIRLogLevel logLevel DEPRECATED_MSG_ATTRIBUTE(
"Use -FIRDebugEnabled and -FIRDebugDisabled or setLoggerLevel. See FIRApp.h for more details.");
/**
* Sets the logging level for internal Firebase logging. Firebase will only log messages
* that are logged at or below loggerLevel. The messages are logged both to the Xcode
* console and to the device's log. Note that if an app is running from AppStore, it will
* never log above FIRLoggerLevelNotice even if loggerLevel is set to a higher (more verbose)
* setting.
*
* @param loggerLevel The maximum logging level. The default level is set to FIRLoggerLevelNotice.
*/
- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel;
@end

View File

@@ -0,0 +1,12 @@
/**
* The log levels used by internal logging.
*/
typedef NS_ENUM(NSInteger, FIRLoggerLevel) {
FIRLoggerLevelError = 3 /*ASL_LEVEL_ERR*/,
FIRLoggerLevelWarning = 4 /*ASL_LEVEL_WARNING*/,
FIRLoggerLevelNotice = 5 /*ASL_LEVEL_NOTICE*/,
FIRLoggerLevelInfo = 6 /*ASL_LEVEL_INFO*/,
FIRLoggerLevelDebug = 7 /*ASL_LEVEL_DEBUG*/,
FIRLoggerLevelMin = FIRLoggerLevelError,
FIRLoggerLevelMax = FIRLoggerLevelDebug
};

View File

@@ -0,0 +1,93 @@
#import <Foundation/Foundation.h>
/**
* This class provides constant fields of Google APIs.
*/
@interface FIROptions : NSObject<NSCopying>
/**
* Returns the default options.
*/
+ (FIROptions *)defaultOptions;
/**
* An iOS API key used for authenticating requests from your app, e.g.
* @"AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk", used to identify your app to Google servers.
*/
@property(nonatomic, readonly, copy) NSString *APIKey;
/**
* The OAuth2 client ID for iOS application used to authenticate Google users, for example
* @"12345.apps.googleusercontent.com", used for signing in with Google.
*/
@property(nonatomic, readonly, copy) NSString *clientID;
/**
* The tracking ID for Google Analytics, e.g. @"UA-12345678-1", used to configure Google Analytics.
*/
@property(nonatomic, readonly, copy) NSString *trackingID;
/**
* The Project Number from the Google Developer's console, for example @"012345678901", used to
* configure Google Cloud Messaging.
*/
@property(nonatomic, readonly, copy) NSString *GCMSenderID;
/**
* The Project ID from the Firebase console, for example @"abc-xyz-123". Currently only populated
* when using [FIROptions defaultOptions].
*/
@property(nonatomic, readonly, copy) NSString *projectID;
/**
* The Android client ID used in Google AppInvite when an iOS app has its Android version, for
* example @"12345.apps.googleusercontent.com".
*/
@property(nonatomic, readonly, copy) NSString *androidClientID;
/**
* The Google App ID that is used to uniquely identify an instance of an app.
*/
@property(nonatomic, readonly, copy) NSString *googleAppID;
/**
* The database root URL, e.g. @"http://abc-xyz-123.firebaseio.com".
*/
@property(nonatomic, readonly, copy) NSString *databaseURL;
/**
* The URL scheme used to set up Durable Deep Link service.
*/
@property(nonatomic, readwrite, copy) NSString *deepLinkURLScheme;
/**
* The Google Cloud Storage bucket name, e.g. @"abc-xyz-123.storage.firebase.com".
*/
@property(nonatomic, readonly, copy) NSString *storageBucket;
/**
* Initializes a customized instance of FIROptions with keys. googleAppID, bundleID and GCMSenderID
* are required. Other keys may required for configuring specific services.
*/
- (instancetype)initWithGoogleAppID:(NSString *)googleAppID
bundleID:(NSString *)bundleID
GCMSenderID:(NSString *)GCMSenderID
APIKey:(NSString *)APIKey
clientID:(NSString *)clientID
trackingID:(NSString *)trackingID
androidClientID:(NSString *)androidClientID
databaseURL:(NSString *)databaseURL
storageBucket:(NSString *)storageBucket
deepLinkURLScheme:(NSString *)deepLinkURLScheme;
/**
* Initializes a customized instance of FIROptions from the file at the given plist file path.
* For example,
* NSString *filePath =
* [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
* FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
* Returns nil if the plist file does not exist or is invalid.
*/
- (instancetype)initWithContentsOfFile:(NSString *)plistPath;
@end

View File

@@ -0,0 +1,5 @@
#import "FIRAnalyticsConfiguration.h"
#import "FIRApp.h"
#import "FIRConfiguration.h"
#import "FIRLoggerLevel.h"
#import "FIROptions.h"

View File

@@ -0,0 +1,7 @@
framework module FirebaseCore {
umbrella header "FirebaseCore.h"
export *
module * { export *}
link "c++"
link "z"
}

View File

@@ -0,0 +1,48 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef Firebase_FIRDataEventType_h
#define Firebase_FIRDataEventType_h
/**
* This enum is the set of events that you can observe at a Firebase Database location.
*/
typedef NS_ENUM(NSInteger, FIRDataEventType) {
/// A new child node is added to a location.
FIRDataEventTypeChildAdded,
/// A child node is removed from a location.
FIRDataEventTypeChildRemoved,
/// A child node at a location changes.
FIRDataEventTypeChildChanged,
/// A child node moves relative to the other child nodes at a location.
FIRDataEventTypeChildMoved,
/// Any data changes at a location or, recursively, at any child node.
FIRDataEventTypeValue
};
#endif

View File

@@ -0,0 +1,158 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class FIRDatabaseReference;
/**
* A FIRDataSnapshot contains data from a Firebase Database location. Any time you read
* Firebase data, you receive the data as a FIRDataSnapshot.
*
* FIRDataSnapshots are passed to the blocks you attach with observeEventType:withBlock: or observeSingleEvent:withBlock:.
* They are efficiently-generated immutable copies of the data at a Firebase Database location.
* They can't be modified and will never change. To modify data at a location,
* use a FIRDatabaseReference (e.g. with setValue:).
*/
@interface FIRDataSnapshot : NSObject
#pragma mark - Navigating and inspecting a snapshot
/**
* Gets a FIRDataSnapshot for the location at the specified relative path.
* The relative path can either be a simple child key (e.g. 'fred')
* or a deeper slash-separated path (e.g. 'fred/name/first'). If the child
* location has no data, an empty FIRDataSnapshot is returned.
*
* @param childPathString A relative path to the location of child data.
* @return The FIRDataSnapshot for the child location.
*/
- (FIRDataSnapshot *)childSnapshotForPath:(NSString *)childPathString;
/**
* Return YES if the specified child exists.
*
* @param childPathString A relative path to the location of a potential child.
* @return YES if data exists at the specified childPathString, else NO.
*/
- (BOOL) hasChild:(NSString *)childPathString;
/**
* Return YES if the DataSnapshot has any children.
*
* @return YES if this snapshot has any children, else NO.
*/
- (BOOL) hasChildren;
/**
* Return YES if the DataSnapshot contains a non-null value.
*
* @return YES if this snapshot contains a non-null value, else NO.
*/
- (BOOL) exists;
#pragma mark - Data export
/**
* Returns the raw value at this location, coupled with any metadata, such as priority.
*
* Priorities, where they exist, are accessible under the ".priority" key in instances of NSDictionary.
* For leaf locations with priorities, the value will be under the ".value" key.
*/
- (id __nullable) valueInExportFormat;
#pragma mark - Properties
/**
* Returns the contents of this data snapshot as native types.
*
* Data types returned:
* + NSDictionary
* + NSArray
* + NSNumber (also includes booleans)
* + NSString
*
* @return The data as a native object.
*/
@property (strong, readonly, nonatomic, nullable) id value;
/**
* Gets the number of children for this DataSnapshot.
*
* @return An integer indicating the number of children.
*/
@property (readonly, nonatomic) NSUInteger childrenCount;
/**
* Gets a FIRDatabaseReference for the location that this data came from.
*
* @return A FIRDatabaseReference instance for the location of this data.
*/
@property (nonatomic, readonly, strong) FIRDatabaseReference * ref;
/**
* The key of the location that generated this FIRDataSnapshot.
*
* @return An NSString containing the key for the location of this FIRDataSnapshot.
*/
@property (strong, readonly, nonatomic) NSString* key;
/**
* An iterator for snapshots of the child nodes in this snapshot.
* You can use the native for..in syntax:
*
* for (FIRDataSnapshot* child in snapshot.children) {
* ...
* }
*
* @return An NSEnumerator of the children.
*/
@property (strong, readonly, nonatomic) NSEnumerator* children;
/**
* The priority of the data in this FIRDataSnapshot.
*
* @return The priority as a string, or nil if no priority was set.
*/
@property (strong, readonly, nonatomic, nullable) id priority;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,150 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
#import "FIRDatabaseReference.h"
@class FIRApp;
NS_ASSUME_NONNULL_BEGIN
/**
* The entry point for accessing a Firebase Database. You can get an instance by calling
* [FIRDatabase database]. To access a location in the database and read or write data,
* use [FIRDatabase reference].
*/
@interface FIRDatabase : NSObject
/**
* Gets the instance of FIRDatabase for the default FIRApp.
*
* @return A FIRDatabase instance.
*/
+ (FIRDatabase *) database NS_SWIFT_NAME(database());
/**
* Gets an instance of FIRDatabase for a specific FIRApp.
*
* @param app The FIRApp to get a FIRDatabase for.
* @return A FIRDatabase instance.
*/
+ (FIRDatabase *) databaseForApp:(FIRApp*)app NS_SWIFT_NAME(database(app:));
/** The FIRApp instance to which this FIRDatabase belongs. */
@property (weak, readonly, nonatomic) FIRApp *app;
/**
* Gets a FIRDatabaseReference for the root of your Firebase Database.
*/
- (FIRDatabaseReference *) reference;
/**
* Gets a FIRDatabaseReference for the provided path.
*
* @param path Path to a location in your Firebase Database.
* @return A FIRDatabaseReference pointing to the specified path.
*/
- (FIRDatabaseReference *) referenceWithPath:(NSString *)path;
/**
* Gets a FIRDatabaseReference for the provided URL. The URL must be a URL to a path
* within this Firebase Database. To create a FIRDatabaseReference to a different database,
* create a FIRApp} with a FIROptions object configured with the appropriate database URL.
*
* @param url A URL to a path within your database.
* @return A FIRDatabaseReference for the provided URL.
*/
- (FIRDatabaseReference *) referenceFromURL:(NSString *)databaseUrl;
/**
* The Firebase Database client automatically queues writes and sends them to the server at the earliest opportunity,
* depending on network connectivity. In some cases (e.g. offline usage) there may be a large number of writes
* waiting to be sent. Calling this method will purge all outstanding writes so they are abandoned.
*
* All writes will be purged, including transactions and onDisconnect writes. The writes will
* be rolled back locally, perhaps triggering events for affected event listeners, and the client will not
* (re-)send them to the Firebase Database backend.
*/
- (void)purgeOutstandingWrites;
/**
* Shuts down our connection to the Firebase Database backend until goOnline is called.
*/
- (void)goOffline;
/**
* Resumes our connection to the Firebase Database backend after a previous goOffline call.
*/
- (void)goOnline;
/**
* The Firebase Database client will cache synchronized data and keep track of all writes you've
* initiated while your application is running. It seamlessly handles intermittent network
* connections and re-sends write operations when the network connection is restored.
*
* However by default your write operations and cached data are only stored in-memory and will
* be lost when your app restarts. By setting this value to `YES`, the data will be persisted
* to on-device (disk) storage and will thus be available again when the app is restarted
* (even when there is no network connectivity at that time). Note that this property must be
* set before creating your first Database reference and only needs to be called once per
* application.
*
*/
@property (nonatomic) BOOL persistenceEnabled;
/**
* By default the Firebase Database client will use up to 10MB of disk space to cache data. If the cache grows beyond
* this size, the client will start removing data that hasn't been recently used. If you find that your application
* caches too little or too much data, call this method to change the cache size. This property must be set before
* creating your first FIRDatabaseReference and only needs to be called once per application.
*
* Note that the specified cache size is only an approximation and the size on disk may temporarily exceed it
* at times. Cache sizes smaller than 1 MB or greater than 100 MB are not supported.
*/
@property (nonatomic) NSUInteger persistenceCacheSizeBytes;
/**
* Sets the dispatch queue on which all events are raised. The default queue is the main queue.
*
* Note that this must be set before creating your first Database reference.
*/
@property (nonatomic, strong) dispatch_queue_t callbackQueue;
/**
* Enables verbose diagnostic logging.
*
* @param enabled YES to enable logging, NO to disable.
*/
+ (void) setLoggingEnabled:(BOOL)enabled;
/** Retrieve the Firebase Database SDK version. */
+ (NSString *) sdkVersion;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,325 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
#import "FIRDataEventType.h"
#import "FIRDataSnapshot.h"
NS_ASSUME_NONNULL_BEGIN
/**
* A FIRDatabaseHandle is used to identify listeners of Firebase Database events. These handles
* are returned by observeEventType: and and can later be passed to removeObserverWithHandle: to
* stop receiving updates.
*/
typedef NSUInteger FIRDatabaseHandle;
/**
* A FIRDatabaseQuery instance represents a query over the data at a particular location.
*
* You create one by calling one of the query methods (queryOrderedByChild:, queryStartingAtValue:, etc.)
* on a FIRDatabaseReference. The query methods can be chained to further specify the data you are interested in
* observing
*/
@interface FIRDatabaseQuery : NSObject
#pragma mark - Attach observers to read data
/**
* observeEventType:withBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot.
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block;
/**
* observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot
* and the previous child's key.
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block;
/**
* observeEventType:withBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes.
*
* The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot.
* @param cancelBlock The block that should be called if this client no longer has permission to receive these events
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
/**
* observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot
* and the previous child's key.
* @param cancelBlock The block that should be called if this client no longer has permission to receive these events
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot.
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key.
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
*
* The cancelBlock will be called if you do not have permission to read data at this location.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot.
* @param cancelBlock The block that will be called if you don't have permission to access this data
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* The cancelBlock will be called if you do not have permission to read data at this location.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key.
* @param cancelBlock The block that will be called if you don't have permission to access this data
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
#pragma mark - Detaching observers
/**
* Detach a block previously attached with observeEventType:withBlock:.
*
* @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove.
*/
- (void) removeObserverWithHandle:(FIRDatabaseHandle)handle;
/**
* Detach all blocks previously attached to this Firebase Database location with observeEventType:withBlock:
*/
- (void) removeAllObservers;
/**
* By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and
* kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept
* synced, it will not be evicted from the persistent disk cache.
*
* @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization.
*/
- (void) keepSynced:(BOOL)keepSynced;
#pragma mark - Querying and limiting
/**
* queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes.
*
* @param limit The upper bound, inclusive, for the number of child nodes to receive events for
* @return A FIRDatabaseQuery instance, limited to at most limit child nodes.
*/
- (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit;
/**
* queryLimitedToLast: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes.
*
* @param limit The upper bound, inclusive, for the number of child nodes to receive events for
* @return A FIRDatabaseQuery instance, limited to at most limit child nodes.
*/
- (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit;
/**
* queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of
* a particular child key. This method is intended to be used in combination with queryStartingAtValue:,
* queryEndingAtValue:, or queryEqualToValue:.
*
* @param key The child key to use in ordering data visible to the returned FIRDatabaseQuery
* @return A FIRDatabaseQuery instance, ordered by the values of the specified child key.
*/
- (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key;
/**
* queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key.
* This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
* or queryEqualToValue:.
*
* @return A FIRDatabaseQuery instance, ordered by child keys.
*/
- (FIRDatabaseQuery *) queryOrderedByKey;
/**
* queryOrderedByValue: is used to generate a reference to a view of the data that's been sorted by child value.
* This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
* or queryEqualToValue:.
*
* @return A FIRDatabaseQuery instance, ordered by child value.
*/
- (FIRDatabaseQuery *) queryOrderedByValue;
/**
* queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child
* priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
* or queryEqualToValue:.
*
* @return A FIRDatabaseQuery instance, ordered by child priorities.
*/
- (FIRDatabaseQuery *) queryOrderedByPriority;
/**
* queryStartingAtValue: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value
* greater than or equal to startValue.
*
* @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue
*/
- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue;
/**
* queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value
* greater than startValue, or equal to startValue and with a key greater than or equal to childKey. This is most
* useful when implementing pagination in a case where multiple nodes can match the startValue.
*
* @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue
* @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue
*/
- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue childKey:(nullable NSString *)childKey;
/**
* queryEndingAtValue: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value
* less than or equal to endValue.
*
* @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue
*/
- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue;
/**
* queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value
* less than endValue, or equal to endValue and with a key less than or equal to childKey. This is most useful when
* implementing pagination in a case where multiple nodes can match the endValue.
*
* @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue
* @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue
*/
- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue childKey:(nullable NSString *)childKey;
/**
* queryEqualToValue: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal
* to the supplied argument.
*
* @param value The value that the data returned by this FIRDatabaseQuery will have
* @return A FIRDatabaseQuery instance, limited to data with the supplied value.
*/
- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value;
/**
* queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value
* equal to the supplied argument and with their key equal to childKey. There will be at most one node that matches
* because child keys are unique.
*
* @param value The value that the data returned by this FIRDatabaseQuery will have
* @param childKey The name of nodes with the right value
* @return A FIRDatabaseQuery instance, limited to data with the supplied value and the key.
*/
- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value childKey:(nullable NSString *)childKey;
#pragma mark - Properties
/**
* Gets a FIRDatabaseReference for the location of this query.
*
* @return A FIRDatabaseReference for the location of this query.
*/
@property (nonatomic, readonly, strong) FIRDatabaseReference * ref;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,730 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
#import "FIRDatabaseQuery.h"
#import "FIRDatabase.h"
#import "FIRDataSnapshot.h"
#import "FIRMutableData.h"
#import "FIRTransactionResult.h"
#import "FIRServerValue.h"
NS_ASSUME_NONNULL_BEGIN
@class FIRDatabase;
/**
* A FIRDatabaseReference represents a particular location in your Firebase Database
* and can be used for reading or writing data to that Firebase Database location.
*
* This class is the starting point for all Firebase Database operations. After you've
* obtained your first FIRDatabaseReference via [FIRDatabase reference], you can use it
* to read data (ie. observeEventType:withBlock:), write data (ie. setValue:), and to
* create new FIRDatabaseReferences (ie. child:).
*/
@interface FIRDatabaseReference : FIRDatabaseQuery
#pragma mark - Getting references to children locations
/**
* Gets a FIRDatabaseReference for the location at the specified relative path.
* The relative path can either be a simple child key (e.g. 'fred') or a
* deeper slash-separated path (e.g. 'fred/name/first').
*
* @param pathString A relative path from this location to the desired child location.
* @return A FIRDatabaseReference for the specified relative path.
*/
- (FIRDatabaseReference *)child:(NSString *)pathString;
/**
* childByAppendingPath: is deprecated, use child: instead.
*/
- (FIRDatabaseReference *)childByAppendingPath:(NSString *)pathString __deprecated_msg("use child: instead");
/**
* childByAutoId generates a new child location using a unique key and returns a
* FIRDatabaseReference to it. This is useful when the children of a Firebase Database
* location represent a list of items.
*
* The unique key generated by childByAutoId: is prefixed with a client-generated
* timestamp so that the resulting list will be chronologically-sorted.
*
* @return A FIRDatabaseReference for the generated location.
*/
- (FIRDatabaseReference *) childByAutoId;
#pragma mark - Writing data
/** Write data to this Firebase Database location.
This will overwrite any data at this location and all child locations.
Data types that can be set are:
- NSString -- @"Hello World"
- NSNumber (also includes boolean) -- @YES, @43, @4.333
- NSDictionary -- @{@"key": @"value", @"nested": @{@"another": @"value"} }
- NSArray
The effect of the write will be visible immediately and the corresponding
events will be triggered. Synchronization of the data to the Firebase Database
servers will also be started.
Passing null for the new value is equivalent to calling remove:;
all data at this location or any child location will be deleted.
Note that setValue: will remove any priority stored at this location, so if priority
is meant to be preserved, you should use setValue:andPriority: instead.
@param value The value to be written.
*/
- (void) setValue:(nullable id)value;
/**
* The same as setValue: with a block that gets triggered after the write operation has
* been committed to the Firebase Database servers.
*
* @param value The value to be written.
* @param block The block to be called after the write has been committed to the Firebase Database servers.
*/
- (void) setValue:(nullable id)value withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* The same as setValue: with an additional priority to be attached to the data being written.
* Priorities are used to order items.
*
* @param value The value to be written.
* @param priority The priority to be attached to that data.
*/
- (void) setValue:(nullable id)value andPriority:(nullable id)priority;
/**
* The same as setValue:andPriority: with a block that gets triggered after the write operation has
* been committed to the Firebase Database servers.
*
* @param value The value to be written.
* @param priority The priority to be attached to that data.
* @param block The block to be called after the write has been committed to the Firebase Database servers.
*/
- (void) setValue:(nullable id)value andPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Remove the data at this Firebase Database location. Any data at child locations will also be deleted.
*
* The effect of the delete will be visible immediately and the corresponding events
* will be triggered. Synchronization of the delete to the Firebase Database servers will
* also be started.
*
* remove: is equivalent to calling setValue:nil
*/
- (void) removeValue;
/**
* The same as remove: with a block that gets triggered after the remove operation has
* been committed to the Firebase Database servers.
*
* @param block The block to be called after the remove has been committed to the Firebase Database servers.
*/
- (void) removeValueWithCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Sets a priority for the data at this Firebase Database location.
* Priorities can be used to provide a custom ordering for the children at a location
* (if no priorities are specified, the children are ordered by key).
*
* You cannot set a priority on an empty location. For this reason
* setValue:andPriority: should be used when setting initial data with a specific priority
* and setPriority: should be used when updating the priority of existing data.
*
* Children are sorted based on this priority using the following rules:
*
* Children with no priority come first.
* Children with a number as their priority come next. They are sorted numerically by priority (small to large).
* Children with a string as their priority come last. They are sorted lexicographically by priority.
* Whenever two children have the same priority (including no priority), they are sorted by key. Numeric
* keys come first (sorted numerically), followed by the remaining keys (sorted lexicographically).
*
* Note that priorities are parsed and ordered as IEEE 754 double-precision floating-point numbers.
* Keys are always stored as strings and are treated as numbers only when they can be parsed as a
* 32-bit integer
*
* @param priority The priority to set at the specified location.
*/
- (void) setPriority:(nullable id)priority;
/**
* The same as setPriority: with a block that is called once the priority has
* been committed to the Firebase Database servers.
*
* @param priority The priority to set at the specified location.
* @param block The block that is triggered after the priority has been written on the servers.
*/
- (void) setPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Updates the values at the specified paths in the dictionary without overwriting other
* keys at this location.
*
* @param values A dictionary of the keys to change and their new values
*/
- (void) updateChildValues:(NSDictionary *)values;
/**
* The same as update: with a block that is called once the update has been committed to the
* Firebase Database servers
*
* @param values A dictionary of the keys to change and their new values
* @param block The block that is triggered after the update has been written on the Firebase Database servers
*/
- (void) updateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
#pragma mark - Attaching observers to read data
/**
* observeEventType:withBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes.
*
* Use removeObserverWithHandle: to stop receiving updates.
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot.
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block;
/**
* observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot
* and the previous child's key.
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block;
/**
* observeEventType:withBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes.
*
* The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot.
* @param cancelBlock The block that should be called if this client no longer has permission to receive these events
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
/**
* observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
* This is the primary way to read data from the Firebase Database. Your block will be triggered
* for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
*
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot
* and the previous child's key.
* @param cancelBlock The block that should be called if this client no longer has permission to receive these events
* @return A handle used to unregister this block later using removeObserverWithHandle:
*/
- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot.
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key.
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
*
* The cancelBlock will be called if you do not have permission to read data at this location.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot.
* @param cancelBlock The block that will be called if you don't have permission to access this data
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
/**
* This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and
* FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
*
* The cancelBlock will be called if you do not have permission to read data at this location.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key.
* @param cancelBlock The block that will be called if you don't have permission to access this data
*/
- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock;
#pragma mark - Detaching observers
/**
* Detach a block previously attached with observeEventType:withBlock:.
*
* @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove.
*/
- (void) removeObserverWithHandle:(FIRDatabaseHandle)handle;
/**
* By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and
* kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept
* synced, it will not be evicted from the persistent disk cache.
*
* @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization.
*/
- (void) keepSynced:(BOOL)keepSynced;
/**
* Removes all observers at the current reference, but does not remove any observers at child references.
* removeAllObservers must be called again for each child reference where a listener was established to remove the observers.
*/
- (void) removeAllObservers;
#pragma mark - Querying and limiting
/**
* queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes.
*
* @param limit The upper bound, inclusive, for the number of child nodes to receive events for
* @return A FIRDatabaseQuery instance, limited to at most limit child nodes.
*/
- (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit;
/**
* queryLimitedToLast: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes.
*
* @param limit The upper bound, inclusive, for the number of child nodes to receive events for
* @return A FIRDatabaseQuery instance, limited to at most limit child nodes.
*/
- (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit;
/**
* queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of
* a particular child key. This method is intended to be used in combination with queryStartingAtValue:,
* queryEndingAtValue:, or queryEqualToValue:.
*
* @param key The child key to use in ordering data visible to the returned FIRDatabaseQuery
* @return A FIRDatabaseQuery instance, ordered by the values of the specified child key.
*/
- (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key;
/**
* queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key.
* This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
* or queryEqualToValue:.
*
* @return A FIRDatabaseQuery instance, ordered by child keys.
*/
- (FIRDatabaseQuery *) queryOrderedByKey;
/**
* queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child
* priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
* or queryEqualToValue:.
*
* @return A FIRDatabaseQuery instance, ordered by child priorities.
*/
- (FIRDatabaseQuery *) queryOrderedByPriority;
/**
* queryStartingAtValue: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value
* greater than or equal to startValue.
*
* @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue
*/
- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue;
/**
* queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value
* greater than startValue, or equal to startValue and with a key greater than or equal to childKey.
*
* @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue
* @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue
*/
- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue childKey:(nullable NSString *)childKey;
/**
* queryEndingAtValue: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value
* less than or equal to endValue.
*
* @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue
*/
- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue;
/**
* queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value
* less than endValue, or equal to endValue and with a key less than or equal to childKey.
*
* @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery
* @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue
* @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue
*/
- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue childKey:(nullable NSString *)childKey;
/**
* queryEqualToValue: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal
* to the supplied argument.
*
* @param value The value that the data returned by this FIRDatabaseQuery will have
* @return A FIRDatabaseQuery instance, limited to data with the supplied value.
*/
- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value;
/**
* queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location.
* The FIRDatabaseQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value
* equal to the supplied argument with a key equal to childKey. There will be at most one node that matches because
* child keys are unique.
*
* @param value The value that the data returned by this FIRDatabaseQuery will have
* @param childKey The key of nodes with the right value
* @return A FIRDatabaseQuery instance, limited to data with the supplied value and the key.
*/
- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value childKey:(nullable NSString *)childKey;
#pragma mark - Managing presence
/**
* Ensure the data at this location is set to the specified value when
* the client is disconnected (due to closing the browser, navigating
* to a new page, or network issues).
*
* onDisconnectSetValue: is especially useful for implementing "presence" systems,
* where a value should be changed or cleared when a user disconnects
* so that he appears "offline" to other users.
*
* @param value The value to be set after the connection is lost.
*/
- (void) onDisconnectSetValue:(nullable id)value;
/**
* Ensure the data at this location is set to the specified value when
* the client is disconnected (due to closing the browser, navigating
* to a new page, or network issues).
*
* The completion block will be triggered when the operation has been successfully queued up on the Firebase Database servers
*
* @param value The value to be set after the connection is lost.
* @param block Block to be triggered when the operation has been queued up on the Firebase Database servers
*/
- (void) onDisconnectSetValue:(nullable id)value withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Ensure the data at this location is set to the specified value and priority when
* the client is disconnected (due to closing the browser, navigating
* to a new page, or network issues).
*
* @param value The value to be set after the connection is lost.
* @param priority The priority to be set after the connection is lost.
*/
- (void) onDisconnectSetValue:(nullable id)value andPriority:(id)priority;
/**
* Ensure the data at this location is set to the specified value and priority when
* the client is disconnected (due to closing the browser, navigating
* to a new page, or network issues).
*
* The completion block will be triggered when the operation has been successfully queued up on the Firebase Database servers
*
* @param value The value to be set after the connection is lost.
* @param priority The priority to be set after the connection is lost.
* @param block Block to be triggered when the operation has been queued up on the Firebase Database servers
*/
- (void) onDisconnectSetValue:(nullable id)value andPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Ensure the data at this location is removed when
* the client is disconnected (due to closing the app, navigating
* to a new page, or network issues).
*
* onDisconnectRemoveValue is especially useful for implementing "presence" systems.
*/
- (void) onDisconnectRemoveValue;
/**
* Ensure the data at this location is removed when
* the client is disconnected (due to closing the app, navigating
* to a new page, or network issues).
*
* onDisconnectRemoveValueWithCompletionBlock: is especially useful for implementing "presence" systems.
*
* @param block Block to be triggered when the operation has been queued up on the Firebase Database servers
*/
- (void) onDisconnectRemoveValueWithCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Ensure the data has the specified child values updated when
* the client is disconnected (due to closing the browser, navigating
* to a new page, or network issues).
*
*
* @param values A dictionary of child node keys and the values to set them to after the connection is lost.
*/
- (void) onDisconnectUpdateChildValues:(NSDictionary *)values;
/**
* Ensure the data has the specified child values updated when
* the client is disconnected (due to closing the browser, navigating
* to a new page, or network issues).
*
*
* @param values A dictionary of child node keys and the values to set them to after the connection is lost.
* @param block A block that will be called once the operation has been queued up on the Firebase Database servers
*/
- (void) onDisconnectUpdateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
/**
* Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:,
* onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the
* connection is lost, call cancelDisconnectOperations:
*/
- (void) cancelDisconnectOperations;
/**
* Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:,
* onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the
* connection is lost, call cancelDisconnectOperations:
*
* @param block A block that will be triggered once the Firebase Database servers have acknowledged the cancel request.
*/
- (void) cancelDisconnectOperationsWithCompletionBlock:(nullable void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block;
#pragma mark - Manual Connection Management
/**
* Manually disconnect the Firebase Database client from the server and disable automatic reconnection.
*
* The Firebase Database client automatically maintains a persistent connection to the Firebase Database server,
* which will remain active indefinitely and reconnect when disconnected. However, the goOffline( )
* and goOnline( ) methods may be used to manually control the client connection in cases where
* a persistent connection is undesirable.
*
* While offline, the Firebase Database client will no longer receive data updates from the server. However,
* all database operations performed locally will continue to immediately fire events, allowing
* your application to continue behaving normally. Additionally, each operation performed locally
* will automatically be queued and retried upon reconnection to the Firebase Database server.
*
* To reconnect to the Firebase Database server and begin receiving remote events, see goOnline( ).
* Once the connection is reestablished, the Firebase Database client will transmit the appropriate data
* and fire the appropriate events so that your client "catches up" automatically.
*
* Note: Invoking this method will impact all Firebase Database connections.
*/
+ (void) goOffline;
/**
* Manually reestablish a connection to the Firebase Database server and enable automatic reconnection.
*
* The Firebase Database client automatically maintains a persistent connection to the Firebase Database server,
* which will remain active indefinitely and reconnect when disconnected. However, the goOffline( )
* and goOnline( ) methods may be used to manually control the client connection in cases where
* a persistent connection is undesirable.
*
* This method should be used after invoking goOffline( ) to disable the active connection.
* Once reconnected, the Firebase Database client will automatically transmit the proper data and fire
* the appropriate events so that your client "catches up" automatically.
*
* To disconnect from the Firebase Database server, see goOffline( ).
*
* Note: Invoking this method will impact all Firebase Database connections.
*/
+ (void) goOnline;
#pragma mark - Transactions
/**
* Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData
* instance that contains the current data at this location. Your block should update this data to the value you
* wish to write to this location, and then return an instance of FIRTransactionResult with the new data.
*
* If, when the operation reaches the server, it turns out that this client had stale data, your block will be run
* again with the latest data from the server.
*
* When your block is run, you may decide to abort the transaction by returning [FIRTransactionResult abort].
*
* @param block This block receives the current data at this location and must return an instance of FIRTransactionResult
*/
- (void) runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block;
/**
* Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData
* instance that contains the current data at this location. Your block should update this data to the value you
* wish to write to this location, and then return an instance of FIRTransactionResult with the new data.
*
* If, when the operation reaches the server, it turns out that this client had stale data, your block will be run
* again with the latest data from the server.
*
* When your block is run, you may decide to abort the transaction by returning [FIRTransactionResult abort].
*
* @param block This block receives the current data at this location and must return an instance of FIRTransactionResult
* @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is.
*/
- (void)runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block andCompletionBlock:(void (^) (NSError *__nullable error, BOOL committed, FIRDataSnapshot *__nullable snapshot))completionBlock;
/**
* Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData
* instance that contains the current data at this location. Your block should update this data to the value you
* wish to write to this location, and then return an instance of FIRTransactionResult with the new data.
*
* If, when the operation reaches the server, it turns out that this client had stale data, your block will be run
* again with the latest data from the server.
*
* When your block is run, you may decide to abort the transaction by return [FIRTransactionResult abort].
*
* Since your block may be run multiple times, this client could see several immediate states that don't exist on the server. You can suppress those immediate states until the server confirms the final state of the transaction.
*
* @param block This block receives the current data at this location and must return an instance of FIRTransactionResult
* @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is.
* @param localEvents Set this to NO to suppress events raised for intermediate states, and only get events based on the final state of the transaction.
*/
- (void)runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block andCompletionBlock:(nullable void (^) (NSError *__nullable error, BOOL committed, FIRDataSnapshot *__nullable snapshot))completionBlock withLocalEvents:(BOOL)localEvents;
#pragma mark - Retrieving String Representation
/**
* Gets the absolute URL of this Firebase Database location.
*
* @return The absolute URL of the referenced Firebase Database location.
*/
- (NSString *) description;
#pragma mark - Properties
/**
* Gets a FIRDatabaseReference for the parent location.
* If this instance refers to the root of your Firebase Database, it has no parent,
* and therefore parent( ) will return null.
*
* @return A FIRDatabaseReference for the parent location.
*/
@property (strong, readonly, nonatomic, nullable) FIRDatabaseReference * parent;
/**
* Gets a FIRDatabaseReference for the root location
*
* @return A new FIRDatabaseReference to root location.
*/
@property (strong, readonly, nonatomic) FIRDatabaseReference * root;
/**
* Gets the last token in a Firebase Database location (e.g. 'fred' in https&#58;//SampleChat.firebaseIO-demo.com/users/fred)
*
* @return The key of the location this reference points to.
*/
@property (strong, readonly, nonatomic) NSString* key;
/**
* Gets the URL for the Firebase Database location referenced by this FIRDatabaseReference.
*
* @return The url of the location this reference points to.
*/
@property (strong, readonly, nonatomic) NSString* URL;
/**
* Gets the FIRDatabase instance associated with this reference.
*
* @return The FIRDatabase object for this reference.
*/
@property (strong, readonly, nonatomic) FIRDatabase *database;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,140 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* A FIRMutableData instance is populated with data from a Firebase Database location.
* When you are using runTransactionBlock:, you will be given an instance containing the current
* data at that location. Your block will be responsible for updating that instance to the data
* you wish to save at that location, and then returning using [FIRTransactionResult successWithValue:].
*
* To modify the data, set its value property to any of the native types support by Firebase Database:
*
* + NSNumber (includes BOOL)
* + NSDictionary
* + NSArray
* + NSString
* + nil / NSNull to remove the data
*
* Note that changes made to a child FIRMutableData instance will be visible to the parent.
*/
@interface FIRMutableData : NSObject
#pragma mark - Inspecting and navigating the data
/**
* Returns boolean indicating whether this mutable data has children.
*
* @return YES if this data contains child nodes.
*/
- (BOOL) hasChildren;
/**
* Indicates whether this mutable data has a child at the given path.
*
* @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child'
* @return YES if this data contains a child at the specified relative path
*/
- (BOOL) hasChildAtPath:(NSString *)path;
/**
* Used to obtain a FIRMutableData instance that encapsulates the data at the given relative path.
* Note that changes made to the child will be visible to the parent.
*
* @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child'
* @return A FIRMutableData instance containing the data at the given path
*/
- (FIRMutableData *)childDataByAppendingPath:(NSString *)path;
#pragma mark - Properties
/**
* To modify the data contained by this instance of FIRMutableData, set this to any of the native types supported by Firebase Database:
*
* + NSNumber (includes BOOL)
* + NSDictionary
* + NSArray
* + NSString
* + nil / NSNull to remove the data
*
* Note that setting this value will override the priority at this location.
*
* @return The current data at this location as a native object
*/
@property (strong, nonatomic, nullable) id value;
/**
* Set this property to update the priority of the data at this location. Can be set to the following types:
*
* + NSNumber
* + NSString
* + nil / NSNull to remove the priority
*
* @return The priority of the data at this location
*/
@property (strong, nonatomic, nullable) id priority;
/**
* @return The number of child nodes at this location
*/
@property (readonly, nonatomic) NSUInteger childrenCount;
/**
* Used to iterate over the children at this location. You can use the native for .. in syntax:
*
* for (FIRMutableData* child in data.children) {
* ...
* }
*
* Note that this enumerator operates on an immutable copy of the child list. So, you can modify the instance
* during iteration, but the new additions will not be visible until you get a new enumerator.
*/
@property (readonly, nonatomic, strong) NSEnumerator* children;
/**
* @return The key name of this node, or nil if it is the top-most location
*/
@property (readonly, nonatomic, strong, nullable) NSString* key;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,44 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
NS_ASSUME_NONNULL_BEGIN
/**
* Placeholder values you may write into Firebase Database as a value or priority
* that will automatically be populated by the Firebase Database server.
*/
@interface FIRServerValue : NSObject
/**
* Placeholder value for the number of milliseconds since the Unix epoch
*/
+ (NSDictionary *) timestamp;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,57 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2013 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
#import "FIRMutableData.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Used for runTransactionBlock:. An FIRTransactionResult instance is a container for the results of the transaction.
*/
@interface FIRTransactionResult : NSObject
/**
* Used for runTransactionBlock:. Indicates that the new value should be saved at this location
*
* @param value A FIRMutableData instance containing the new value to be set
* @return An FIRTransactionResult instance that can be used as a return value from the block given to runTransactionBlock:
*/
+ (FIRTransactionResult *)successWithValue:(FIRMutableData *)value;
/**
* Used for runTransactionBlock:. Indicates that the current transaction should no longer proceed.
*
* @return An FIRTransactionResult instance that can be used as a return value from the block given to runTransactionBlock:
*/
+ (FIRTransactionResult *) abort;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,41 @@
/*
* Firebase iOS Client Library
*
* Copyright © 2016 Firebase - All Rights Reserved
* https://www.firebase.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binaryform must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FirebaseDatabase_h
#define FirebaseDatabase_h
#import "FIRDatabase.h"
#import "FIRDatabaseQuery.h"
#import "FIRDatabaseReference.h"
#import "FIRDataEventType.h"
#import "FIRDataSnapshot.h"
#import "FIRMutableData.h"
#import "FIRServerValue.h"
#import "FIRTransactionResult.h"
#endif /* FirebaseDatabase_h */

View File

@@ -0,0 +1,13 @@
framework module FirebaseDatabase {
umbrella header "FirebaseDatabase.h"
export *
module * { export * }
link framework "CFNetwork"
link framework "Security"
link framework "SystemConfiguration"
link "c++"
link "icucore"
}

View File

@@ -0,0 +1,47 @@
Google LevelDB
Copyright (c) 2011 The LevelDB Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
Square Socket Rocket
Copyright 2012 Square Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
--
APLevelDB
Created by Adam Preble on 1/23/12.
Copyright (c) 2012 Adam Preble. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission 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.

View File

@@ -0,0 +1,40 @@
# 2017-03-31 -- v1.0.10
- Improvements to token-fetching logic
- Fixed some warnings in Instance ID
- Improved error messages if Instance ID couldn't be initialized properly
- Improvements to console logging
# 2017-01-31 -- v1.0.9
- Removed an error being mistakenly logged to the console.
# 2016-07-06 -- v1.0.8
- Don't store InstanceID plists in Documents folder.
# 2016-06-19 -- v1.0.7
- Fix remote-notifications warning on app submission.
# 2016-05-16 -- v1.0.6
- Fix CocoaPod linter issues for InstanceID pod.
# 2016-05-13 -- v1.0.5
- Fix Authorization errors for InstanceID tokens.
# 2016-05-11 -- v1.0.4
- Reduce wait for InstanceID token during parallel requests.
# 2016-04-18 -- v1.0.3
- Change flag to disable swizzling to *FirebaseAppDelegateProxyEnabled*.
- Fix incessant Keychain errors while accessing InstanceID.
- Fix max retries for fetching IID token.
# 2016-04-18 -- v1.0.2
- Register for remote notifications on iOS8+ in the SDK itself.

View File

@@ -0,0 +1,245 @@
#import <Foundation/Foundation.h>
/**
* @memberof FIRInstanceID
*
* The scope to be used when fetching/deleting a token for Firebase Messaging.
*/
FOUNDATION_EXPORT NSString * __nonnull const kFIRInstanceIDScopeFirebaseMessaging;
/**
* Called when the system determines that tokens need to be refreshed.
* This method is also called if Instance ID has been reset in which
* case, tokens and FCM topic subscriptions also need to be refreshed.
*
* Instance ID service will throttle the refresh event across all devices
* to control the rate of token updates on application servers.
*/
FOUNDATION_EXPORT NSString * __nonnull const kFIRInstanceIDTokenRefreshNotification;
/**
* @related FIRInstanceID
*
* The completion handler invoked when the InstanceID token returns. If
* the call fails we return the appropriate `error code` as described below.
*
* @param token The valid token as returned by InstanceID backend.
*
* @param error The error describing why generating a new token
* failed. See the error codes below for a more detailed
* description.
*/
typedef void(^FIRInstanceIDTokenHandler)( NSString * __nullable token, NSError * __nullable error);
/**
* @related FIRInstanceID
*
* The completion handler invoked when the InstanceID `deleteToken` returns. If
* the call fails we return the appropriate `error code` as described below
*
* @param error The error describing why deleting the token failed.
* See the error codes below for a more detailed description.
*/
typedef void(^FIRInstanceIDDeleteTokenHandler)(NSError * __nullable error);
/**
* @related FIRInstanceID
*
* The completion handler invoked when the app identity is created. If the
* identity wasn't created for some reason we return the appropriate error code.
*
* @param identity A valid identity for the app instance, nil if there was an error
* while creating an identity.
* @param error The error if fetching the identity fails else nil.
*/
typedef void(^FIRInstanceIDHandler)(NSString * __nullable identity, NSError * __nullable error);
/**
* @related FIRInstanceID
*
* The completion handler invoked when the app identity and all the tokens associated
* with it are deleted. Returns a valid error object in case of failure else nil.
*
* @param error The error if deleting the identity and all the tokens associated with
* it fails else nil.
*/
typedef void(^FIRInstanceIDDeleteHandler)(NSError * __nullable error);
/**
* @enum FIRInstanceIDError
*/
typedef NS_ENUM(NSUInteger, FIRInstanceIDError) {
// Http related errors.
/// Unknown error.
FIRInstanceIDErrorUnknown = 0,
/// Auth Error -- GCM couldn't validate request from this client.
FIRInstanceIDErrorAuthentication = 1,
/// NoAccess -- InstanceID service cannot be accessed.
FIRInstanceIDErrorNoAccess = 2,
/// Timeout -- Request to InstanceID backend timed out.
FIRInstanceIDErrorTimeout = 3,
/// Network -- No network available to reach the servers.
FIRInstanceIDErrorNetwork = 4,
/// OperationInProgress -- Another similar operation in progress,
/// bailing this one.
FIRInstanceIDErrorOperationInProgress = 5,
/// InvalidRequest -- Some parameters of the request were invalid.
FIRInstanceIDErrorInvalidRequest = 7,
};
/**
* The APNS token type for the app. If the token type is set to `UNKNOWN`
* InstanceID will implicitly try to figure out what the actual token type
* is from the provisioning profile.
*/
typedef NS_ENUM(NSInteger, FIRInstanceIDAPNSTokenType) {
/// Unknown token type.
FIRInstanceIDAPNSTokenTypeUnknown,
/// Sandbox token type.
FIRInstanceIDAPNSTokenTypeSandbox,
/// Production token type.
FIRInstanceIDAPNSTokenTypeProd,
};
/**
* Instance ID provides a unique identifier for each app instance and a mechanism
* to authenticate and authorize actions (for example, sending an FCM message).
*
* Instance ID is long lived but, may be reset if the device is not used for
* a long time or the Instance ID service detects a problem.
* If Instance ID is reset, the app will be notified via
* `kFIRInstanceIDTokenRefreshNotification`.
*
* If the Instance ID has become invalid, the app can request a new one and
* send it to the app server.
* To prove ownership of Instance ID and to allow servers to access data or
* services associated with the app, call
* `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`.
*/
@interface FIRInstanceID : NSObject
/**
* FIRInstanceID.
*
* @return A shared instance of FIRInstanceID.
*/
+ (nonnull instancetype)instanceID NS_SWIFT_NAME(instanceID());
/**
* Unavailable. Use +instanceID instead.
*/
- (nonnull instancetype)init __attribute__((unavailable("Use +instanceID instead.")));
/**
* Set APNS token for the application. This APNS token will be used to register
* with Firebase Messaging using `token` or
* `tokenWithAuthorizedEntity:scope:options:handler`. If the token type is set to
* `FIRInstanceIDAPNSTokenTypeUnknown` InstanceID will read the provisioning profile
* to find out the token type.
*
* @param token The APNS token for the application.
* @param type The APNS token type for the above token.
*/
- (void)setAPNSToken:(nonnull NSData *)token
type:(FIRInstanceIDAPNSTokenType)type;
#pragma mark - Tokens
/**
* Returns a Firebase Messaging scoped token for the firebase app.
*
* @return Null Returns null if the device has not yet been registerd with
* Firebase Message else returns a valid token.
*/
- (nullable NSString *)token;
/**
* Returns a token that authorizes an Entity (example: cloud service) to perform
* an action on behalf of the application identified by Instance ID.
*
* This is similar to an OAuth2 token except, it applies to the
* application instance instead of a user.
*
* This is an asynchronous call. If the token fetching fails for some reason
* we invoke the completion callback with nil `token` and the appropriate
* error.
*
* Note, you can only have one `token` or `deleteToken` call for a given
* authorizedEntity and scope at any point of time. Making another such call with the
* same authorizedEntity and scope before the last one finishes will result in an
* error with code `OperationInProgress`.
*
* @see FIRInstanceID deleteTokenWithAuthorizedEntity:scope:handler:
*
* @param authorizedEntity Entity authorized by the token.
* @param scope Action authorized for authorizedEntity.
* @param options The extra options to be sent with your token request. The
* value for the `apns_token` should be the NSData object
* passed to UIApplication's
* `didRegisterForRemoteNotificationsWithDeviceToken` method.
* All other keys and values in the options dict need to be
* instances of NSString or else they will be discarded. Bundle
* keys starting with 'GCM.' and 'GOOGLE.' are reserved.
* @param handler The callback handler which is invoked when the token is
* successfully fetched. In case of success a valid `token` and
* `nil` error are returned. In case of any error the `token`
* is nil and a valid `error` is returned. The valid error
* codes have been documented above.
*/
- (void)tokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity
scope:(nonnull NSString *)scope
options:(nullable NSDictionary *)options
handler:(nonnull FIRInstanceIDTokenHandler)handler;
/**
* Revokes access to a scope (action) for an entity previously
* authorized by `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`.
*
* This is an asynchronous call. Call this on the main thread since InstanceID lib
* is not thread safe. In case token deletion fails for some reason we invoke the
* `handler` callback passed in with the appropriate error code.
*
* Note, you can only have one `token` or `deleteToken` call for a given
* authorizedEntity and scope at a point of time. Making another such call with the
* same authorizedEntity and scope before the last one finishes will result in an error
* with code `OperationInProgress`.
*
* @param authorizedEntity Entity that must no longer have access.
* @param scope Action that entity is no longer authorized to perform.
* @param handler The handler that is invoked once the unsubscribe call ends.
* In case of error an appropriate error object is returned
* else error is nil.
*/
- (void)deleteTokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity
scope:(nonnull NSString *)scope
handler:(nonnull FIRInstanceIDDeleteTokenHandler)handler;
#pragma mark - Identity
/**
* Asynchronously fetch a stable identifier that uniquely identifies the app
* instance. If the identifier has been revoked or has expired, this method will
* return a new identifier.
*
*
* @param handler The handler to invoke once the identifier has been fetched.
* In case of error an appropriate error object is returned else
* a valid identifier is returned and a valid identifier for the
* application instance.
*/
- (void)getIDWithHandler:(nonnull FIRInstanceIDHandler)handler;
/**
* Resets Instance ID and revokes all tokens.
*/
- (void)deleteIDWithHandler:(nonnull FIRInstanceIDDeleteHandler)handler;
@end

View File

@@ -0,0 +1 @@
#import "FIRInstanceID.h"

View File

@@ -0,0 +1,7 @@
framework module FirebaseInstanceID {
umbrella header "FirebaseInstanceID.h"
export *
module * { export *}
link "c++"
link "z"
}

10
Task Master/Pods/FirebaseInstanceID/README.md generated Executable file
View File

@@ -0,0 +1,10 @@
# InstanceID SDK for iOS
Instance ID provides a unique ID per instance of your apps and also provides a
mechanism to authenticate and authorize actions, like sending messages via
Firebase Cloud Messaging (FCM).
Please visit [our developer
site](https://developers.google.com/instance-id/) for integration instructions,
documentation, support information, and terms of service.

202
Task Master/Pods/GTMSessionFetcher/LICENSE generated Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,23 @@
# Google Toolbox for Mac - Session Fetcher #
**Project site** <https://github.com/google/gtm-session-fetcher><br>
**Discussion group** <http://groups.google.com/group/google-toolbox-for-mac>
[![Build Status](https://travis-ci.org/google/gtm-session-fetcher.svg?branch=master)](https://travis-ci.org/google/gtm-session-fetcher)
`GTMSessionFetcher` makes it easy for Cocoa applications to perform http
operations. The fetcher is implemented as a wrapper on `NSURLSession`, so its
behavior is asynchronous and uses operating-system settings on iOS and Mac OS X.
Features include:
- Simple to build; only one source/header file pair is required
- Simple to use: takes just two lines of code to fetch a request
- Supports upload and download sessions
- Flexible cookie storage
- Automatic retry on errors, with exponential backoff
- Support for generating multipart MIME upload streams
- Easy, convenient logging of http requests and responses
- Supports plug-in authentication such as with GTMAppAuth
- Easily testable; self-mocking
- Automatic rate limiting when created by the `GTMSessionFetcherService` factory class
- Fully independent of other projects

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
/* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "GTMSessionFetcher.h"
// GTM HTTP Logging
//
// All traffic using GTMSessionFetcher can be easily logged. Call
//
// [GTMSessionFetcher setLoggingEnabled:YES];
//
// to begin generating log files.
//
// Log files are put into a folder on the desktop called "GTMHTTPDebugLogs"
// unless another directory is specified with +setLoggingDirectory.
//
// In the iPhone simulator, the default logs location is the user's home
// directory in ~/Library/Application Support. On the iPhone device, the
// default logs location is the application's documents directory on the device.
//
// Tip: use the Finder's "Sort By Date" to find the most recent logs.
//
// Each run of an application gets a separate set of log files. An html
// file is generated to simplify browsing the run's http transactions.
// The html file includes javascript links for inline viewing of uploaded
// and downloaded data.
//
// A symlink is created in the logs folder to simplify finding the html file
// for the latest run of the application; the symlink is called
//
// AppName_http_log_newest.html
//
// For better viewing of XML logs, use Camino or Firefox rather than Safari.
//
// Each fetcher may be given a comment to be inserted as a label in the logs,
// such as
// [fetcher setCommentWithFormat:@"retrieve item %@", itemName];
//
// Projects may define STRIP_GTM_FETCH_LOGGING to remove logging code.
#if !STRIP_GTM_FETCH_LOGGING
@interface GTMSessionFetcher (GTMSessionFetcherLogging)
// Note: the default logs directory is ~/Desktop/GTMHTTPDebugLogs; it will be
// created as needed. If a custom directory is set, the directory should
// already exist.
+ (void)setLoggingDirectory:(NSString *)path;
+ (NSString *)loggingDirectory;
// client apps can turn logging on and off
+ (void)setLoggingEnabled:(BOOL)isLoggingEnabled;
+ (BOOL)isLoggingEnabled;
// client apps can turn off logging to a file if they want to only check
// the fetcher's log property
+ (void)setLoggingToFileEnabled:(BOOL)isLoggingToFileEnabled;
+ (BOOL)isLoggingToFileEnabled;
// client apps can optionally specify process name and date string used in
// log file names
+ (void)setLoggingProcessName:(NSString *)processName;
+ (NSString *)loggingProcessName;
+ (void)setLoggingDateStamp:(NSString *)dateStamp;
+ (NSString *)loggingDateStamp;
// client apps can specify the directory for the log for this specific run,
// typically to match the directory used by another fetcher class, like:
//
// [GTMSessionFetcher setLogDirectoryForCurrentRun:[GTMHTTPFetcher logDirectoryForCurrentRun]];
//
// Setting this overrides the logging directory, process name, and date stamp when writing
// the log file.
+ (void)setLogDirectoryForCurrentRun:(NSString *)logDirectoryForCurrentRun;
+ (NSString *)logDirectoryForCurrentRun;
// Prunes old log directories that have not been modified since the provided date.
// This will not delete the current run's log directory.
+ (void)deleteLogDirectoriesOlderThanDate:(NSDate *)date;
// internal; called by fetcher
- (void)logFetchWithError:(NSError *)error;
- (NSInputStream *)loggedInputStreamForInputStream:(NSInputStream *)inputStream;
- (GTMSessionFetcherBodyStreamProvider)loggedStreamProviderForStreamProvider:
(GTMSessionFetcherBodyStreamProvider)streamProvider;
// internal; accessors useful for viewing logs
+ (NSString *)processNameLogPrefix;
+ (NSString *)symlinkNameSuffix;
+ (NSString *)htmlFileName;
@end
#endif // !STRIP_GTM_FETCH_LOGGING

View File

@@ -0,0 +1,976 @@
/* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#include <sys/stat.h>
#include <unistd.h>
#import "GTMSessionFetcherLogging.h"
#ifndef STRIP_GTM_FETCH_LOGGING
#error GTMSessionFetcher headers should have defaulted this if it wasn't already defined.
#endif
#if !STRIP_GTM_FETCH_LOGGING
// Sensitive credential strings are replaced in logs with _snip_
//
// Apps that must see the contents of sensitive tokens can set this to 1
#ifndef SKIP_GTM_FETCH_LOGGING_SNIPPING
#define SKIP_GTM_FETCH_LOGGING_SNIPPING 0
#endif
// If GTMReadMonitorInputStream is available, it can be used for
// capturing uploaded streams of data
//
// We locally declare methods of GTMReadMonitorInputStream so we
// do not need to import the header, as some projects may not have it available
#if !GTMSESSION_BUILD_COMBINED_SOURCES
@interface GTMReadMonitorInputStream : NSInputStream
+ (instancetype)inputStreamWithStream:(NSInputStream *)input;
@property (assign) id readDelegate;
@property (assign) SEL readSelector;
@end
#else
@class GTMReadMonitorInputStream;
#endif // !GTMSESSION_BUILD_COMBINED_SOURCES
@interface GTMSessionFetcher (GTMHTTPFetcherLoggingUtilities)
+ (NSString *)headersStringForDictionary:(NSDictionary *)dict;
+ (NSString *)snipSubstringOfString:(NSString *)originalStr
betweenStartString:(NSString *)startStr
endString:(NSString *)endStr;
- (void)inputStream:(GTMReadMonitorInputStream *)stream
readIntoBuffer:(void *)buffer
length:(int64_t)length;
@end
@implementation GTMSessionFetcher (GTMSessionFetcherLogging)
// fetchers come and fetchers go, but statics are forever
static BOOL gIsLoggingEnabled = NO;
static BOOL gIsLoggingToFile = YES;
static NSString *gLoggingDirectoryPath = nil;
static NSString *gLogDirectoryForCurrentRun = nil;
static NSString *gLoggingDateStamp = nil;
static NSString *gLoggingProcessName = nil;
+ (void)setLoggingDirectory:(NSString *)path {
gLoggingDirectoryPath = [path copy];
}
+ (NSString *)loggingDirectory {
if (!gLoggingDirectoryPath) {
NSArray *paths = nil;
#if TARGET_IPHONE_SIMULATOR
// default to a directory called GTMHTTPDebugLogs into a sandbox-safe
// directory that a developer can find easily, the application home
paths = @[ NSHomeDirectory() ];
#elif TARGET_OS_IPHONE
// Neither ~/Desktop nor ~/Home is writable on an actual iOS, watchOS, or tvOS device.
// Put it in ~/Documents.
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
#else
// default to a directory called GTMHTTPDebugLogs in the desktop folder
paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
#endif
NSString *desktopPath = paths.firstObject;
if (desktopPath) {
NSString *const kGTMLogFolderName = @"GTMHTTPDebugLogs";
NSString *logsFolderPath = [desktopPath stringByAppendingPathComponent:kGTMLogFolderName];
NSFileManager *fileMgr = [NSFileManager defaultManager];
BOOL isDir;
BOOL doesFolderExist = [fileMgr fileExistsAtPath:logsFolderPath isDirectory:&isDir];
if (!doesFolderExist) {
// make the directory
doesFolderExist = [fileMgr createDirectoryAtPath:logsFolderPath
withIntermediateDirectories:YES
attributes:nil
error:NULL];
}
if (doesFolderExist) {
// it's there; store it in the global
gLoggingDirectoryPath = [logsFolderPath copy];
}
}
}
return gLoggingDirectoryPath;
}
+ (void)setLogDirectoryForCurrentRun:(NSString *)logDirectoryForCurrentRun {
// Set the path for this run's logs.
gLogDirectoryForCurrentRun = [logDirectoryForCurrentRun copy];
}
+ (NSString *)logDirectoryForCurrentRun {
// make a directory for this run's logs, like SyncProto_logs_10-16_01-56-58PM
if (gLogDirectoryForCurrentRun) return gLogDirectoryForCurrentRun;
NSString *parentDir = [self loggingDirectory];
NSString *logNamePrefix = [self processNameLogPrefix];
NSString *dateStamp = [self loggingDateStamp];
NSString *dirName = [NSString stringWithFormat:@"%@%@", logNamePrefix, dateStamp];
NSString *logDirectory = [parentDir stringByAppendingPathComponent:dirName];
if (gIsLoggingToFile) {
NSFileManager *fileMgr = [NSFileManager defaultManager];
// Be sure that the first time this app runs, it's not writing to a preexisting folder
static BOOL gShouldReuseFolder = NO;
if (!gShouldReuseFolder) {
gShouldReuseFolder = YES;
NSString *origLogDir = logDirectory;
for (int ctr = 2; ctr < 20; ++ctr) {
if (![fileMgr fileExistsAtPath:logDirectory]) break;
// append a digit
logDirectory = [origLogDir stringByAppendingFormat:@"_%d", ctr];
}
}
if (![fileMgr createDirectoryAtPath:logDirectory
withIntermediateDirectories:YES
attributes:nil
error:NULL]) return nil;
}
gLogDirectoryForCurrentRun = logDirectory;
return gLogDirectoryForCurrentRun;
}
+ (void)setLoggingEnabled:(BOOL)isLoggingEnabled {
gIsLoggingEnabled = isLoggingEnabled;
}
+ (BOOL)isLoggingEnabled {
return gIsLoggingEnabled;
}
+ (void)setLoggingToFileEnabled:(BOOL)isLoggingToFileEnabled {
gIsLoggingToFile = isLoggingToFileEnabled;
}
+ (BOOL)isLoggingToFileEnabled {
return gIsLoggingToFile;
}
+ (void)setLoggingProcessName:(NSString *)processName {
gLoggingProcessName = [processName copy];
}
+ (NSString *)loggingProcessName {
// get the process name (once per run) replacing spaces with underscores
if (!gLoggingProcessName) {
NSString *procName = [[NSProcessInfo processInfo] processName];
gLoggingProcessName = [procName stringByReplacingOccurrencesOfString:@" " withString:@"_"];
}
return gLoggingProcessName;
}
+ (void)setLoggingDateStamp:(NSString *)dateStamp {
gLoggingDateStamp = [dateStamp copy];
}
+ (NSString *)loggingDateStamp {
// We'll pick one date stamp per run, so a run that starts at a later second
// will get a unique results html file
if (!gLoggingDateStamp) {
// produce a string like 08-21_01-41-23PM
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[formatter setDateFormat:@"M-dd_hh-mm-ssa"];
gLoggingDateStamp = [formatter stringFromDate:[NSDate date]];
}
return gLoggingDateStamp;
}
+ (NSString *)processNameLogPrefix {
static NSString *gPrefix = nil;
if (!gPrefix) {
NSString *processName = [self loggingProcessName];
gPrefix = [[NSString alloc] initWithFormat:@"%@_log_", processName];
}
return gPrefix;
}
+ (NSString *)symlinkNameSuffix {
return @"_log_newest.html";
}
+ (NSString *)htmlFileName {
return @"aperçu_http_log.html";
}
+ (void)deleteLogDirectoriesOlderThanDate:(NSDate *)cutoffDate {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSURL *parentDir = [NSURL fileURLWithPath:[[self class] loggingDirectory]];
NSURL *logDirectoryForCurrentRun =
[NSURL fileURLWithPath:[[self class] logDirectoryForCurrentRun]];
NSError *error;
NSArray *contents = [fileMgr contentsOfDirectoryAtURL:parentDir
includingPropertiesForKeys:@[ NSURLContentModificationDateKey ]
options:0
error:&error];
for (NSURL *itemURL in contents) {
if ([itemURL isEqual:logDirectoryForCurrentRun]) continue;
NSDate *modDate;
if ([itemURL getResourceValue:&modDate
forKey:NSURLContentModificationDateKey
error:&error]) {
if ([modDate compare:cutoffDate] == NSOrderedAscending) {
if (![fileMgr removeItemAtURL:itemURL error:&error]) {
NSLog(@"deleteLogDirectoriesOlderThanDate failed to delete %@: %@",
itemURL.path, error);
}
}
} else {
NSLog(@"deleteLogDirectoriesOlderThanDate failed to get mod date of %@: %@",
itemURL.path, error);
}
}
}
// formattedStringFromData returns a prettyprinted string for XML or JSON input,
// and a plain string for other input data
- (NSString *)formattedStringFromData:(NSData *)inputData
contentType:(NSString *)contentType
JSON:(NSDictionary **)outJSON {
if (!inputData) return nil;
// if the content type is JSON and we have the parsing class available, use that
if ([contentType hasPrefix:@"application/json"] && inputData.length > 5) {
// convert from JSON string to NSObjects and back to a formatted string
NSMutableDictionary *obj = [NSJSONSerialization JSONObjectWithData:inputData
options:NSJSONReadingMutableContainers
error:NULL];
if (obj) {
if (outJSON) *outJSON = obj;
if ([obj isKindOfClass:[NSMutableDictionary class]]) {
// for security and privacy, omit OAuth 2 response access and refresh tokens
if ([obj valueForKey:@"refresh_token"] != nil) {
[obj setObject:@"_snip_" forKey:@"refresh_token"];
}
if ([obj valueForKey:@"access_token"] != nil) {
[obj setObject:@"_snip_" forKey:@"access_token"];
}
}
NSData *data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted
error:NULL];
if (data) {
NSString *jsonStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
return jsonStr;
}
}
}
#if !TARGET_OS_IPHONE && !GTM_SKIP_LOG_XMLFORMAT
// verify that this data starts with the bytes indicating XML
NSString *const kXMLLintPath = @"/usr/bin/xmllint";
static BOOL gHasCheckedAvailability = NO;
static BOOL gIsXMLLintAvailable = NO;
if (!gHasCheckedAvailability) {
gIsXMLLintAvailable = [[NSFileManager defaultManager] fileExistsAtPath:kXMLLintPath];
gHasCheckedAvailability = YES;
}
if (gIsXMLLintAvailable
&& inputData.length > 5
&& strncmp(inputData.bytes, "<?xml", 5) == 0) {
// call xmllint to format the data
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:kXMLLintPath];
// use the dash argument to specify stdin as the source file
[task setArguments:@[ @"--format", @"-" ]];
[task setEnvironment:@{}];
NSPipe *inputPipe = [NSPipe pipe];
NSPipe *outputPipe = [NSPipe pipe];
[task setStandardInput:inputPipe];
[task setStandardOutput:outputPipe];
[task launch];
[[inputPipe fileHandleForWriting] writeData:inputData];
[[inputPipe fileHandleForWriting] closeFile];
// drain the stdout before waiting for the task to exit
NSData *formattedData = [[outputPipe fileHandleForReading] readDataToEndOfFile];
[task waitUntilExit];
int status = [task terminationStatus];
if (status == 0 && formattedData.length > 0) {
// success
inputData = formattedData;
}
}
#else
// we can't call external tasks on the iPhone; leave the XML unformatted
#endif
NSString *dataStr = [[NSString alloc] initWithData:inputData
encoding:NSUTF8StringEncoding];
return dataStr;
}
// stringFromStreamData creates a string given the supplied data
//
// If NSString can create a UTF-8 string from the data, then that is returned.
//
// Otherwise, this routine tries to find a MIME boundary at the beginning of the data block, and
// uses that to break up the data into parts. Each part will be used to try to make a UTF-8 string.
// For parts that fail, a replacement string showing the part header and <<n bytes>> is supplied
// in place of the binary data.
- (NSString *)stringFromStreamData:(NSData *)data
contentType:(NSString *)contentType {
if (!data) return nil;
// optimistically, see if the whole data block is UTF-8
NSString *streamDataStr = [self formattedStringFromData:data
contentType:contentType
JSON:NULL];
if (streamDataStr) return streamDataStr;
// Munge a buffer by replacing non-ASCII bytes with underscores, and turn that munged buffer an
// NSString. That gives us a string we can use with NSScanner.
NSMutableData *mutableData = [NSMutableData dataWithData:data];
unsigned char *bytes = (unsigned char *)mutableData.mutableBytes;
for (unsigned int idx = 0; idx < mutableData.length; ++idx) {
if (bytes[idx] > 0x7F || bytes[idx] == 0) {
bytes[idx] = '_';
}
}
NSString *mungedStr = [[NSString alloc] initWithData:mutableData
encoding:NSUTF8StringEncoding];
if (mungedStr) {
// scan for the boundary string
NSString *boundary = nil;
NSScanner *scanner = [NSScanner scannerWithString:mungedStr];
if ([scanner scanUpToString:@"\r\n" intoString:&boundary]
&& [boundary hasPrefix:@"--"]) {
// we found a boundary string; use it to divide the string into parts
NSArray *mungedParts = [mungedStr componentsSeparatedByString:boundary];
// look at each munged part in the original string, and try to convert those into UTF-8
NSMutableArray *origParts = [NSMutableArray array];
NSUInteger offset = 0;
for (NSString *mungedPart in mungedParts) {
NSUInteger partSize = mungedPart.length;
NSData *origPartData = [data subdataWithRange:NSMakeRange(offset, partSize)];
NSString *origPartStr = [[NSString alloc] initWithData:origPartData
encoding:NSUTF8StringEncoding];
if (origPartStr) {
// we could make this original part into UTF-8; use the string
[origParts addObject:origPartStr];
} else {
// this part can't be made into UTF-8; scan the header, if we can
NSString *header = nil;
NSScanner *headerScanner = [NSScanner scannerWithString:mungedPart];
if (![headerScanner scanUpToString:@"\r\n\r\n" intoString:&header]) {
// we couldn't find a header
header = @"";
}
// make a part string with the header and <<n bytes>>
NSString *binStr = [NSString stringWithFormat:@"\r%@\r<<%lu bytes>>\r",
header, (long)(partSize - header.length)];
[origParts addObject:binStr];
}
offset += partSize + boundary.length;
}
// rejoin the original parts
streamDataStr = [origParts componentsJoinedByString:boundary];
}
}
if (!streamDataStr) {
// give up; just make a string showing the uploaded bytes
streamDataStr = [NSString stringWithFormat:@"<<%u bytes>>", (unsigned int)data.length];
}
return streamDataStr;
}
// logFetchWithError is called following a successful or failed fetch attempt
//
// This method does all the work for appending to and creating log files
- (void)logFetchWithError:(NSError *)error {
if (![[self class] isLoggingEnabled]) return;
NSString *logDirectory = [[self class] logDirectoryForCurrentRun];
if (!logDirectory) return;
NSString *processName = [[self class] loggingProcessName];
// TODO: add Javascript to display response data formatted in hex
// each response's NSData goes into its own xml or txt file, though all responses for this run of
// the app share a main html file. This counter tracks all fetch responses for this app run.
//
// we'll use a local variable since this routine may be reentered while waiting for XML formatting
// to be completed by an external task
static int gResponseCounter = 0;
int responseCounter = ++gResponseCounter;
NSURLResponse *response = [self response];
NSDictionary *responseHeaders = [self responseHeaders];
NSString *responseDataStr = nil;
NSDictionary *responseJSON = nil;
// if there's response data, decide what kind of file to put it in based on the first bytes of the
// file or on the mime type supplied by the server
NSString *responseMIMEType = [response MIMEType];
BOOL isResponseImage = NO;
// file name for an image data file
NSString *responseDataFileName = nil;
int64_t responseDataLength = self.downloadedLength;
if (responseDataLength > 0) {
NSData *downloadedData = self.downloadedData;
if (downloadedData == nil
&& responseDataLength > 0
&& responseDataLength < 20000
&& self.destinationFileURL) {
// There's a download file that's not too big, so get the data to display from the downloaded
// file.
NSURL *destinationURL = self.destinationFileURL;
downloadedData = [NSData dataWithContentsOfURL:destinationURL];
}
NSString *responseType = [responseHeaders valueForKey:@"Content-Type"];
responseDataStr = [self formattedStringFromData:downloadedData
contentType:responseType
JSON:&responseJSON];
NSString *responseDataExtn = nil;
NSData *dataToWrite = nil;
if (responseDataStr) {
// we were able to make a UTF-8 string from the response data
if ([responseMIMEType isEqual:@"application/atom+xml"]
|| [responseMIMEType hasSuffix:@"/xml"]) {
responseDataExtn = @"xml";
dataToWrite = [responseDataStr dataUsingEncoding:NSUTF8StringEncoding];
}
} else if ([responseMIMEType isEqual:@"image/jpeg"]) {
responseDataExtn = @"jpg";
dataToWrite = downloadedData;
isResponseImage = YES;
} else if ([responseMIMEType isEqual:@"image/gif"]) {
responseDataExtn = @"gif";
dataToWrite = downloadedData;
isResponseImage = YES;
} else if ([responseMIMEType isEqual:@"image/png"]) {
responseDataExtn = @"png";
dataToWrite = downloadedData;
isResponseImage = YES;
} else {
// add more non-text types here
}
// if we have an extension, save the raw data in a file with that extension
if (responseDataExtn && dataToWrite) {
// generate a response file base name like
NSString *responseBaseName = [NSString stringWithFormat:@"fetch_%d_response", responseCounter];
responseDataFileName = [responseBaseName stringByAppendingPathExtension:responseDataExtn];
NSString *responseDataFilePath = [logDirectory stringByAppendingPathComponent:responseDataFileName];
NSError *downloadedError = nil;
if (gIsLoggingToFile && ![dataToWrite writeToFile:responseDataFilePath
options:0
error:&downloadedError]) {
NSLog(@"%@ logging write error:%@ (%@)", [self class], downloadedError, responseDataFileName);
}
}
}
// we'll have one main html file per run of the app
NSString *htmlName = [[self class] htmlFileName];
NSString *htmlPath =[logDirectory stringByAppendingPathComponent:htmlName];
// if the html file exists (from logging previous fetches) we don't need
// to re-write the header or the scripts
NSFileManager *fileMgr = [NSFileManager defaultManager];
BOOL didFileExist = [fileMgr fileExistsAtPath:htmlPath];
NSMutableString* outputHTML = [NSMutableString string];
// we need a header to say we'll have UTF-8 text
if (!didFileExist) {
[outputHTML appendFormat:@"<html><head><meta http-equiv=\"content-type\" "
"content=\"text/html; charset=UTF-8\"><title>%@ HTTP fetch log %@</title>",
processName, [[self class] loggingDateStamp]];
}
// now write the visible html elements
NSString *copyableFileName = [NSString stringWithFormat:@"fetch_%d.txt", responseCounter];
NSDate *now = [NSDate date];
// write the date & time, the comment, and the link to the plain-text (copyable) log
[outputHTML appendFormat:@"<b>%@ &nbsp;&nbsp;&nbsp;&nbsp; ", now];
NSString *comment = [self comment];
if (comment.length > 0) {
[outputHTML appendFormat:@"%@ &nbsp;&nbsp;&nbsp;&nbsp; ", comment];
}
[outputHTML appendFormat:@"</b><a href='%@'><i>request/response log</i></a><br>", copyableFileName];
NSTimeInterval elapsed = -self.initialBeginFetchDate.timeIntervalSinceNow;
[outputHTML appendFormat:@"elapsed: %5.3fsec<br>", elapsed];
// write the request URL
NSURLRequest *request = self.request;
NSString *requestMethod = request.HTTPMethod;
NSURL *requestURL = request.URL;
// Save the request URL for next time in case this redirects.
NSString *redirectedFromURLString = [self.redirectedFromURL absoluteString];
self.redirectedFromURL = [requestURL copy];
if (redirectedFromURLString) {
[outputHTML appendFormat:@"<FONT COLOR='#990066'><i>redirected from %@</i></FONT><br>",
redirectedFromURLString];
}
[outputHTML appendFormat:@"<b>request:</b> %@ <code>%@</code><br>\n", requestMethod, requestURL];
// write the request headers
NSDictionary *requestHeaders = request.allHTTPHeaderFields;
NSUInteger numberOfRequestHeaders = requestHeaders.count;
if (numberOfRequestHeaders > 0) {
// Indicate if the request is authorized; warn if the request is authorized but non-SSL
NSString *auth = [requestHeaders objectForKey:@"Authorization"];
NSString *headerDetails = @"";
if (auth) {
BOOL isInsecure = [[requestURL scheme] isEqual:@"http"];
if (isInsecure) {
// 26A0 =
headerDetails =
@"&nbsp;&nbsp;&nbsp;<i>authorized, non-SSL</i><FONT COLOR='#FF00FF'> &#x26A0;</FONT> ";
} else {
headerDetails = @"&nbsp;&nbsp;&nbsp;<i>authorized</i>";
}
}
NSString *cookiesHdr = [requestHeaders objectForKey:@"Cookie"];
if (cookiesHdr) {
headerDetails = [headerDetails stringByAppendingString:@"&nbsp;&nbsp;&nbsp;<i>cookies</i>"];
}
NSString *matchHdr = [requestHeaders objectForKey:@"If-Match"];
if (matchHdr) {
headerDetails = [headerDetails stringByAppendingString:@"&nbsp;&nbsp;&nbsp;<i>if-match</i>"];
}
matchHdr = [requestHeaders objectForKey:@"If-None-Match"];
if (matchHdr) {
headerDetails = [headerDetails stringByAppendingString:@"&nbsp;&nbsp;&nbsp;<i>if-none-match</i>"];
}
[outputHTML appendFormat:@"&nbsp;&nbsp; headers: %d %@<br>",
(int)numberOfRequestHeaders, headerDetails];
} else {
[outputHTML appendFormat:@"&nbsp;&nbsp; headers: none<br>"];
}
// write the request post data
NSData *bodyData = nil;
NSData *loggedStreamData = self.loggedStreamData;
if (loggedStreamData) {
bodyData = loggedStreamData;
} else {
bodyData = self.bodyData;
if (bodyData == nil) {
bodyData = self.request.HTTPBody;
}
}
uint64_t bodyDataLength = bodyData.length;
if (bodyData.length == 0) {
// If the data is in a body upload file URL, read that in if it's not huge.
NSURL *bodyFileURL = self.bodyFileURL;
if (bodyFileURL) {
NSNumber *fileSizeNum = nil;
NSError *fileSizeError = nil;
if ([bodyFileURL getResourceValue:&fileSizeNum
forKey:NSURLFileSizeKey
error:&fileSizeError]) {
bodyDataLength = [fileSizeNum unsignedLongLongValue];
if (bodyDataLength > 0 && bodyDataLength < 50000) {
bodyData = [NSData dataWithContentsOfURL:bodyFileURL
options:NSDataReadingUncached
error:&fileSizeError];
}
}
}
}
NSString *bodyDataStr = nil;
NSString *postType = [requestHeaders valueForKey:@"Content-Type"];
if (bodyDataLength > 0) {
[outputHTML appendFormat:@"&nbsp;&nbsp; data: %llu bytes, <code>%@</code><br>\n",
bodyDataLength, postType ? postType : @"(no type)"];
NSString *logRequestBody = self.logRequestBody;
if (logRequestBody) {
bodyDataStr = [logRequestBody copy];
self.logRequestBody = nil;
} else {
bodyDataStr = [self stringFromStreamData:bodyData
contentType:postType];
if (bodyDataStr) {
// remove OAuth 2 client secret and refresh token
bodyDataStr = [[self class] snipSubstringOfString:bodyDataStr
betweenStartString:@"client_secret="
endString:@"&"];
bodyDataStr = [[self class] snipSubstringOfString:bodyDataStr
betweenStartString:@"refresh_token="
endString:@"&"];
// remove ClientLogin password
bodyDataStr = [[self class] snipSubstringOfString:bodyDataStr
betweenStartString:@"&Passwd="
endString:@"&"];
}
}
} else {
// no post data
}
// write the response status, MIME type, URL
NSInteger status = [self statusCode];
if (response) {
NSString *statusString = @"";
if (status != 0) {
if (status == 200 || status == 201) {
statusString = [NSString stringWithFormat:@"%ld", (long)status];
// report any JSON-RPC error
if ([responseJSON isKindOfClass:[NSDictionary class]]) {
NSDictionary *jsonError = [responseJSON objectForKey:@"error"];
if ([jsonError isKindOfClass:[NSDictionary class]]) {
NSString *jsonCode = [[jsonError valueForKey:@"code"] description];
NSString *jsonMessage = [jsonError valueForKey:@"message"];
if (jsonCode || jsonMessage) {
// 2691 =
NSString *const jsonErrFmt =
@"&nbsp;&nbsp;&nbsp;<i>JSON error:</i> <FONT COLOR='#FF00FF'>%@ %@ &nbsp;&#x2691;</FONT>";
statusString = [statusString stringByAppendingFormat:jsonErrFmt,
jsonCode ? jsonCode : @"",
jsonMessage ? jsonMessage : @""];
}
}
}
} else {
// purple for anything other than 200 or 201
NSString *flag = status >= 400 ? @"&nbsp;&#x2691;" : @""; // 2691 =
NSString *explanation = [NSHTTPURLResponse localizedStringForStatusCode:status];
NSString *const statusFormat = @"<FONT COLOR='#FF00FF'>%ld %@ %@</FONT>";
statusString = [NSString stringWithFormat:statusFormat, (long)status, explanation, flag];
}
}
// show the response URL only if it's different from the request URL
NSString *responseURLStr = @"";
NSURL *responseURL = response.URL;
if (responseURL && ![responseURL isEqual:request.URL]) {
NSString *const responseURLFormat =
@"<FONT COLOR='#FF00FF'>response URL:</FONT> <code>%@</code><br>\n";
responseURLStr = [NSString stringWithFormat:responseURLFormat, [responseURL absoluteString]];
}
[outputHTML appendFormat:@"<b>response:</b>&nbsp;&nbsp;status %@<br>\n%@",
statusString, responseURLStr];
// Write the response headers
NSUInteger numberOfResponseHeaders = responseHeaders.count;
if (numberOfResponseHeaders > 0) {
// Indicate if the server is setting cookies
NSString *cookiesSet = [responseHeaders valueForKey:@"Set-Cookie"];
NSString *cookiesStr =
cookiesSet ? @"&nbsp;&nbsp;<FONT COLOR='#990066'><i>sets cookies</i></FONT>" : @"";
// Indicate if the server is redirecting
NSString *location = [responseHeaders valueForKey:@"Location"];
BOOL isRedirect = status >= 300 && status <= 399 && location != nil;
NSString *redirectsStr =
isRedirect ? @"&nbsp;&nbsp;<FONT COLOR='#990066'><i>redirects</i></FONT>" : @"";
[outputHTML appendFormat:@"&nbsp;&nbsp; headers: %d %@ %@<br>\n",
(int)numberOfResponseHeaders, cookiesStr, redirectsStr];
} else {
[outputHTML appendString:@"&nbsp;&nbsp; headers: none<br>\n"];
}
}
// error
if (error) {
[outputHTML appendFormat:@"<b>Error:</b> %@ <br>\n", error.description];
}
// Write the response data
if (responseDataFileName) {
if (isResponseImage) {
// Make a small inline image that links to the full image file
[outputHTML appendFormat:@"&nbsp;&nbsp; data: %lld bytes, <code>%@</code><br>",
responseDataLength, responseMIMEType];
NSString *const fmt =
@"<a href=\"%@\"><img src='%@' alt='image' style='border:solid thin;max-height:32'></a>\n";
[outputHTML appendFormat:fmt, responseDataFileName, responseDataFileName];
} else {
// The response data was XML; link to the xml file
NSString *const fmt =
@"&nbsp;&nbsp; data: %lld bytes, <code>%@</code>&nbsp;&nbsp;&nbsp;<i><a href=\"%@\">%@</a></i>\n";
[outputHTML appendFormat:fmt, responseDataLength, responseMIMEType,
responseDataFileName, [responseDataFileName pathExtension]];
}
} else {
// The response data was not an image; just show the length and MIME type
[outputHTML appendFormat:@"&nbsp;&nbsp; data: %lld bytes, <code>%@</code>\n",
responseDataLength, responseMIMEType ? responseMIMEType : @"(no response type)"];
}
// Make a single string of the request and response, suitable for copying
// to the clipboard and pasting into a bug report
NSMutableString *copyable = [NSMutableString string];
if (comment) {
[copyable appendFormat:@"%@\n\n", comment];
}
[copyable appendFormat:@"%@ elapsed: %5.3fsec\n", now, elapsed];
if (redirectedFromURLString) {
[copyable appendFormat:@"Redirected from %@\n", redirectedFromURLString];
}
[copyable appendFormat:@"Request: %@ %@\n", requestMethod, requestURL];
if (requestHeaders.count > 0) {
[copyable appendFormat:@"Request headers:\n%@\n",
[[self class] headersStringForDictionary:requestHeaders]];
}
if (bodyDataLength > 0) {
[copyable appendFormat:@"Request body: (%llu bytes)\n", bodyDataLength];
if (bodyDataStr) {
[copyable appendFormat:@"%@\n", bodyDataStr];
}
[copyable appendString:@"\n"];
}
if (response) {
[copyable appendFormat:@"Response: status %d\n", (int) status];
[copyable appendFormat:@"Response headers:\n%@\n",
[[self class] headersStringForDictionary:responseHeaders]];
[copyable appendFormat:@"Response body: (%lld bytes)\n", responseDataLength];
if (responseDataLength > 0) {
NSString *logResponseBody = self.logResponseBody;
if (logResponseBody) {
// The user has provided the response body text.
responseDataStr = [logResponseBody copy];
self.logResponseBody = nil;
}
if (responseDataStr != nil) {
[copyable appendFormat:@"%@\n", responseDataStr];
} else {
// Even though it's redundant, we'll put in text to indicate that all the bytes are binary.
if (self.destinationFileURL) {
[copyable appendFormat:@"<<%lld bytes>> to file %@\n",
responseDataLength, self.destinationFileURL.path];
} else {
[copyable appendFormat:@"<<%lld bytes>>\n", responseDataLength];
}
}
}
}
if (error) {
[copyable appendFormat:@"Error: %@\n", error];
}
// Save to log property before adding the separator
self.log = copyable;
[copyable appendString:@"-----------------------------------------------------------\n"];
// Write the copyable version to another file (linked to at the top of the html file, above)
//
// Ideally, something to just copy this to the clipboard like
// <span onCopy='window.event.clipboardData.setData(\"Text\",
// \"copyable stuff\");return false;'>Copy here.</span>"
// would work everywhere, but it only works in Safari as of 8/2010
if (gIsLoggingToFile) {
NSString *parentDir = [[self class] loggingDirectory];
NSString *copyablePath = [logDirectory stringByAppendingPathComponent:copyableFileName];
NSError *copyableError = nil;
if (![copyable writeToFile:copyablePath
atomically:NO
encoding:NSUTF8StringEncoding
error:&copyableError]) {
// Error writing to file
NSLog(@"%@ logging write error:%@ (%@)", [self class], copyableError, copyablePath);
}
[outputHTML appendString:@"<br><hr><p>"];
// Append the HTML to the main output file
const char* htmlBytes = outputHTML.UTF8String;
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:htmlPath
append:YES];
[stream open];
[stream write:(const uint8_t *) htmlBytes maxLength:strlen(htmlBytes)];
[stream close];
// Make a symlink to the latest html
NSString *const symlinkNameSuffix = [[self class] symlinkNameSuffix];
NSString *symlinkName = [processName stringByAppendingString:symlinkNameSuffix];
NSString *symlinkPath = [parentDir stringByAppendingPathComponent:symlinkName];
[fileMgr removeItemAtPath:symlinkPath error:NULL];
[fileMgr createSymbolicLinkAtPath:symlinkPath
withDestinationPath:htmlPath
error:NULL];
#if TARGET_OS_IPHONE
static BOOL gReportedLoggingPath = NO;
if (!gReportedLoggingPath) {
gReportedLoggingPath = YES;
NSLog(@"GTMSessionFetcher logging to \"%@\"", parentDir);
}
#endif
}
}
- (NSInputStream *)loggedInputStreamForInputStream:(NSInputStream *)inputStream {
if (!inputStream) return nil;
if (![GTMSessionFetcher isLoggingEnabled]) return inputStream;
[self clearLoggedStreamData]; // Clear any previous data.
Class monitorClass = NSClassFromString(@"GTMReadMonitorInputStream");
if (!monitorClass) {
NSString const *str = @"<<Uploaded stream log unavailable without GTMReadMonitorInputStream>>";
NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding];
[self appendLoggedStreamData:stringData];
return inputStream;
}
inputStream = [monitorClass inputStreamWithStream:inputStream];
GTMReadMonitorInputStream *readMonitorInputStream = (GTMReadMonitorInputStream *)inputStream;
[readMonitorInputStream setReadDelegate:self];
SEL readSel = @selector(inputStream:readIntoBuffer:length:);
[readMonitorInputStream setReadSelector:readSel];
return inputStream;
}
- (GTMSessionFetcherBodyStreamProvider)loggedStreamProviderForStreamProvider:
(GTMSessionFetcherBodyStreamProvider)streamProvider {
if (!streamProvider) return nil;
if (![GTMSessionFetcher isLoggingEnabled]) return streamProvider;
[self clearLoggedStreamData]; // Clear any previous data.
Class monitorClass = NSClassFromString(@"GTMReadMonitorInputStream");
if (!monitorClass) {
NSString const *str = @"<<Uploaded stream log unavailable without GTMReadMonitorInputStream>>";
NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding];
[self appendLoggedStreamData:stringData];
return streamProvider;
}
GTMSessionFetcherBodyStreamProvider loggedStreamProvider =
^(GTMSessionFetcherBodyStreamProviderResponse response) {
streamProvider(^(NSInputStream *bodyStream) {
bodyStream = [self loggedInputStreamForInputStream:bodyStream];
response(bodyStream);
});
};
return loggedStreamProvider;
}
@end
@implementation GTMSessionFetcher (GTMSessionFetcherLoggingUtilities)
- (void)inputStream:(GTMReadMonitorInputStream *)stream
readIntoBuffer:(void *)buffer
length:(int64_t)length {
// append the captured data
NSData *data = [NSData dataWithBytesNoCopy:buffer
length:(NSUInteger)length
freeWhenDone:NO];
[self appendLoggedStreamData:data];
}
#pragma mark Fomatting Utilities
+ (NSString *)snipSubstringOfString:(NSString *)originalStr
betweenStartString:(NSString *)startStr
endString:(NSString *)endStr {
#if SKIP_GTM_FETCH_LOGGING_SNIPPING
return originalStr;
#else
if (!originalStr) return nil;
// Find the start string, and replace everything between it
// and the end string (or the end of the original string) with "_snip_"
NSRange startRange = [originalStr rangeOfString:startStr];
if (startRange.location == NSNotFound) return originalStr;
// We found the start string
NSUInteger originalLength = originalStr.length;
NSUInteger startOfTarget = NSMaxRange(startRange);
NSRange targetAndRest = NSMakeRange(startOfTarget, originalLength - startOfTarget);
NSRange endRange = [originalStr rangeOfString:endStr
options:0
range:targetAndRest];
NSRange replaceRange;
if (endRange.location == NSNotFound) {
// Found no end marker so replace to end of string
replaceRange = targetAndRest;
} else {
// Replace up to the endStr
replaceRange = NSMakeRange(startOfTarget, endRange.location - startOfTarget);
}
NSString *result = [originalStr stringByReplacingCharactersInRange:replaceRange
withString:@"_snip_"];
return result;
#endif // SKIP_GTM_FETCH_LOGGING_SNIPPING
}
+ (NSString *)headersStringForDictionary:(NSDictionary *)dict {
// Format the dictionary in http header style, like
// Accept: application/json
// Cache-Control: no-cache
// Content-Type: application/json; charset=utf-8
//
// Pad the key names, but not beyond 16 chars, since long custom header
// keys just create too much whitespace
NSArray *keys = [dict.allKeys sortedArrayUsingSelector:@selector(compare:)];
NSMutableString *str = [NSMutableString string];
for (NSString *key in keys) {
NSString *value = [dict valueForKey:key];
if ([key isEqual:@"Authorization"]) {
// Remove OAuth 1 token
value = [[self class] snipSubstringOfString:value
betweenStartString:@"oauth_token=\""
endString:@"\""];
// Remove OAuth 2 bearer token (draft 16, and older form)
value = [[self class] snipSubstringOfString:value
betweenStartString:@"Bearer "
endString:@"\n"];
value = [[self class] snipSubstringOfString:value
betweenStartString:@"OAuth "
endString:@"\n"];
// Remove Google ClientLogin
value = [[self class] snipSubstringOfString:value
betweenStartString:@"GoogleLogin auth="
endString:@"\n"];
}
[str appendFormat:@" %@: %@\n", key, value];
}
return str;
}
@end
#endif // !STRIP_GTM_FETCH_LOGGING

View File

@@ -0,0 +1,190 @@
/* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// For best performance and convenient usage, fetchers should be generated by a common
// GTMSessionFetcherService instance, like
//
// _fetcherService = [[GTMSessionFetcherService alloc] init];
// GTMSessionFetcher* myFirstFetcher = [_fetcherService fetcherWithRequest:request1];
// GTMSessionFetcher* mySecondFetcher = [_fetcherService fetcherWithRequest:request2];
#import "GTMSessionFetcher.h"
GTM_ASSUME_NONNULL_BEGIN
// Notifications.
// This notification indicates a reusable session has become invalid. It is intended mainly for the
// service's unit tests.
//
// The notification object is the fetcher service.
// The invalid session is provided via the userInfo kGTMSessionFetcherServiceSessionKey key.
extern NSString *const kGTMSessionFetcherServiceSessionBecameInvalidNotification;
extern NSString *const kGTMSessionFetcherServiceSessionKey;
@interface GTMSessionFetcherService : NSObject<GTMSessionFetcherServiceProtocol>
// Queues of delayed and running fetchers. Each dictionary contains arrays
// of GTMSessionFetcher *fetchers, keyed by NSString *host
@property(atomic, strong, readonly, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, NSArray *) *delayedFetchersByHost;
@property(atomic, strong, readonly, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, NSArray *) *runningFetchersByHost;
// A max value of 0 means no fetchers should be delayed.
// The default limit is 10 simultaneous fetchers targeting each host.
// This does not apply to fetchers whose useBackgroundSession property is YES. Since services are
// not resurrected on an app relaunch, delayed fetchers would effectively be abandoned.
@property(atomic, assign) NSUInteger maxRunningFetchersPerHost;
// Properties to be applied to each fetcher; see GTMSessionFetcher.h for descriptions
@property(atomic, strong, GTM_NULLABLE) NSURLSessionConfiguration *configuration;
@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherConfigurationBlock configurationBlock;
@property(atomic, strong, GTM_NULLABLE) NSHTTPCookieStorage *cookieStorage;
@property(atomic, strong, GTM_NULL_RESETTABLE) dispatch_queue_t callbackQueue;
@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherChallengeBlock challengeBlock;
@property(atomic, strong, GTM_NULLABLE) NSURLCredential *credential;
@property(atomic, strong) NSURLCredential *proxyCredential;
@property(atomic, copy, GTM_NULLABLE) GTM_NSArrayOf(NSString *) *allowedInsecureSchemes;
@property(atomic, assign) BOOL allowLocalhostRequest;
@property(atomic, assign) BOOL allowInvalidServerCertificates;
@property(atomic, assign, getter=isRetryEnabled) BOOL retryEnabled;
@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherRetryBlock retryBlock;
@property(atomic, assign) NSTimeInterval maxRetryInterval;
@property(atomic, assign) NSTimeInterval minRetryInterval;
@property(atomic, copy, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, id) *properties;
#if GTM_BACKGROUND_TASK_FETCHING
@property(atomic, assign) BOOL skipBackgroundTask;
#endif
// A default useragent of GTMFetcherStandardUserAgentString(nil) will be given to each fetcher
// created by this service unless the request already has a user-agent header set.
// This default will be added starting with builds with the SDKs for OS X 10.11 and iOS 9.
//
// To use the configuration's default user agent, set this property to nil.
@property(atomic, copy, GTM_NULLABLE) NSString *userAgent;
// The authorizer to attach to the created fetchers. If a specific fetcher should
// not authorize its requests, the fetcher's authorizer property may be set to nil
// before the fetch begins.
@property(atomic, strong, GTM_NULLABLE) id<GTMFetcherAuthorizationProtocol> authorizer;
// Delegate queue used by the session when calling back to the fetcher. The default
// is the main queue. Changing this does not affect the queue used to call back to the
// application; that is specified by the callbackQueue property above.
@property(atomic, strong, GTM_NULL_RESETTABLE) NSOperationQueue *sessionDelegateQueue;
// When enabled, indicates the same session should be used by subsequent fetchers.
//
// This is enabled by default.
@property(atomic, assign) BOOL reuseSession;
// Sets the delay until an unused session is invalidated.
// The default interval is 60 seconds.
//
// If the interval is set to 0, then any reused session is not invalidated except by
// explicitly invoking -resetSession. Be aware that setting the interval to 0 thus
// causes the session's delegate to be retained until the session is explicitly reset.
@property(atomic, assign) NSTimeInterval unusedSessionTimeout;
// If shouldReuseSession is enabled, this will force creation of a new session when future
// fetchers begin.
- (void)resetSession;
// Create a fetcher
//
// These methods will return a fetcher. If successfully created, the connection
// will hold a strong reference to it for the life of the connection as well.
// So the caller doesn't have to hold onto the fetcher explicitly unless they
// want to be able to monitor or cancel it.
- (GTMSessionFetcher *)fetcherWithRequest:(NSURLRequest *)request;
- (GTMSessionFetcher *)fetcherWithURL:(NSURL *)requestURL;
- (GTMSessionFetcher *)fetcherWithURLString:(NSString *)requestURLString;
// Common method for fetcher creation.
//
// -fetcherWithRequest:fetcherClass: may be overridden to customize creation of
// fetchers. This is the ONLY method in the GTMSessionFetcher library intended to
// be overridden.
- (id)fetcherWithRequest:(NSURLRequest *)request
fetcherClass:(Class)fetcherClass;
- (BOOL)isDelayingFetcher:(GTMSessionFetcher *)fetcher;
- (NSUInteger)numberOfFetchers; // running + delayed fetchers
- (NSUInteger)numberOfRunningFetchers;
- (NSUInteger)numberOfDelayedFetchers;
// Return a list of all running or delayed fetchers. This includes fetchers created
// by the service which have been started and have not yet stopped.
//
// Returns an array of fetcher objects, or nil if none.
- (GTM_NULLABLE GTM_NSArrayOf(GTMSessionFetcher *) *)issuedFetchers;
// Search for running or delayed fetchers with the specified URL.
//
// Returns an array of fetcher objects found, or nil if none found.
- (GTM_NULLABLE GTM_NSArrayOf(GTMSessionFetcher *) *)issuedFetchersWithRequestURL:(NSURL *)requestURL;
- (void)stopAllFetchers;
// Methods for use by the fetcher class only.
- (GTM_NULLABLE NSURLSession *)session;
- (GTM_NULLABLE NSURLSession *)sessionForFetcherCreation;
- (GTM_NULLABLE id<NSURLSessionDelegate>)sessionDelegate;
- (GTM_NULLABLE NSDate *)stoppedAllFetchersDate;
// The testBlock can inspect its fetcher parameter's request property to
// determine which fetcher is being faked.
@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherTestBlock testBlock;
@end
@interface GTMSessionFetcherService (TestingSupport)
// Convenience method to create a fetcher service for testing.
//
// Fetchers generated by this mock fetcher service will not perform any
// network operation, but will invoke callbacks and provide the supplied data
// or error to the completion handler.
//
// You can make more customized mocks by setting the test block property of the service
// or fetcher; the test block can inspect the fetcher's request or other properties.
//
// See the description of the testBlock property below.
+ (instancetype)mockFetcherServiceWithFakedData:(GTM_NULLABLE NSData *)fakedDataOrNil
fakedError:(GTM_NULLABLE NSError *)fakedErrorOrNil;
// Spin the run loop and discard events (or, if not on the main thread, just sleep the thread)
// until all running and delayed fetchers have completed.
//
// This is only for use in testing or in tools without a user interface.
//
// Synchronous fetches should never be done by shipping apps; they are
// sufficient reason for rejection from the app store.
//
// Returns NO if timed out.
- (BOOL)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds;
@end
@interface GTMSessionFetcherService (BackwardsCompatibilityOnly)
// Clients using GTMSessionFetcher should set the cookie storage explicitly themselves.
// This method is just for compatibility with the old fetcher.
@property(atomic, assign) NSInteger cookieStorageMethod;
@end
GTM_ASSUME_NONNULL_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
/* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// GTMSessionUploadFetcher implements Google's resumable upload protocol.
//
// This subclass of GTMSessionFetcher simulates the series of fetches
// needed for chunked upload as a single fetch operation.
//
// Protocol document: TBD
//
// To the client, the only fetcher that exists is this class; the subsidiary
// fetchers needed for uploading chunks are not visible (though the most recent
// chunk fetcher may be accessed via the -activeFetcher or -chunkFetcher methods, and
// -responseHeaders and -statusCode reflect results from the most recent chunk
// fetcher.)
//
// Chunk fetchers are discarded as soon as they have completed.
//
// Note: Unlike the fetcher superclass, the methods of GTMSessionUploadFetcher should
// only be used from the main thread until further work is done to make this subclass
// thread-safe.
#import "GTMSessionFetcher.h"
#import "GTMSessionFetcherService.h"
GTM_ASSUME_NONNULL_BEGIN
// Unless an application knows it needs a smaller chunk size, it should use the standard
// chunk size, which sends the entire file as a single chunk to minimize upload overhead.
extern int64_t const kGTMSessionUploadFetcherStandardChunkSize;
// When uploading requires data buffer allocations (such as uploading from an NSData or
// an NSFileHandle) this is the maximum buffer size that will be created by the fetcher.
extern int64_t const kGTMSessionUploadFetcherMaximumDemandBufferSize;
// Notification that the upload location URL was provided by the server.
extern NSString *const kGTMSessionFetcherUploadLocationObtainedNotification;
// Block to provide data during uploads.
//
// Response data may be allocated with dataWithBytesNoCopy:length:freeWhenDone: for efficiency,
// and released after the response block returns.
//
// Pass nil as the data (and optionally an NSError) for a failure.
typedef void (^GTMSessionUploadFetcherDataProviderResponse)(NSData * GTM_NULLABLE_TYPE data,
NSError * GTM_NULLABLE_TYPE error);
typedef void (^GTMSessionUploadFetcherDataProvider)(int64_t offset, int64_t length,
GTMSessionUploadFetcherDataProviderResponse response);
@interface GTMSessionUploadFetcher : GTMSessionFetcher
// Create an upload fetcher specifying either the request or the resume location URL,
// then set an upload data source using one of these:
//
// setUploadFileURL:
// setUploadDataLength:provider:
// setUploadFileHandle:
// setUploadData:
+ (instancetype)uploadFetcherWithRequest:(NSURLRequest *)request
uploadMIMEType:(NSString *)uploadMIMEType
chunkSize:(int64_t)chunkSize
fetcherService:(GTM_NULLABLE GTMSessionFetcherService *)fetcherServiceOrNil;
+ (instancetype)uploadFetcherWithLocation:(NSURL * GTM_NULLABLE_TYPE)uploadLocationURL
uploadMIMEType:(NSString *)uploadMIMEType
chunkSize:(int64_t)chunkSize
fetcherService:(GTM_NULLABLE GTMSessionFetcherService *)fetcherServiceOrNil;
- (void)setUploadDataLength:(int64_t)fullLength
provider:(GTM_NULLABLE GTMSessionUploadFetcherDataProvider)block;
+ (NSArray *)uploadFetchersForBackgroundSessions;
+ (GTM_NULLABLE instancetype)uploadFetcherForSessionIdentifier:(NSString *)sessionIdentifier;
- (void)pauseFetching;
- (void)resumeFetching;
- (BOOL)isPaused;
@property(atomic, strong, GTM_NULLABLE) NSURL *uploadLocationURL;
@property(atomic, strong, GTM_NULLABLE) NSData *uploadData;
@property(atomic, strong, GTM_NULLABLE) NSURL *uploadFileURL;
@property(atomic, strong, GTM_NULLABLE) NSFileHandle *uploadFileHandle;
@property(atomic, copy, readonly, GTM_NULLABLE) GTMSessionUploadFetcherDataProvider uploadDataProvider;
@property(atomic, copy) NSString *uploadMIMEType;
@property(atomic, assign) int64_t chunkSize;
@property(atomic, readonly, assign) int64_t currentOffset;
// The fetcher for the current data chunk, if any
@property(atomic, strong, GTM_NULLABLE) GTMSessionFetcher *chunkFetcher;
// The active fetcher is the current chunk fetcher, or the upload fetcher itself
// if no chunk fetcher has yet been created.
@property(atomic, readonly) GTMSessionFetcher *activeFetcher;
// The last request made by an active fetcher. Useful for testing.
@property(atomic, readonly, GTM_NULLABLE) NSURLRequest *lastChunkRequest;
// The status code from the most recently-completed fetch.
@property(atomic, assign) NSInteger statusCode;
// Exposed for testing only.
@property(atomic, readonly, GTM_NULLABLE) dispatch_queue_t delegateCallbackQueue;
@property(atomic, readonly, GTM_NULLABLE) GTMSessionFetcherCompletionHandler delegateCompletionHandler;
@end
@interface GTMSessionFetcher (GTMSessionUploadFetcherMethods)
@property(readonly, GTM_NULLABLE) GTMSessionUploadFetcher *parentUploadFetcher;
@end
GTM_ASSUME_NONNULL_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
//
// GTMDebugSelectorValidation.h
//
// This file should only be included within an implimation file. In any
// function that takes an object and selector to invoke, you should call:
//
// GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, @encode(arg1type), ..., NULL)
// or
// GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(obj, sel, @encode(returnType), @encode(arg1type), ..., NULL)
//
// This will then validate that the selector is defined and using the right
// type(s), this can help catch errors much earlier then waiting for the
// selector to actually fire (and in the case of error selectors, might never
// really be tested until in the field).
//
// Copyright 2007-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#if DEBUG
#import <stdarg.h>
#import "GTMDefines.h"
static void GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(id obj, SEL sel, const char *retType, ...) {
// verify that the object's selector is implemented with the proper
// number and type of arguments
va_list argList;
va_start(argList, retType);
if (obj && sel) {
// check that the selector is implemented
_GTMDevAssert([obj respondsToSelector:sel],
@"\"%@\" selector \"%@\" is unimplemented or misnamed",
NSStringFromClass([obj class]),
NSStringFromSelector(sel));
const char *expectedArgType;
NSUInteger argCount = 2; // skip self and _cmd
NSMethodSignature *sig = [obj methodSignatureForSelector:sel];
// check that each expected argument is present and of the correct type
while ((expectedArgType = va_arg(argList, const char*)) != 0) {
if ([sig numberOfArguments] > argCount) {
const char *foundArgType = [sig getArgumentTypeAtIndex:argCount];
_GTMDevAssert(0 == strncmp(foundArgType, expectedArgType, strlen(expectedArgType)),
@"\"%@\" selector \"%@\" argument %u should be type %s",
NSStringFromClass([obj class]),
NSStringFromSelector(sel),
(uint32_t)(argCount - 2),
expectedArgType);
}
argCount++;
}
// check that the proper number of arguments are present in the selector
_GTMDevAssert(argCount == [sig numberOfArguments],
@"\"%@\" selector \"%@\" should have %u arguments",
NSStringFromClass([obj class]),
NSStringFromSelector(sel),
(uint32_t)(argCount - 2));
// if asked, validate the return type
if (retType && (strcmp("gtm_skip_return_test", retType) != 0)) {
const char *foundRetType = [sig methodReturnType];
_GTMDevAssert(0 == strncmp(foundRetType, retType, strlen(retType)),
@"\"%@\" selector \"%@\" return type should be type %s",
NSStringFromClass([obj class]),
NSStringFromSelector(sel),
retType);
}
}
va_end(argList);
}
#define GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, ...) \
GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments((obj), (sel), "gtm_skip_return_test", __VA_ARGS__)
#else // DEBUG
// make it go away if not debug
#define GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(obj, sel, retType, ...) do { } while (0)
#define GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, ...) do { } while (0)
#endif // DEBUG

View File

@@ -0,0 +1,44 @@
//
// GTMDebugThreadValidation.h
//
// Copyright 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import "GTMDefines.h"
#import <Foundation/Foundation.h>
// GTMCheckCurrentQueue, GTMIsCurrentQueue
//
// GTMCheckCurrentQueue takes a target queue and uses _GTMDevAssert to
// report if that is not the currently executing queue.
//
// GTMIsCurrentQueue takes a target queue and returns true if the target queue
// is the currently executing dispatch queue. This can be passed to another
// assertion call in debug builds; it should never be used in release code.
//
// The dispatch queue must have a label.
#define GTMCheckCurrentQueue(targetQueue) \
_GTMDevAssert(GTMIsCurrentQueue(targetQueue), \
@"Current queue is %s (expected %s)", \
_GTMQueueName(DISPATCH_CURRENT_QUEUE_LABEL), \
_GTMQueueName(targetQueue))
#define GTMIsCurrentQueue(targetQueue) \
(strcmp(_GTMQueueName(DISPATCH_CURRENT_QUEUE_LABEL), \
_GTMQueueName(targetQueue)) == 0)
#define _GTMQueueName(queue) \
(strlen(dispatch_queue_get_label(queue)) > 0 ? \
dispatch_queue_get_label(queue) : "unnamed")

View File

@@ -0,0 +1,69 @@
//
// GTMMethodCheck.h
//
// Copyright 2006-2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import <Foundation/Foundation.h>
#import <stdio.h>
#import <sysexits.h>
/// A macro for enforcing debug time checks to make sure all required methods are linked in
//
// When using categories, it can be very easy to forget to include the
// implementation of a category.
// Let's say you had a class foo that depended on method bar of class baz, and
// method bar was implemented as a member of a category.
// You could add the following code:
//
// GTM_METHOD_CHECK(baz, bar)
//
// and the code would check to make sure baz was implemented just before main
// was called. This works for both dynamic libraries, and executables.
//
//
// This is not compiled into release builds.
#ifdef DEBUG
// This is the "magic".
// A) we need a multi layer define here so that the preprocessor expands
// __LINE__ the way we want it. We need __LINE__ so that each of our
// GTM_METHOD_CHECKs generates a unique function name.
#define GTM_METHOD_CHECK(class, method) GTM_METHOD_CHECK_INNER(class, method, __LINE__)
#define GTM_METHOD_CHECK_INNER(class, method, line) \
GTM_METHOD_CHECK_INNER_INNER(class, method, line)
// B) define a function that is called at startup to check that |class| has an
// implementation for |method| (either a class method or an instance method).
#define GTM_METHOD_CHECK_INNER_INNER(class, method, line) \
__attribute__ ((constructor, visibility("hidden"))) \
static void xxGTMMethodCheckMethod ## class ## line () { \
@autoreleasepool { \
if (![class instancesRespondToSelector:@selector(method)] \
&& ![class respondsToSelector:@selector(method)]) { \
fprintf(stderr, "%s:%d: error: We need method '%s' to be linked in for class '%s'\n", \
__FILE__, line, #method, #class); \
exit(EX_SOFTWARE); \
} \
} \
}
#else // DEBUG
// Do nothing in release.
#define GTM_METHOD_CHECK(class, method)
#endif // DEBUG

View File

@@ -0,0 +1,199 @@
//
// GTMNSData+zlib.h
//
// Copyright 2007-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import <Foundation/Foundation.h>
#import "GTMDefines.h"
/// Helpers for dealing w/ zlib inflate/deflate calls.
@interface NSData (GTMZLibAdditions)
// NOTE: For 64bit, none of these apis handle input sizes >32bits, they will
// return nil when given such data. To handle data of that size you really
// should be streaming it rather then doing it all in memory.
#pragma mark Gzip Compression
/// Return an autoreleased NSData w/ the result of gzipping the bytes.
//
// Uses the default compression level.
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length;
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of gzipping the payload of |data|.
//
// Uses the default compression level.
+ (NSData *)gtm_dataByGzippingData:(NSData *)data __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of gzipping the bytes using |level| compression level.
//
// |level| can be 1-9, any other values will be clipped to that range.
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of gzipping the payload of |data| using |level| compression level.
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
compressionLevel:(int)level
error:(NSError **)error;
#pragma mark Zlib "Stream" Compression
// NOTE: deflate is *NOT* gzip. deflate is a "zlib" stream. pick which one
// you really want to create. (the inflate api will handle either)
/// Return an autoreleased NSData w/ the result of deflating the bytes.
//
// Uses the default compression level.
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of deflating the payload of |data|.
//
// Uses the default compression level.
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of deflating the bytes using |level| compression level.
//
// |level| can be 1-9, any other values will be clipped to that range.
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of deflating the payload of |data| using |level| compression level.
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
compressionLevel:(int)level
error:(NSError **)error;
#pragma mark Uncompress of Gzip or Zlib
/// Return an autoreleased NSData w/ the result of decompressing the bytes.
//
// The bytes to decompress can be zlib or gzip payloads.
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of decompressing the payload of |data|.
//
// The data to decompress can be zlib or gzip payloads.
+ (NSData *)gtm_dataByInflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByInflatingData:(NSData *)data
error:(NSError **)error;
#pragma mark "Raw" Compression Support
// NOTE: raw deflate is *NOT* gzip or deflate. it does not include a header
// of any form and should only be used within streams here an external crc/etc.
// is done to validate the data. The RawInflate apis can be used on data
// processed like this.
/// Return an autoreleased NSData w/ the result of *raw* deflating the bytes.
//
// Uses the default compression level.
// *No* header is added to the resulting data.
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data|.
//
// Uses the default compression level.
// *No* header is added to the resulting data.
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of *raw* deflating the bytes using |level| compression level.
//
// |level| can be 1-9, any other values will be clipped to that range.
// *No* header is added to the resulting data.
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data| using |level| compression level.
// *No* header is added to the resulting data.
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
compressionLevel:(int)level
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of *raw* decompressing the bytes.
//
// The data to decompress, it should *not* have any header (zlib nor gzip).
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error;
/// Return an autoreleased NSData w/ the result of *raw* decompressing the payload of |data|.
//
// The data to decompress, it should *not* have any header (zlib nor gzip).
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data
error:(NSError **)error;
@end
FOUNDATION_EXPORT NSString *const GTMNSDataZlibErrorDomain;
FOUNDATION_EXPORT NSString *const GTMNSDataZlibErrorKey; // NSNumber
FOUNDATION_EXPORT NSString *const GTMNSDataZlibRemainingBytesKey; // NSNumber
typedef NS_ENUM(NSInteger, GTMNSDataZlibError) {
GTMNSDataZlibErrorGreaterThan32BitsToCompress = 1024,
// An internal zlib error.
// GTMNSDataZlibErrorKey will contain the error value.
// NSLocalizedDescriptionKey may contain an error string from zlib.
// Look in zlib.h for list of errors.
GTMNSDataZlibErrorInternal,
// There was left over data in the buffer that was not used.
// GTMNSDataZlibRemainingBytesKey will contain number of remaining bytes.
GTMNSDataZlibErrorDataRemaining
};

View File

@@ -0,0 +1,531 @@
//
// GTMNSData+zlib.m
//
// Copyright 2007-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import "GTMNSData+zlib.h"
#import <zlib.h>
#import "GTMDefines.h"
#define kChunkSize 1024
NSString *const GTMNSDataZlibErrorDomain = @"com.google.GTMNSDataZlibErrorDomain";
NSString *const GTMNSDataZlibErrorKey = @"GTMNSDataZlibErrorKey";
NSString *const GTMNSDataZlibRemainingBytesKey = @"GTMNSDataZlibRemainingBytesKey";
typedef enum {
CompressionModeZlib,
CompressionModeGzip,
CompressionModeRaw,
} CompressionMode;
@interface NSData (GTMZlibAdditionsPrivate)
+ (NSData *)gtm_dataByCompressingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
mode:(CompressionMode)mode
error:(NSError **)error;
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
length:(NSUInteger)length
isRawData:(BOOL)isRawData
error:(NSError **)error;
@end
@implementation NSData (GTMZlibAdditionsPrivate)
+ (NSData *)gtm_dataByCompressingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
mode:(CompressionMode)mode
error:(NSError **)error {
if (!bytes || !length) {
return nil;
}
#if defined(__LP64__) && __LP64__
// Don't support > 32bit length for 64 bit, see note in header.
if (length > UINT_MAX) {
if (error) {
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
code:GTMNSDataZlibErrorGreaterThan32BitsToCompress
userInfo:nil];
}
return nil;
}
#endif
if (level == Z_DEFAULT_COMPRESSION) {
// the default value is actually outside the range, so we have to let it
// through specifically.
} else if (level < Z_BEST_SPEED) {
level = Z_BEST_SPEED;
} else if (level > Z_BEST_COMPRESSION) {
level = Z_BEST_COMPRESSION;
}
z_stream strm;
bzero(&strm, sizeof(z_stream));
int memLevel = 8; // the default
int windowBits = 15; // the default
switch (mode) {
case CompressionModeZlib:
// nothing to do
break;
case CompressionModeGzip:
windowBits += 16; // enable gzip header instead of zlib header
break;
case CompressionModeRaw:
windowBits *= -1; // Negative to mean no header.
break;
}
int retCode;
if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits,
memLevel, Z_DEFAULT_STRATEGY)) != Z_OK) {
// COV_NF_START - no real way to force this in a unittest (we guard all args)
if (error) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
forKey:GTMNSDataZlibErrorKey];
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
code:GTMNSDataZlibErrorInternal
userInfo:userInfo];
}
return nil;
// COV_NF_END
}
// hint the size at 1/4 the input size
NSMutableData *result = [NSMutableData dataWithCapacity:(length/4)];
unsigned char output[kChunkSize];
// setup the input
strm.avail_in = (unsigned int)length;
strm.next_in = (unsigned char*)bytes;
// loop to collect the data
do {
// update what we're passing in
strm.avail_out = kChunkSize;
strm.next_out = output;
retCode = deflate(&strm, Z_FINISH);
if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {
// COV_NF_START - no real way to force this in a unittest
// (in inflate, we can feed bogus/truncated data to test, but an error
// here would be some internal issue w/in zlib, and there isn't any real
// way to test it)
if (error) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
forKey:GTMNSDataZlibErrorKey];
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
code:GTMNSDataZlibErrorInternal
userInfo:userInfo];
}
deflateEnd(&strm);
return nil;
// COV_NF_END
}
// collect what we got
unsigned gotBack = kChunkSize - strm.avail_out;
if (gotBack > 0) {
[result appendBytes:output length:gotBack];
}
} while (retCode == Z_OK);
// if the loop exits, we used all input and the stream ended
_GTMDevAssert(strm.avail_in == 0,
@"thought we finished deflate w/o using all input, %u bytes left",
strm.avail_in);
_GTMDevAssert(retCode == Z_STREAM_END,
@"thought we finished deflate w/o getting a result of stream end, code %d",
retCode);
// clean up
deflateEnd(&strm);
return result;
} // gtm_dataByCompressingBytes:length:compressionLevel:useGzip:
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
length:(NSUInteger)length
isRawData:(BOOL)isRawData
error:(NSError **)error {
if (!bytes || !length) {
return nil;
}
#if defined(__LP64__) && __LP64__
// Don't support > 32bit length for 64 bit, see note in header.
if (length > UINT_MAX) {
return nil;
}
#endif
z_stream strm;
bzero(&strm, sizeof(z_stream));
// setup the input
strm.avail_in = (unsigned int)length;
strm.next_in = (unsigned char*)bytes;
int windowBits = 15; // 15 to enable any window size
if (isRawData) {
windowBits *= -1; // make it negative to signal no header.
} else {
windowBits += 32; // and +32 to enable zlib or gzip header detection.
}
int retCode;
if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) {
// COV_NF_START - no real way to force this in a unittest (we guard all args)
if (error) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
forKey:GTMNSDataZlibErrorKey];
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
code:GTMNSDataZlibErrorInternal
userInfo:userInfo];
}
return nil;
// COV_NF_END
}
// hint the size at 4x the input size
NSMutableData *result = [NSMutableData dataWithCapacity:(length*4)];
unsigned char output[kChunkSize];
// loop to collect the data
do {
// update what we're passing in
strm.avail_out = kChunkSize;
strm.next_out = output;
retCode = inflate(&strm, Z_NO_FLUSH);
if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {
if (error) {
NSMutableDictionary *userInfo =
[NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
forKey:GTMNSDataZlibErrorKey];
if (strm.msg) {
NSString *message = [NSString stringWithUTF8String:strm.msg];
if (message) {
[userInfo setObject:message forKey:NSLocalizedDescriptionKey];
}
}
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
code:GTMNSDataZlibErrorInternal
userInfo:userInfo];
}
inflateEnd(&strm);
return nil;
}
// collect what we got
unsigned gotBack = kChunkSize - strm.avail_out;
if (gotBack > 0) {
[result appendBytes:output length:gotBack];
}
} while (retCode == Z_OK);
// make sure there wasn't more data tacked onto the end of a valid compressed
// stream.
if (strm.avail_in != 0) {
if (error) {
NSDictionary *userInfo =
[NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:strm.avail_in]
forKey:GTMNSDataZlibRemainingBytesKey];
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
code:GTMNSDataZlibErrorDataRemaining
userInfo:userInfo];
}
result = nil;
}
// the only way out of the loop was by hitting the end of the stream
_GTMDevAssert(retCode == Z_STREAM_END,
@"thought we finished inflate w/o getting a result of stream end, code %d",
retCode);
// clean up
inflateEnd(&strm);
return result;
} // gtm_dataByInflatingBytes:length:windowBits:
@end
@implementation NSData (GTMZLibAdditions)
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length {
return [self gtm_dataByGzippingBytes:bytes length:length error:NULL];
} // gtm_dataByGzippingBytes:length:
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error {
return [self gtm_dataByCompressingBytes:bytes
length:length
compressionLevel:Z_DEFAULT_COMPRESSION
mode:CompressionModeGzip
error:error];
} // gtm_dataByGzippingBytes:length:error:
+ (NSData *)gtm_dataByGzippingData:(NSData *)data {
return [self gtm_dataByGzippingData:data error:NULL];
} // gtm_dataByGzippingData:
+ (NSData *)gtm_dataByGzippingData:(NSData *)data error:(NSError **)error {
return [self gtm_dataByCompressingBytes:[data bytes]
length:[data length]
compressionLevel:Z_DEFAULT_COMPRESSION
mode:CompressionModeGzip
error:error];
} // gtm_dataByGzippingData:error:
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level {
return [self gtm_dataByGzippingBytes:bytes
length:length
compressionLevel:level
error:NULL];
} // gtm_dataByGzippingBytes:length:level:
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
error:(NSError **)error{
return [self gtm_dataByCompressingBytes:bytes
length:length
compressionLevel:level
mode:CompressionModeGzip
error:error];
} // gtm_dataByGzippingBytes:length:level:error
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
compressionLevel:(int)level {
return [self gtm_dataByGzippingData:data
compressionLevel:level
error:NULL];
} // gtm_dataByGzippingData:level:
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
compressionLevel:(int)level
error:(NSError **)error{
return [self gtm_dataByCompressingBytes:[data bytes]
length:[data length]
compressionLevel:level
mode:CompressionModeGzip
error:error];
} // gtm_dataByGzippingData:level:error
#pragma mark -
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length {
return [self gtm_dataByDeflatingBytes:bytes
length:length
error:NULL];
} // gtm_dataByDeflatingBytes:length:
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error{
return [self gtm_dataByCompressingBytes:bytes
length:length
compressionLevel:Z_DEFAULT_COMPRESSION
mode:CompressionModeZlib
error:error];
} // gtm_dataByDeflatingBytes:length:error
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data {
return [self gtm_dataByDeflatingData:data error:NULL];
} // gtm_dataByDeflatingData:
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data error:(NSError **)error {
return [self gtm_dataByCompressingBytes:[data bytes]
length:[data length]
compressionLevel:Z_DEFAULT_COMPRESSION
mode:CompressionModeZlib
error:error];
} // gtm_dataByDeflatingData:
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level {
return [self gtm_dataByDeflatingBytes:bytes
length:length
compressionLevel:level
error:NULL];
} // gtm_dataByDeflatingBytes:length:level:
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
error:(NSError **)error {
return [self gtm_dataByCompressingBytes:bytes
length:length
compressionLevel:level
mode:CompressionModeZlib
error:error];
} // gtm_dataByDeflatingBytes:length:level:error:
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
compressionLevel:(int)level {
return [self gtm_dataByDeflatingData:data
compressionLevel:level
error:NULL];
} // gtm_dataByDeflatingData:level:
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
compressionLevel:(int)level
error:(NSError **)error {
return [self gtm_dataByCompressingBytes:[data bytes]
length:[data length]
compressionLevel:level
mode:CompressionModeZlib
error:error];
} // gtm_dataByDeflatingData:level:error:
#pragma mark -
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
length:(NSUInteger)length {
return [self gtm_dataByInflatingBytes:bytes
length:length
error:NULL];
} // gtm_dataByInflatingBytes:length:
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error {
return [self gtm_dataByInflatingBytes:bytes
length:length
isRawData:NO
error:error];
} // gtm_dataByInflatingBytes:length:error:
+ (NSData *)gtm_dataByInflatingData:(NSData *)data {
return [self gtm_dataByInflatingData:data error:NULL];
} // gtm_dataByInflatingData:
+ (NSData *)gtm_dataByInflatingData:(NSData *)data
error:(NSError **)error {
return [self gtm_dataByInflatingBytes:[data bytes]
length:[data length]
isRawData:NO
error:error];
} // gtm_dataByInflatingData:
#pragma mark -
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length {
return [self gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:NULL];
} // gtm_dataByRawDeflatingBytes:length:
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error {
return [self gtm_dataByCompressingBytes:bytes
length:length
compressionLevel:Z_DEFAULT_COMPRESSION
mode:CompressionModeRaw
error:error];
} // gtm_dataByRawDeflatingBytes:length:error:
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data {
return [self gtm_dataByRawDeflatingData:data error:NULL];
} // gtm_dataByRawDeflatingData:
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data error:(NSError **)error {
return [self gtm_dataByCompressingBytes:[data bytes]
length:[data length]
compressionLevel:Z_DEFAULT_COMPRESSION
mode:CompressionModeRaw
error:error];
} // gtm_dataByRawDeflatingData:error:
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level {
return [self gtm_dataByRawDeflatingBytes:bytes
length:length
compressionLevel:level
error:NULL];
} // gtm_dataByRawDeflatingBytes:length:compressionLevel:
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
length:(NSUInteger)length
compressionLevel:(int)level
error:(NSError **)error{
return [self gtm_dataByCompressingBytes:bytes
length:length
compressionLevel:level
mode:CompressionModeRaw
error:error];
} // gtm_dataByRawDeflatingBytes:length:compressionLevel:error:
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
compressionLevel:(int)level {
return [self gtm_dataByRawDeflatingData:data
compressionLevel:level
error:NULL];
} // gtm_dataByRawDeflatingData:compressionLevel:
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
compressionLevel:(int)level
error:(NSError **)error {
return [self gtm_dataByCompressingBytes:[data bytes]
length:[data length]
compressionLevel:level
mode:CompressionModeRaw
error:error];
} // gtm_dataByRawDeflatingData:compressionLevel:error:
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
length:(NSUInteger)length {
return [self gtm_dataByInflatingBytes:bytes
length:length
error:NULL];
} // gtm_dataByRawInflatingBytes:length:
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
length:(NSUInteger)length
error:(NSError **)error{
return [self gtm_dataByInflatingBytes:bytes
length:length
isRawData:YES
error:error];
} // gtm_dataByRawInflatingBytes:length:error:
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data {
return [self gtm_dataByRawInflatingData:data
error:NULL];
} // gtm_dataByRawInflatingData:
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data
error:(NSError **)error {
return [self gtm_dataByInflatingBytes:[data bytes]
length:[data length]
isRawData:YES
error:error];
} // gtm_dataByRawInflatingData:error:
@end

View File

@@ -0,0 +1,40 @@
//
// GTMNSDictionary+URLArguments.h
//
// Copyright 2006-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import <Foundation/Foundation.h>
/// Utility for building a URL or POST argument string.
@interface NSDictionary (GTMNSDictionaryURLArgumentsAdditions)
/// Returns a dictionary of the decoded key-value pairs in a http arguments
/// string of the form key1=value1&key2=value2&...&keyN=valueN.
/// Keys and values will be unescaped automatically.
/// Only the first value for a repeated key is returned.
///
/// NOTE: Apps targeting iOS 8 or OS X 10.10 and later should use
/// NSURLComponents and NSURLQueryItem to create URLs with
/// query arguments instead of using these category methods.
+ (NSDictionary *)gtm_dictionaryWithHttpArgumentsString:(NSString *)argString;
/// Gets a string representation of the dictionary in the form
/// key1=value1&key2=value2&...&keyN=valueN, suitable for use as either
/// URL arguments (after a '?') or POST body. Keys and values will be escaped
/// automatically, so should be unescaped in the dictionary.
- (NSString *)gtm_httpArgumentsString;
@end

View File

@@ -0,0 +1,77 @@
//
// GTMNSDictionary+URLArguments.m
//
// Copyright 2006-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import "GTMNSDictionary+URLArguments.h"
#import "GTMNSString+URLArguments.h"
#import "GTMMethodCheck.h"
#import "GTMDefines.h"
// Export a nonsense symbol to suppress a libtool warning when this is linked alone in a static lib.
__attribute__((visibility("default")))
char GTMNSDictionaryURLArgumentsExportToSuppressLibToolWarning = 0;
@implementation NSDictionary (GTMNSDictionaryURLArgumentsAdditions)
GTM_METHOD_CHECK(NSString, gtm_stringByEscapingForURLArgument);
GTM_METHOD_CHECK(NSString, gtm_stringByUnescapingFromURLArgument);
+ (NSDictionary *)gtm_dictionaryWithHttpArgumentsString:(NSString *)argString {
NSMutableDictionary* ret = [NSMutableDictionary dictionary];
NSArray* components = [argString componentsSeparatedByString:@"&"];
NSString* component;
// Use reverse order so that the first occurrence of a key replaces
// those subsequent.
for (component in [components reverseObjectEnumerator]) {
if ([component length] == 0)
continue;
NSRange pos = [component rangeOfString:@"="];
NSString *key;
NSString *val;
if (pos.location == NSNotFound) {
key = [component gtm_stringByUnescapingFromURLArgument];
val = @"";
} else {
key = [[component substringToIndex:pos.location]
gtm_stringByUnescapingFromURLArgument];
val = [[component substringFromIndex:pos.location + pos.length]
gtm_stringByUnescapingFromURLArgument];
}
// gtm_stringByUnescapingFromURLArgument returns nil on invalid UTF8
// and NSMutableDictionary raises an exception when passed nil values.
if (!key) key = @"";
if (!val) val = @"";
[ret setObject:val forKey:key];
}
return ret;
}
- (NSString *)gtm_httpArgumentsString {
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:[self count]];
NSString* key;
for (key in self) {
[arguments addObject:[NSString stringWithFormat:@"%@=%@",
[key gtm_stringByEscapingForURLArgument],
[[[self objectForKey:key] description] gtm_stringByEscapingForURLArgument]]];
}
return [arguments componentsJoinedByString:@"&"];
}
@end

View File

@@ -0,0 +1,45 @@
//
// GTMNSString+URLArguments.h
//
// Copyright 2006-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import <Foundation/Foundation.h>
/// Utilities for encoding and decoding URL arguments.
@interface NSString (GTMNSStringURLArgumentsAdditions)
/// Returns a string that is escaped properly to be a URL argument.
///
/// This differs from stringByAddingPercentEscapesUsingEncoding: in that it
/// will escape all the reserved characters (per RFC 3986
/// <http://www.ietf.org/rfc/rfc3986.txt>) which
/// stringByAddingPercentEscapesUsingEncoding would leave.
///
/// This will also escape '%', so this should not be used on a string that has
/// already been escaped unless double-escaping is the desired result.
///
/// NOTE: Apps targeting iOS 8 or OS X 10.10 and later should use
/// NSURLComponents and NSURLQueryItem to create properly-escaped
/// URLs instead of using these category methods.
- (NSString*)gtm_stringByEscapingForURLArgument;
/// Returns the unescaped version of a URL argument
///
/// This has the same behavior as stringByReplacingPercentEscapesUsingEncoding:,
/// except that it will also convert '+' to space.
- (NSString*)gtm_stringByUnescapingFromURLArgument;
@end

View File

@@ -0,0 +1,48 @@
//
// GTMNSString+URLArguments.m
//
// Copyright 2006-2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import "GTMNSString+URLArguments.h"
@implementation NSString (GTMNSStringURLArgumentsAdditions)
- (NSString *)gtm_stringByEscapingForURLArgument {
// Encode all the reserved characters, per RFC 3986
// (<http://www.ietf.org/rfc/rfc3986.txt>)
CFStringRef escaped =
CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8);
#if defined(__has_feature) && __has_feature(objc_arc)
return CFBridgingRelease(escaped);
#else
return [(NSString *)escaped autorelease];
#endif
}
- (NSString *)gtm_stringByUnescapingFromURLArgument {
NSMutableString *resultString = [NSMutableString stringWithString:self];
[resultString replaceOccurrencesOfString:@"+"
withString:@" "
options:NSLiteralSearch
range:NSMakeRange(0, [resultString length])];
return [resultString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
@end

View File

@@ -0,0 +1,392 @@
//
// GTMDefines.h
//
// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
// ============================================================================
#include <AvailabilityMacros.h>
#include <TargetConditionals.h>
#ifdef __OBJC__
#include <Foundation/NSObjCRuntime.h>
#endif // __OBJC__
#if TARGET_OS_IPHONE
#include <Availability.h>
#endif // TARGET_OS_IPHONE
// ----------------------------------------------------------------------------
// CPP symbols that can be overridden in a prefix to control how the toolbox
// is compiled.
// ----------------------------------------------------------------------------
// By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
// when a validation fails. If you implement your own validators, you may want
// to control their internals using the same macros for consistency.
#ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
#define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
#endif
// Ensure __has_feature and __has_extension are safe to use.
// See http://clang-analyzer.llvm.org/annotations.html
#ifndef __has_feature // Optional.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif
// Give ourselves a consistent way to do inlines. Apple's macros even use
// a few different actual definitions, so we're based off of the foundation
// one.
#if !defined(GTM_INLINE)
#if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__)
#define GTM_INLINE static __inline__ __attribute__((always_inline))
#else
#define GTM_INLINE static __inline__
#endif
#endif
// Give ourselves a consistent way of doing externs that links up nicely
// when mixing objc and objc++
#if !defined (GTM_EXTERN)
#if defined __cplusplus
#define GTM_EXTERN extern "C"
#define GTM_EXTERN_C_BEGIN extern "C" {
#define GTM_EXTERN_C_END }
#else
#define GTM_EXTERN extern
#define GTM_EXTERN_C_BEGIN
#define GTM_EXTERN_C_END
#endif
#endif
// Give ourselves a consistent way of exporting things if we have visibility
// set to hidden.
#if !defined (GTM_EXPORT)
#define GTM_EXPORT __attribute__((visibility("default")))
#endif
// Give ourselves a consistent way of declaring something as unused. This
// doesn't use __unused because that is only supported in gcc 4.2 and greater.
#if !defined (GTM_UNUSED)
#define GTM_UNUSED(x) ((void)(x))
#endif
// _GTMDevLog & _GTMDevAssert
//
// _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
// developer level errors. This implementation simply macros to NSLog/NSAssert.
// It is not intended to be a general logging/reporting system.
//
// Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
// for a little more background on the usage of these macros.
//
// _GTMDevLog log some error/problem in debug builds
// _GTMDevAssert assert if condition isn't met w/in a method/function
// in all builds.
//
// To replace this system, just provide different macro definitions in your
// prefix header. Remember, any implementation you provide *must* be thread
// safe since this could be called by anything in what ever situtation it has
// been placed in.
//
// We only define the simple macros if nothing else has defined this.
#ifndef _GTMDevLog
#ifdef DEBUG
#define _GTMDevLog(...) NSLog(__VA_ARGS__)
#else
#define _GTMDevLog(...) do { } while (0)
#endif
#endif // _GTMDevLog
#ifndef _GTMDevAssert
// we directly invoke the NSAssert handler so we can pass on the varargs
// (NSAssert doesn't have a macro we can use that takes varargs)
#if !defined(NS_BLOCK_ASSERTIONS)
#define _GTMDevAssert(condition, ...) \
do { \
if (!(condition)) { \
[[NSAssertionHandler currentHandler] \
handleFailureInFunction:(NSString *) \
[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
file:(NSString *)[NSString stringWithUTF8String:__FILE__] \
lineNumber:__LINE__ \
description:__VA_ARGS__]; \
} \
} while(0)
#else // !defined(NS_BLOCK_ASSERTIONS)
#define _GTMDevAssert(condition, ...) do { } while (0)
#endif // !defined(NS_BLOCK_ASSERTIONS)
#endif // _GTMDevAssert
// _GTMCompileAssert
//
// Note: Software for current compilers should just use _Static_assert directly
// instead of this macro.
//
// _GTMCompileAssert is an assert that is meant to fire at compile time if you
// want to check things at compile instead of runtime. For example if you
// want to check that a wchar is 4 bytes instead of 2 you would use
// _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
// Note that the second "arg" is not in quotes, and must be a valid processor
// symbol in it's own right (no spaces, punctuation etc).
// Wrapping this in an #ifndef allows external groups to define their own
// compile time assert scheme.
#ifndef _GTMCompileAssert
#if __has_feature(c_static_assert) || __has_extension(c_static_assert)
#define _GTMCompileAssert(test, msg) _Static_assert((test), #msg)
#else
// Pre-Xcode 7 support.
//
// We got this technique from here:
// http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
#define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
#define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
#define _GTMCompileAssert(test, msg) \
typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
#endif // __has_feature(c_static_assert) || __has_extension(c_static_assert)
#endif // _GTMCompileAssert
// ----------------------------------------------------------------------------
// CPP symbols defined based on the project settings so the GTM code has
// simple things to test against w/o scattering the knowledge of project
// setting through all the code.
// ----------------------------------------------------------------------------
// Provide a single constant CPP symbol that all of GTM uses for ifdefing
// iPhone code.
#if TARGET_OS_IPHONE // iPhone SDK
// For iPhone specific stuff
#define GTM_IPHONE_SDK 1
#if TARGET_IPHONE_SIMULATOR
#define GTM_IPHONE_DEVICE 0
#define GTM_IPHONE_SIMULATOR 1
#else
#define GTM_IPHONE_DEVICE 1
#define GTM_IPHONE_SIMULATOR 0
#endif // TARGET_IPHONE_SIMULATOR
// By default, GTM has provided it's own unittesting support, define this
// to use the support provided by Xcode, especially for the Xcode4 support
// for unittesting.
#ifndef GTM_USING_XCTEST
#define GTM_USING_XCTEST 0
#endif
#define GTM_MACOS_SDK 0
#else
// For MacOS specific stuff
#define GTM_MACOS_SDK 1
#define GTM_IPHONE_SDK 0
#define GTM_IPHONE_SIMULATOR 0
#define GTM_IPHONE_DEVICE 0
#ifndef GTM_USING_XCTEST
#define GTM_USING_XCTEST 0
#endif
#endif
// Some of our own availability macros
#if GTM_MACOS_SDK
#define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
#define GTM_AVAILABLE_ONLY_ON_MACOS
#else
#define GTM_AVAILABLE_ONLY_ON_IPHONE
#define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
#endif
// GC was dropped by Apple, define the old constant incase anyone still keys
// off of it.
#ifndef GTM_SUPPORT_GC
#define GTM_SUPPORT_GC 0
#endif
// Some support for advanced clang static analysis functionality
#ifndef NS_RETURNS_RETAINED
#if __has_feature(attribute_ns_returns_retained)
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
#else
#define NS_RETURNS_RETAINED
#endif
#endif
#ifndef NS_RETURNS_NOT_RETAINED
#if __has_feature(attribute_ns_returns_not_retained)
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
#else
#define NS_RETURNS_NOT_RETAINED
#endif
#endif
#ifndef CF_RETURNS_RETAINED
#if __has_feature(attribute_cf_returns_retained)
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#else
#define CF_RETURNS_RETAINED
#endif
#endif
#ifndef CF_RETURNS_NOT_RETAINED
#if __has_feature(attribute_cf_returns_not_retained)
#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
#else
#define CF_RETURNS_NOT_RETAINED
#endif
#endif
#ifndef NS_CONSUMED
#if __has_feature(attribute_ns_consumed)
#define NS_CONSUMED __attribute__((ns_consumed))
#else
#define NS_CONSUMED
#endif
#endif
#ifndef CF_CONSUMED
#if __has_feature(attribute_cf_consumed)
#define CF_CONSUMED __attribute__((cf_consumed))
#else
#define CF_CONSUMED
#endif
#endif
#ifndef NS_CONSUMES_SELF
#if __has_feature(attribute_ns_consumes_self)
#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
#else
#define NS_CONSUMES_SELF
#endif
#endif
#ifndef GTM_NONNULL
#if defined(__has_attribute)
#if __has_attribute(nonnull)
#define GTM_NONNULL(x) __attribute__((nonnull x))
#else
#define GTM_NONNULL(x)
#endif
#else
#define GTM_NONNULL(x)
#endif
#endif
// Invalidates the initializer from which it's called.
#ifndef GTMInvalidateInitializer
#if __has_feature(objc_arc)
#define GTMInvalidateInitializer() \
do { \
[self class]; /* Avoid warning of dead store to |self|. */ \
_GTMDevAssert(NO, @"Invalid initializer."); \
return nil; \
} while (0)
#else
#define GTMInvalidateInitializer() \
do { \
[self release]; \
_GTMDevAssert(NO, @"Invalid initializer."); \
return nil; \
} while (0)
#endif
#endif
#ifndef GTMCFAutorelease
// GTMCFAutorelease returns an id. In contrast, Apple's CFAutorelease returns
// a CFTypeRef.
#if __has_feature(objc_arc)
#define GTMCFAutorelease(x) CFBridgingRelease(x)
#else
#define GTMCFAutorelease(x) ([(id)x autorelease])
#endif
#endif
#ifdef __OBJC__
// Macro to allow you to create NSStrings out of other macros.
// #define FOO foo
// NSString *fooString = GTM_NSSTRINGIFY(FOO);
#if !defined (GTM_NSSTRINGIFY)
#define GTM_NSSTRINGIFY_INNER(x) @#x
#define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
#endif
// Macro to allow fast enumeration when building for 10.5 or later, and
// reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration
// does keys, so pick the right thing, nothing is done on the FastEnumeration
// side to be sure you're getting what you wanted.
#ifndef GTM_FOREACH_OBJECT
#if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
#define GTM_FOREACH_ENUMEREE(element, enumeration) \
for (element in enumeration)
#define GTM_FOREACH_OBJECT(element, collection) \
for (element in collection)
#define GTM_FOREACH_KEY(element, collection) \
for (element in collection)
#else
#define GTM_FOREACH_ENUMEREE(element, enumeration) \
for (NSEnumerator *_ ## element ## _enum = enumeration; \
(element = [_ ## element ## _enum nextObject]) != nil; )
#define GTM_FOREACH_OBJECT(element, collection) \
GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
#define GTM_FOREACH_KEY(element, collection) \
GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
#endif
#endif
// ============================================================================
// GTM_SEL_STRING is for specifying selector (usually property) names to KVC
// or KVO methods.
// In debug it will generate warnings for undeclared selectors if
// -Wunknown-selector is turned on.
// In release it will have no runtime overhead.
#ifndef GTM_SEL_STRING
#ifdef DEBUG
#define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
#else
#define GTM_SEL_STRING(selName) @#selName
#endif // DEBUG
#endif // GTM_SEL_STRING
#ifndef GTM_WEAK
#if __has_feature(objc_arc_weak)
// With ARC enabled, __weak means a reference that isn't implicitly
// retained. __weak objects are accessed through runtime functions, so
// they are zeroed out, but this requires OS X 10.7+.
// At clang r251041+, ARC-style zeroing weak references even work in
// non-ARC mode.
#define GTM_WEAK __weak
#elif __has_feature(objc_arc)
// ARC, but targeting 10.6 or older, where zeroing weak references don't
// exist.
#define GTM_WEAK __unsafe_unretained
#else
// With manual reference counting, __weak used to be silently ignored.
// clang r251041 gives it the ARC semantics instead. This means they
// now require a deployment target of 10.7, while some clients of GTM
// still target 10.6. In these cases, expand to __unsafe_unretained instead
#define GTM_WEAK
#endif
#endif
#endif // __OBJC__

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,15 @@
# GTM: Google Toolbox for Mac #
**Project site** <https://github.com/google/google-toolbox-for-mac><br>
**Discussion group** <http://groups.google.com/group/google-toolbox-for-mac>
# Google Toolbox for Mac #
A collection of source from different Google projects that may be of use to
developers working other iOS or OS X projects.
If you find a problem/bug or want a new feature to be included in the Google
Toolbox for Mac, please join the
[discussion group](http://groups.google.com/group/google-toolbox-for-mac)
or submit an
[issue](https://github.com/google/google-toolbox-for-mac/issues).

View File

@@ -0,0 +1 @@
../../../Firebase/Core/Sources/Firebase.h

View File

@@ -0,0 +1 @@
../../../GTMSessionFetcher/Source/GTMSessionFetcher.h

View File

@@ -0,0 +1 @@
../../../GTMSessionFetcher/Source/GTMSessionFetcherLogging.h

View File

@@ -0,0 +1 @@
../../../GTMSessionFetcher/Source/GTMSessionFetcherService.h

View File

@@ -0,0 +1 @@
../../../GTMSessionFetcher/Source/GTMSessionUploadFetcher.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/DebugUtils/GTMDebugSelectorValidation.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/DebugUtils/GTMDebugThreadValidation.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/GTMDefines.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/DebugUtils/GTMMethodCheck.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/Foundation/GTMNSData+zlib.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/Foundation/GTMNSDictionary+URLArguments.h

View File

@@ -0,0 +1 @@
../../../GoogleToolboxForMac/Foundation/GTMNSString+URLArguments.h

View File

@@ -0,0 +1 @@
../../../Firebase/Core/Sources/Firebase.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalyticsConfiguration.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRApp.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRConfiguration.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h

View File

@@ -0,0 +1 @@
../../../../FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIROptions.h

Some files were not shown because too many files have changed in this diff Show More