diff --git a/.gitignore b/.gitignore index 3e55a23..4ba322d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,18 @@ profile *.moved-aside DerivedData .idea/ -Carthage \ No newline at end of file +Carthage + +# Local build output (this project builds into ./build via -derivedDataPath) +build/ +*.profraw + +# Keep the Swift Package Manager resolved versions under version control +# (overrides the broad *.xcworkspace rule above) +!PodcastMenu.xcodeproj/project.xcworkspace +PodcastMenu.xcodeproj/project.xcworkspace/* +!PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata +PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/* +!PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm +PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/* +!PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved \ No newline at end of file diff --git a/Cartfile b/Cartfile deleted file mode 100644 index cf17f3f..0000000 --- a/Cartfile +++ /dev/null @@ -1,5 +0,0 @@ -github "SwiftyJSON/SwiftyJSON" ~> 3.1 - -github "Instagram/IGListKit" ~> 2.0.0 - -github "sparkle-project/Sparkle" ~> 1.17 \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved deleted file mode 100644 index b70aa69..0000000 --- a/Cartfile.resolved +++ /dev/null @@ -1,3 +0,0 @@ -github "Instagram/IGListKit" "2.1.0" -github "SwiftyJSON/SwiftyJSON" "3.1.4" -github "sparkle-project/Sparkle" "1.18.1" diff --git a/Crashlytics.framework/Crashlytics b/Crashlytics.framework/Crashlytics deleted file mode 120000 index 7074275..0000000 --- a/Crashlytics.framework/Crashlytics +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Crashlytics \ No newline at end of file diff --git a/Crashlytics.framework/Headers b/Crashlytics.framework/Headers deleted file mode 120000 index a177d2a..0000000 --- a/Crashlytics.framework/Headers +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Headers \ No newline at end of file diff --git a/Crashlytics.framework/Modules b/Crashlytics.framework/Modules deleted file mode 120000 index 5736f31..0000000 --- a/Crashlytics.framework/Modules +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Modules \ No newline at end of file diff --git a/Crashlytics.framework/Resources b/Crashlytics.framework/Resources deleted file mode 120000 index 953ee36..0000000 --- a/Crashlytics.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file diff --git a/Crashlytics.framework/Versions/A/Crashlytics b/Crashlytics.framework/Versions/A/Crashlytics deleted file mode 100755 index db310dd..0000000 Binary files a/Crashlytics.framework/Versions/A/Crashlytics and /dev/null differ diff --git a/Crashlytics.framework/Versions/A/Headers/ANSCompatibility.h b/Crashlytics.framework/Versions/A/Headers/ANSCompatibility.h deleted file mode 100644 index 6ec011d..0000000 --- a/Crashlytics.framework/Versions/A/Headers/ANSCompatibility.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// ANSCompatibility.h -// AnswersKit -// -// Copyright (c) 2015 Crashlytics, Inc. All rights reserved. -// - -#pragma once - -#if !__has_feature(nullability) -#define nonnull -#define nullable -#define _Nullable -#define _Nonnull -#endif - -#ifndef NS_ASSUME_NONNULL_BEGIN -#define NS_ASSUME_NONNULL_BEGIN -#endif - -#ifndef NS_ASSUME_NONNULL_END -#define NS_ASSUME_NONNULL_END -#endif - -#if __has_feature(objc_generics) -#define ANS_GENERIC_NSARRAY(type) NSArray -#define ANS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary -#else -#define ANS_GENERIC_NSARRAY(type) NSArray -#define ANS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary -#endif diff --git a/Crashlytics.framework/Versions/A/Headers/Answers.h b/Crashlytics.framework/Versions/A/Headers/Answers.h deleted file mode 100644 index 710eb50..0000000 --- a/Crashlytics.framework/Versions/A/Headers/Answers.h +++ /dev/null @@ -1,210 +0,0 @@ -// -// Answers.h -// Crashlytics -// -// Copyright (c) 2015 Crashlytics, Inc. All rights reserved. -// - -#import -#import "ANSCompatibility.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * This class exposes the Answers Events API, allowing you to track key - * user user actions and metrics in your app. - */ -@interface Answers : NSObject - -/** - * Log a Sign Up event to see users signing up for your app in real-time, understand how - * many users are signing up with different methods and their success rate signing up. - * - * @param signUpMethodOrNil The method by which a user logged in, e.g. Twitter or Digits. - * @param signUpSucceededOrNil The ultimate success or failure of the login - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logSignUpWithMethod:(nullable NSString *)signUpMethodOrNil - success:(nullable NSNumber *)signUpSucceededOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log an Log In event to see users logging into your app in real-time, understand how many - * users are logging in with different methods and their success rate logging into your app. - * - * @param loginMethodOrNil The method by which a user logged in, e.g. email, Twitter or Digits. - * @param loginSucceededOrNil The ultimate success or failure of the login - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logLoginWithMethod:(nullable NSString *)loginMethodOrNil - success:(nullable NSNumber *)loginSucceededOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Share event to see users sharing from your app in real-time, letting you - * understand what content they're sharing from the type or genre down to the specific id. - * - * @param shareMethodOrNil The method by which a user shared, e.g. email, Twitter, SMS. - * @param contentNameOrNil The human readable name for this piece of content. - * @param contentTypeOrNil The type of content shared. - * @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logShareWithMethod:(nullable NSString *)shareMethodOrNil - contentName:(nullable NSString *)contentNameOrNil - contentType:(nullable NSString *)contentTypeOrNil - contentId:(nullable NSString *)contentIdOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log an Invite Event to track how users are inviting other users into - * your application. - * - * @param inviteMethodOrNil The method of invitation, e.g. GameCenter, Twitter, email. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logInviteWithMethod:(nullable NSString *)inviteMethodOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Purchase event to see your revenue in real-time, understand how many users are making purchases, see which - * items are most popular, and track plenty of other important purchase-related metrics. - * - * @param itemPriceOrNil The purchased item's price. - * @param currencyOrNil The ISO4217 currency code. Example: USD - * @param purchaseSucceededOrNil Was the purchase succesful or unsuccesful - * @param itemNameOrNil The human-readable form of the item's name. Example: - * @param itemTypeOrNil The type, or genre of the item. Example: Song - * @param itemIdOrNil The machine-readable, unique item identifier Example: SKU - * @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. - */ -+ (void)logPurchaseWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil - currency:(nullable NSString *)currencyOrNil - success:(nullable NSNumber *)purchaseSucceededOrNil - itemName:(nullable NSString *)itemNameOrNil - itemType:(nullable NSString *)itemTypeOrNil - itemId:(nullable NSString *)itemIdOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Level Start Event to track where users are in your game. - * - * @param levelNameOrNil The level name - * @param customAttributesOrNil A dictionary of custom attributes to associate with this level start event. - */ -+ (void)logLevelStart:(nullable NSString *)levelNameOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Level End event to track how users are completing levels in your game. - * - * @param levelNameOrNil The name of the level completed, E.G. "1" or "Training" - * @param scoreOrNil The score the user completed the level with. - * @param levelCompletedSuccesfullyOrNil A boolean representing whether or not the level was completed succesfully. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logLevelEnd:(nullable NSString *)levelNameOrNil - score:(nullable NSNumber *)scoreOrNil - success:(nullable NSNumber *)levelCompletedSuccesfullyOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log an Add to Cart event to see users adding items to a shopping cart in real-time, understand how - * many users start the purchase flow, see which items are most popular, and track plenty of other important - * purchase-related metrics. - * - * @param itemPriceOrNil The purchased item's price. - * @param currencyOrNil The ISO4217 currency code. Example: USD - * @param itemNameOrNil The human-readable form of the item's name. Example: - * @param itemTypeOrNil The type, or genre of the item. Example: Song - * @param itemIdOrNil The machine-readable, unique item identifier Example: SKU - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logAddToCartWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil - currency:(nullable NSString *)currencyOrNil - itemName:(nullable NSString *)itemNameOrNil - itemType:(nullable NSString *)itemTypeOrNil - itemId:(nullable NSString *)itemIdOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Start Checkout event to see users moving through the purchase funnel in real-time, understand how many - * users are doing this and how much they're spending per checkout, and see how it related to other important - * purchase-related metrics. - * - * @param totalPriceOrNil The total price of the cart. - * @param currencyOrNil The ISO4217 currency code. Example: USD - * @param itemCountOrNil The number of items in the cart. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logStartCheckoutWithPrice:(nullable NSDecimalNumber *)totalPriceOrNil - currency:(nullable NSString *)currencyOrNil - itemCount:(nullable NSNumber *)itemCountOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Rating event to see users rating content within your app in real-time and understand what - * content is most engaging, from the type or genre down to the specific id. - * - * @param ratingOrNil The integer rating given by the user. - * @param contentNameOrNil The human readable name for this piece of content. - * @param contentTypeOrNil The type of content shared. - * @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logRating:(nullable NSNumber *)ratingOrNil - contentName:(nullable NSString *)contentNameOrNil - contentType:(nullable NSString *)contentTypeOrNil - contentId:(nullable NSString *)contentIdOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Content View event to see users viewing content within your app in real-time and - * understand what content is most engaging, from the type or genre down to the specific id. - * - * @param contentNameOrNil The human readable name for this piece of content. - * @param contentTypeOrNil The type of content shared. - * @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logContentViewWithName:(nullable NSString *)contentNameOrNil - contentType:(nullable NSString *)contentTypeOrNil - contentId:(nullable NSString *)contentIdOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Search event allows you to see users searching within your app in real-time and understand - * exactly what they're searching for. - * - * @param queryOrNil The user's query. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. - */ -+ (void)logSearchWithQuery:(nullable NSString *)queryOrNil - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -/** - * Log a Custom Event to see user actions that are uniquely important for your app in real-time, to see how often - * they're performing these actions with breakdowns by different categories you add. Use a human-readable name for - * the name of the event, since this is how the event will appear in Answers. - * - * @param eventName The human-readable name for the event. - * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. Attribute keys - * must be NSString and and values must be NSNumber or NSString. - * @discussion How we treat NSNumbers: - * We will provide information about the distribution of values over time. - * - * How we treat NSStrings: - * NSStrings are used as categorical data, allowing comparison across different category values. - * Strings are limited to a maximum length of 100 characters, attributes over this length will be - * truncated. - * - * When tracking the Tweet views to better understand user engagement, sending the tweet's length - * and the type of media present in the tweet allows you to track how tweet length and the type of media influence - * engagement. - */ -+ (void)logCustomEventWithName:(NSString *)eventName - customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Crashlytics.framework/Versions/A/Headers/CLSAttributes.h b/Crashlytics.framework/Versions/A/Headers/CLSAttributes.h deleted file mode 100644 index 1526b0d..0000000 --- a/Crashlytics.framework/Versions/A/Headers/CLSAttributes.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// CLSAttributes.h -// Crashlytics -// -// Copyright (c) 2015 Crashlytics, Inc. All rights reserved. -// - -#pragma once - -#define CLS_DEPRECATED(x) __attribute__ ((deprecated(x))) - -#if !__has_feature(nullability) - #define nonnull - #define nullable - #define _Nullable - #define _Nonnull -#endif - -#ifndef NS_ASSUME_NONNULL_BEGIN - #define NS_ASSUME_NONNULL_BEGIN -#endif - -#ifndef NS_ASSUME_NONNULL_END - #define NS_ASSUME_NONNULL_END -#endif - -#if __has_feature(objc_generics) - #define CLS_GENERIC_NSARRAY(type) NSArray - #define CLS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary -#else - #define CLS_GENERIC_NSARRAY(type) NSArray - #define CLS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary -#endif diff --git a/Crashlytics.framework/Versions/A/Headers/CLSLogging.h b/Crashlytics.framework/Versions/A/Headers/CLSLogging.h deleted file mode 100644 index 59590d5..0000000 --- a/Crashlytics.framework/Versions/A/Headers/CLSLogging.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// CLSLogging.h -// Crashlytics -// -// Copyright (c) 2015 Crashlytics, Inc. All rights reserved. -// -#ifdef __OBJC__ -#import "CLSAttributes.h" -#import - -NS_ASSUME_NONNULL_BEGIN -#endif - - - -/** - * - * The CLS_LOG macro provides as easy way to gather more information in your log messages that are - * sent with your crash data. CLS_LOG prepends your custom log message with the function name and - * line number where the macro was used. If your app was built with the DEBUG preprocessor macro - * defined CLS_LOG uses the CLSNSLog function which forwards your log message to NSLog and CLSLog. - * If the DEBUG preprocessor macro is not defined CLS_LOG uses CLSLog only. - * - * Example output: - * -[AppDelegate login:] line 134 $ login start - * - * If you would like to change this macro, create a new header file, unset our define and then define - * your own version. Make sure this new header file is imported after the Crashlytics header file. - * - * #undef CLS_LOG - * #define CLS_LOG(__FORMAT__, ...) CLSNSLog... - * - **/ -#ifdef __OBJC__ -#ifdef DEBUG -#define CLS_LOG(__FORMAT__, ...) CLSNSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) -#else -#define CLS_LOG(__FORMAT__, ...) CLSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) -#endif -#endif - -/** - * - * Add logging that will be sent with your crash data. This logging will not show up in the system.log - * and will only be visible in your Crashlytics dashboard. - * - **/ - -#ifdef __OBJC__ -OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2); -OBJC_EXTERN void CLSLogv(NSString *format, va_list ap) NS_FORMAT_FUNCTION(1,0); - -/** - * - * Add logging that will be sent with your crash data. This logging will show up in the system.log - * and your Crashlytics dashboard. It is not recommended for Release builds. - * - **/ -OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2); -OBJC_EXTERN void CLSNSLogv(NSString *format, va_list ap) NS_FORMAT_FUNCTION(1,0); - - -NS_ASSUME_NONNULL_END -#endif diff --git a/Crashlytics.framework/Versions/A/Headers/CLSReport.h b/Crashlytics.framework/Versions/A/Headers/CLSReport.h deleted file mode 100644 index 6e3a515..0000000 --- a/Crashlytics.framework/Versions/A/Headers/CLSReport.h +++ /dev/null @@ -1,103 +0,0 @@ -// -// CLSReport.h -// Crashlytics -// -// Copyright (c) 2015 Crashlytics, Inc. All rights reserved. -// - -#import -#import "CLSAttributes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The CLSCrashReport protocol is deprecated. See the CLSReport class and the CrashyticsDelegate changes for details. - **/ -@protocol CLSCrashReport - -@property (nonatomic, copy, readonly) NSString *identifier; -@property (nonatomic, copy, readonly) NSDictionary *customKeys; -@property (nonatomic, copy, readonly) NSString *bundleVersion; -@property (nonatomic, copy, readonly) NSString *bundleShortVersionString; -@property (nonatomic, copy, readonly) NSDate *crashedOnDate; -@property (nonatomic, copy, readonly) NSString *OSVersion; -@property (nonatomic, copy, readonly) NSString *OSBuildVersion; - -@end - -/** - * The CLSReport exposes an interface to the phsyical report that Crashlytics has created. You can - * use this class to get information about the event, and can also set some values after the - * event has occured. - **/ -@interface CLSReport : NSObject - -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; - -/** - * Returns the session identifier for the report. - **/ -@property (nonatomic, copy, readonly) NSString *identifier; - -/** - * Returns the custom key value data for the report. - **/ -@property (nonatomic, copy, readonly) NSDictionary *customKeys; - -/** - * Returns the CFBundleVersion of the application that generated the report. - **/ -@property (nonatomic, copy, readonly) NSString *bundleVersion; - -/** - * Returns the CFBundleShortVersionString of the application that generated the report. - **/ -@property (nonatomic, copy, readonly) NSString *bundleShortVersionString; - -/** - * Returns the date that the report was created. - **/ -@property (nonatomic, copy, readonly) NSDate *dateCreated; - -/** - * Returns the os version that the application crashed on. - **/ -@property (nonatomic, copy, readonly) NSString *OSVersion; - -/** - * Returns the os build version that the application crashed on. - **/ -@property (nonatomic, copy, readonly) NSString *OSBuildVersion; - -/** - * Returns YES if the report contains any crash information, otherwise returns NO. - **/ -@property (nonatomic, assign, readonly) BOOL isCrash; - -/** - * You can use this method to set, after the event, additional custom keys. The rules - * and semantics for this method are the same as those documented in Crashlytics.h. Be aware - * that the maximum size and count of custom keys is still enforced, and you can overwrite keys - * and/or cause excess keys to be deleted by using this method. - **/ -- (void)setObjectValue:(nullable id)value forKey:(NSString *)key; - -/** - * Record an application-specific user identifier. See Crashlytics.h for details. - **/ -@property (nonatomic, copy, nullable) NSString * userIdentifier; - -/** - * Record a user name. See Crashlytics.h for details. - **/ -@property (nonatomic, copy, nullable) NSString * userName; - -/** - * Record a user email. See Crashlytics.h for details. - **/ -@property (nonatomic, copy, nullable) NSString * userEmail; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Crashlytics.framework/Versions/A/Headers/CLSStackFrame.h b/Crashlytics.framework/Versions/A/Headers/CLSStackFrame.h deleted file mode 100644 index cdb5596..0000000 --- a/Crashlytics.framework/Versions/A/Headers/CLSStackFrame.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// CLSStackFrame.h -// Crashlytics -// -// Copyright 2015 Crashlytics, Inc. All rights reserved. -// - -#import -#import "CLSAttributes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * - * This class is used in conjunction with -[Crashlytics recordCustomExceptionName:reason:frameArray:] to - * record information about non-ObjC/C++ exceptions. All information included here will be displayed - * in the Crashlytics UI, and can influence crash grouping. Be particularly careful with the use of the - * address property. If set, Crashlytics will attempt symbolication and could overwrite other properities - * in the process. - * - **/ -@interface CLSStackFrame : NSObject - -+ (instancetype)stackFrame; -+ (instancetype)stackFrameWithAddress:(NSUInteger)address; -+ (instancetype)stackFrameWithSymbol:(NSString *)symbol; - -@property (nonatomic, copy, nullable) NSString *symbol; -@property (nonatomic, copy, nullable) NSString *rawSymbol; -@property (nonatomic, copy, nullable) NSString *library; -@property (nonatomic, copy, nullable) NSString *fileName; -@property (nonatomic, assign) uint32_t lineNumber; -@property (nonatomic, assign) uint64_t offset; -@property (nonatomic, assign) uint64_t address; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Crashlytics.framework/Versions/A/Headers/Crashlytics.h b/Crashlytics.framework/Versions/A/Headers/Crashlytics.h deleted file mode 100644 index 34288f1..0000000 --- a/Crashlytics.framework/Versions/A/Headers/Crashlytics.h +++ /dev/null @@ -1,266 +0,0 @@ -// -// Crashlytics.h -// Crashlytics -// -// Copyright (c) 2015 Crashlytics, Inc. All rights reserved. -// - -#import - -#import "CLSAttributes.h" -#import "CLSLogging.h" -#import "CLSReport.h" -#import "CLSStackFrame.h" -#import "Answers.h" - -NS_ASSUME_NONNULL_BEGIN - -@protocol CrashlyticsDelegate; - -/** - * Crashlytics. Handles configuration and initialization of Crashlytics. - * - * Note: The Crashlytics class cannot be subclassed. If this is causing you pain for - * testing, we suggest using either a wrapper class or a protocol extension. - */ -@interface Crashlytics : NSObject - -@property (nonatomic, readonly, copy) NSString *APIKey; -@property (nonatomic, readonly, copy) NSString *version; -@property (nonatomic, assign) BOOL debugMode; - -/** - * - * The delegate can be used to influence decisions on reporting and behavior, as well as reacting - * to previous crashes. - * - * Make certain that the delegate is setup before starting Crashlytics with startWithAPIKey:... or - * via +[Fabric with:...]. Failure to do will result in missing any delegate callbacks that occur - * synchronously during start. - * - **/ -@property (nonatomic, assign, nullable) id delegate; - -/** - * The recommended way to install Crashlytics into your application is to place a call to +startWithAPIKey: - * in your -application:didFinishLaunchingWithOptions: or -applicationDidFinishLaunching: - * method. - * - * Note: Starting with 3.0, the submission process has been significantly improved. The delay parameter - * is no longer required to throttle submissions on launch, performance will be great without it. - * - * @param apiKey The Crashlytics API Key for this app - * - * @return The singleton Crashlytics instance - */ -+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey; -+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey afterDelay:(NSTimeInterval)delay CLS_DEPRECATED("Crashlytics no longer needs or uses the delay parameter. Please use +startWithAPIKey: instead."); - -/** - * If you need the functionality provided by the CrashlyticsDelegate protocol, you can use - * these convenience methods to activate the framework and set the delegate in one call. - * - * @param apiKey The Crashlytics API Key for this app - * @param delegate A delegate object which conforms to CrashlyticsDelegate. - * - * @return The singleton Crashlytics instance - */ -+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(nullable id)delegate; -+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(nullable id)delegate afterDelay:(NSTimeInterval)delay CLS_DEPRECATED("Crashlytics no longer needs or uses the delay parameter. Please use +startWithAPIKey:delegate: instead."); - -/** - * Access the singleton Crashlytics instance. - * - * @return The singleton Crashlytics instance - */ -+ (Crashlytics *)sharedInstance; - -/** - * The easiest way to cause a crash - great for testing! - */ -- (void)crash; - -/** - * The easiest way to cause a crash with an exception - great for testing. - */ -- (void)throwException; - -/** - * Specify a user identifier which will be visible in the Crashlytics UI. - * - * Many of our customers have requested the ability to tie crashes to specific end-users of their - * application in order to facilitate responses to support requests or permit the ability to reach - * out for more information. We allow you to specify up to three separate values for display within - * the Crashlytics UI - but please be mindful of your end-user's privacy. - * - * We recommend specifying a user identifier - an arbitrary string that ties an end-user to a record - * in your system. This could be a database id, hash, or other value that is meaningless to a - * third-party observer but can be indexed and queried by you. - * - * Optionally, you may also specify the end-user's name or username, as well as email address if you - * do not have a system that works well with obscured identifiers. - * - * Pursuant to our EULA, this data is transferred securely throughout our system and we will not - * disseminate end-user data unless required to by law. That said, if you choose to provide end-user - * contact information, we strongly recommend that you disclose this in your application's privacy - * policy. Data privacy is of our utmost concern. - * - * @param identifier An arbitrary user identifier string which ties an end-user to a record in your system. - */ -- (void)setUserIdentifier:(nullable NSString *)identifier; - -/** - * Specify a user name which will be visible in the Crashlytics UI. - * Please be mindful of your end-user's privacy and see if setUserIdentifier: can fulfil your needs. - * @see setUserIdentifier: - * - * @param name An end user's name. - */ -- (void)setUserName:(nullable NSString *)name; - -/** - * Specify a user email which will be visible in the Crashlytics UI. - * Please be mindful of your end-user's privacy and see if setUserIdentifier: can fulfil your needs. - * - * @see setUserIdentifier: - * - * @param email An end user's email address. - */ -- (void)setUserEmail:(nullable NSString *)email; - -+ (void)setUserIdentifier:(nullable NSString *)identifier CLS_DEPRECATED("Please access this method via +sharedInstance"); -+ (void)setUserName:(nullable NSString *)name CLS_DEPRECATED("Please access this method via +sharedInstance"); -+ (void)setUserEmail:(nullable NSString *)email CLS_DEPRECATED("Please access this method via +sharedInstance"); - -/** - * Set a value for a for a key to be associated with your crash data which will be visible in the Crashlytics UI. - * When setting an object value, the object is converted to a string. This is typically done by calling - * -[NSObject description]. - * - * @param value The object to be associated with the key - * @param key The key with which to associate the value - */ -- (void)setObjectValue:(nullable id)value forKey:(NSString *)key; - -/** - * Set an int value for a key to be associated with your crash data which will be visible in the Crashlytics UI. - * - * @param value The integer value to be set - * @param key The key with which to associate the value - */ -- (void)setIntValue:(int)value forKey:(NSString *)key; - -/** - * Set an BOOL value for a key to be associated with your crash data which will be visible in the Crashlytics UI. - * - * @param value The BOOL value to be set - * @param key The key with which to associate the value - */ -- (void)setBoolValue:(BOOL)value forKey:(NSString *)key; - -/** - * Set an float value for a key to be associated with your crash data which will be visible in the Crashlytics UI. - * - * @param value The float value to be set - * @param key The key with which to associate the value - */ -- (void)setFloatValue:(float)value forKey:(NSString *)key; - -+ (void)setObjectValue:(nullable id)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance"); -+ (void)setIntValue:(int)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance"); -+ (void)setBoolValue:(BOOL)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance"); -+ (void)setFloatValue:(float)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance"); - -/** - * This method can be used to record a single exception structure in a report. This is particularly useful - * when your code interacts with non-native languages like Lua, C#, or Javascript. This call can be - * expensive and should only be used shortly before process termination. This API is not intended be to used - * to log NSException objects. All safely-reportable NSExceptions are automatically captured by - * Crashlytics. - * - * @param name The name of the custom exception - * @param reason The reason this exception occured - * @param frameArray An array of CLSStackFrame objects - */ -- (void)recordCustomExceptionName:(NSString *)name reason:(nullable NSString *)reason frameArray:(CLS_GENERIC_NSARRAY(CLSStackFrame *) *)frameArray; - -/** - * - * This allows you to record a non-fatal event, described by an NSError object. These events will be grouped and - * displayed similarly to crashes. Keep in mind that this method can be expensive. Also, the total number of - * NSErrors that can be recorded during your app's life-cycle is limited by a fixed-size circular buffer. If the - * buffer is overrun, the oldest data is dropped. Errors are relayed to Crashlytics on a subsequent launch - * of your application. - * - * You can also use the -recordError:withAdditionalUserInfo: to include additional context not represented - * by the NSError instance itself. - * - **/ -- (void)recordError:(NSError *)error; -- (void)recordError:(NSError *)error withAdditionalUserInfo:(nullable CLS_GENERIC_NSDICTIONARY(NSString *, id) *)userInfo; - -- (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); -- (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); -+ (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); -+ (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); - -@end - -/** - * - * The CrashlyticsDelegate protocol provides a mechanism for your application to take - * action on events that occur in the Crashlytics crash reporting system. You can make - * use of these calls by assigning an object to the Crashlytics' delegate property directly, - * or through the convenience +startWithAPIKey:delegate: method. - * - */ -@protocol CrashlyticsDelegate -@optional - - -- (void)crashlyticsDidDetectCrashDuringPreviousExecution:(Crashlytics *)crashlytics CLS_DEPRECATED("Please refer to -crashlyticsDidDetectReportForLastExecution:"); -- (void)crashlytics:(Crashlytics *)crashlytics didDetectCrashDuringPreviousExecution:(id )crash CLS_DEPRECATED("Please refer to -crashlyticsDidDetectReportForLastExecution:"); - -/** - * - * Called when a Crashlytics instance has determined that the last execution of the - * application ended in a crash. This is called synchronously on Crashlytics - * initialization. Your delegate must invoke the completionHandler, but does not need to do so - * synchronously, or even on the main thread. Invoking completionHandler with NO will cause the - * detected report to be deleted and not submitted to Crashlytics. This is useful for - * implementing permission prompts, or other more-complex forms of logic around submitting crashes. - * - * @warning Failure to invoke the completionHandler will prevent submissions from being reported. Watch out. - * - * @warning Just implementing this delegate method will disable all forms of synchronous report submission. This can - * impact the reliability of reporting crashes very early in application launch. - * - * @param report The CLSReport object representing the last detected crash - * @param completionHandler The completion handler to call when your logic has completed. - * - */ -- (void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report completionHandler:(void (^)(BOOL submit))completionHandler; - -/** - * If your app is running on an OS that supports it (OS X 10.9+, iOS 7.0+), Crashlytics will submit - * most reports using out-of-process background networking operations. This results in a significant - * improvement in reliability of reporting, as well as power and performance wins for your users. - * If you don't want this functionality, you can disable by returning NO from this method. - * - * @warning Background submission is not supported for extensions on iOS or OS X. - * - * @param crashlytics The Crashlytics singleton instance - * - * @return Return NO if you don't want out-of-process background network operations. - * - */ -- (BOOL)crashlyticsCanUseBackgroundSessions:(Crashlytics *)crashlytics; - -@end - -/** - * `CrashlyticsKit` can be used as a parameter to `[Fabric with:@[CrashlyticsKit]];` in Objective-C. In Swift, use Crashlytics.sharedInstance() - */ -#define CrashlyticsKit [Crashlytics sharedInstance] - -NS_ASSUME_NONNULL_END diff --git a/Crashlytics.framework/Versions/A/Modules/module.modulemap b/Crashlytics.framework/Versions/A/Modules/module.modulemap deleted file mode 100644 index da0845e..0000000 --- a/Crashlytics.framework/Versions/A/Modules/module.modulemap +++ /dev/null @@ -1,14 +0,0 @@ -framework module Crashlytics { - header "Crashlytics.h" - header "Answers.h" - header "ANSCompatibility.h" - header "CLSLogging.h" - header "CLSReport.h" - header "CLSStackFrame.h" - header "CLSAttributes.h" - - export * - - link "z" - link "c++" -} diff --git a/Crashlytics.framework/Versions/A/Resources/Info.plist b/Crashlytics.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index 4860a27..0000000 --- a/Crashlytics.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,53 +0,0 @@ - - - - - BuildMachineOSBuild - 15G31 - CFBundleDevelopmentRegion - English - CFBundleExecutable - Crashlytics - CFBundleIdentifier - com.twitter.crashlytics.mac - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Crashlytics - CFBundlePackageType - FMWK - CFBundleShortVersionString - 3.8.3 - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 120 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 7D1014 - DTPlatformVersion - GM - DTSDKBuild - 15E60 - DTSDKName - macosx10.11 - DTXcode - 0731 - DTXcodeBuild - 7D1014 - NSHumanReadableCopyright - Copyright © 2016 Crashlytics, Inc. All rights reserved. - UIDeviceFamily - - 3 - 2 - 1 - 4 - - - diff --git a/Crashlytics.framework/Versions/Current b/Crashlytics.framework/Versions/Current deleted file mode 120000 index 8c7e5a6..0000000 --- a/Crashlytics.framework/Versions/Current +++ /dev/null @@ -1 +0,0 @@ -A \ No newline at end of file diff --git a/Crashlytics.framework/run b/Crashlytics.framework/run deleted file mode 100755 index 9058ea6..0000000 --- a/Crashlytics.framework/run +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -# run -# -# Copyright (c) 2015 Crashlytics. All rights reserved. - -# Figure out where we're being called from -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - -# Quote path in case of spaces or special chars -DIR="\"${DIR}" - -PATH_SEP="/" -VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script" -UPLOAD_COMMAND="uploadDSYM\" $@ run-script" - -# Ensure params are as expected, run in sync mode to validate -eval $DIR$PATH_SEP$VALIDATE_COMMAND -return_code=$? - -if [[ $return_code != 0 ]]; then - exit $return_code -fi - -# Verification passed, upload dSYM in background to prevent Xcode from waiting -# Note: Validation is performed again before upload. -# Output can still be found in Console.app -eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 & diff --git a/Crashlytics.framework/submit b/Crashlytics.framework/submit deleted file mode 100755 index c05b8e9..0000000 Binary files a/Crashlytics.framework/submit and /dev/null differ diff --git a/Crashlytics.framework/uploadDSYM b/Crashlytics.framework/uploadDSYM deleted file mode 100755 index 6edd046..0000000 Binary files a/Crashlytics.framework/uploadDSYM and /dev/null differ diff --git a/Fabric.framework/Fabric b/Fabric.framework/Fabric deleted file mode 120000 index 4df0d3a..0000000 --- a/Fabric.framework/Fabric +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Fabric \ No newline at end of file diff --git a/Fabric.framework/Headers b/Fabric.framework/Headers deleted file mode 120000 index a177d2a..0000000 --- a/Fabric.framework/Headers +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Headers \ No newline at end of file diff --git a/Fabric.framework/Modules b/Fabric.framework/Modules deleted file mode 120000 index 5736f31..0000000 --- a/Fabric.framework/Modules +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Modules \ No newline at end of file diff --git a/Fabric.framework/Resources b/Fabric.framework/Resources deleted file mode 120000 index 953ee36..0000000 --- a/Fabric.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file diff --git a/Fabric.framework/Versions/A/Fabric b/Fabric.framework/Versions/A/Fabric deleted file mode 100755 index ff72f22..0000000 Binary files a/Fabric.framework/Versions/A/Fabric and /dev/null differ diff --git a/Fabric.framework/Versions/A/Headers/FABAttributes.h b/Fabric.framework/Versions/A/Headers/FABAttributes.h deleted file mode 100644 index 3a9355a..0000000 --- a/Fabric.framework/Versions/A/Headers/FABAttributes.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// FABAttributes.h -// Fabric -// -// Copyright (C) 2015 Twitter, 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. -// - -#pragma once - -#define FAB_UNAVAILABLE(x) __attribute__((unavailable(x))) - -#if !__has_feature(nullability) - #define nonnull - #define nullable - #define _Nullable - #define _Nonnull -#endif - -#ifndef NS_ASSUME_NONNULL_BEGIN - #define NS_ASSUME_NONNULL_BEGIN -#endif - -#ifndef NS_ASSUME_NONNULL_END - #define NS_ASSUME_NONNULL_END -#endif - - -/** - * The following macros are defined here to provide - * backwards compatability. If you are still using - * them you should migrate to the native nullability - * macros. - */ -#define fab_nullable nullable -#define fab_nonnull nonnull -#define FAB_NONNULL __fab_nonnull -#define FAB_NULLABLE __fab_nullable -#define FAB_START_NONNULL NS_ASSUME_NONNULL_BEGIN -#define FAB_END_NONNULL NS_ASSUME_NONNULL_END diff --git a/Fabric.framework/Versions/A/Headers/Fabric.h b/Fabric.framework/Versions/A/Headers/Fabric.h deleted file mode 100644 index ecbdb53..0000000 --- a/Fabric.framework/Versions/A/Headers/Fabric.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// Fabric.h -// Fabric -// -// Copyright (C) 2015 Twitter, 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 -#import "FABAttributes.h" - -NS_ASSUME_NONNULL_BEGIN - -#if TARGET_OS_IPHONE -#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 - #error "Fabric's minimum iOS version is 6.0" -#endif -#else -#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - #error "Fabric's minimum OS X version is 10.7" -#endif -#endif - -/** - * Fabric Base. Coordinates configuration and starts all provided kits. - */ -@interface Fabric : NSObject - -/** - * Initialize Fabric and all provided kits. Call this method within your App Delegate's `application:didFinishLaunchingWithOptions:` and provide the kits you wish to use. - * - * For example, in Objective-C: - * - * `[Fabric with:@[[Crashlytics class], [Twitter class], [Digits class], [MoPub class]]];` - * - * Swift: - * - * `Fabric.with([Crashlytics.self(), Twitter.self(), Digits.self(), MoPub.self()])` - * - * Only the first call to this method is honored. Subsequent calls are no-ops. - * - * @param kitClasses An array of kit Class objects - * - * @return Returns the shared Fabric instance. In most cases this can be ignored. - */ -+ (instancetype)with:(NSArray *)kitClasses; - -/** - * Returns the Fabric singleton object. - */ -+ (instancetype)sharedSDK; - -/** - * This BOOL enables or disables debug logging, such as kit version information. The default value is NO. - */ -@property (nonatomic, assign) BOOL debug; - -/** - * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance. - */ -- (id)init FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance."); - -/** - * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance. - */ -+ (instancetype)new FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance."); - -@end - -NS_ASSUME_NONNULL_END - diff --git a/Fabric.framework/Versions/A/Modules/module.modulemap b/Fabric.framework/Versions/A/Modules/module.modulemap deleted file mode 100644 index 2a31223..0000000 --- a/Fabric.framework/Versions/A/Modules/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module Fabric { - umbrella header "Fabric.h" - - export * - module * { export * } -} \ No newline at end of file diff --git a/Fabric.framework/Versions/A/Resources/Info.plist b/Fabric.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index 239df12..0000000 --- a/Fabric.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,53 +0,0 @@ - - - - - BuildMachineOSBuild - 15G31 - CFBundleDevelopmentRegion - en - CFBundleExecutable - Fabric - CFBundleIdentifier - io.fabric.sdk.mac - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Fabric - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.6.11 - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 60 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 7D1014 - DTPlatformVersion - GM - DTSDKBuild - 15E60 - DTSDKName - macosx10.11 - DTXcode - 0731 - DTXcodeBuild - 7D1014 - NSHumanReadableCopyright - Copyright © 2015 Twitter. All rights reserved. - UIDeviceFamily - - 3 - 2 - 1 - 4 - - - diff --git a/Fabric.framework/Versions/Current b/Fabric.framework/Versions/Current deleted file mode 120000 index 8c7e5a6..0000000 --- a/Fabric.framework/Versions/Current +++ /dev/null @@ -1 +0,0 @@ -A \ No newline at end of file diff --git a/Fabric.framework/run b/Fabric.framework/run deleted file mode 100755 index 9058ea6..0000000 --- a/Fabric.framework/run +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -# run -# -# Copyright (c) 2015 Crashlytics. All rights reserved. - -# Figure out where we're being called from -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - -# Quote path in case of spaces or special chars -DIR="\"${DIR}" - -PATH_SEP="/" -VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script" -UPLOAD_COMMAND="uploadDSYM\" $@ run-script" - -# Ensure params are as expected, run in sync mode to validate -eval $DIR$PATH_SEP$VALIDATE_COMMAND -return_code=$? - -if [[ $return_code != 0 ]]; then - exit $return_code -fi - -# Verification passed, upload dSYM in background to prevent Xcode from waiting -# Note: Validation is performed again before upload. -# Output can still be found in Console.app -eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 & diff --git a/Fabric.framework/uploadDSYM b/Fabric.framework/uploadDSYM deleted file mode 100755 index 6d5888d..0000000 Binary files a/Fabric.framework/uploadDSYM and /dev/null differ diff --git a/PodcastMenu.xcodeproj/project.pbxproj b/PodcastMenu.xcodeproj/project.pbxproj index 49a65f2..8cf7d47 100644 --- a/PodcastMenu.xcodeproj/project.pbxproj +++ b/PodcastMenu.xcodeproj/project.pbxproj @@ -7,12 +7,8 @@ objects = { /* Begin PBXBuildFile section */ - 012E8CCC1FA96F7F00E5FBF9 /* IGListKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 012E8CC91FA96F7E00E5FBF9 /* IGListKit.framework */; }; - 012E8CCD1FA96F7F00E5FBF9 /* IGListKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 012E8CC91FA96F7E00E5FBF9 /* IGListKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 012E8CCE1FA96F7F00E5FBF9 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 012E8CCA1FA96F7E00E5FBF9 /* Sparkle.framework */; }; - 012E8CCF1FA96F7F00E5FBF9 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 012E8CCA1FA96F7E00E5FBF9 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 012E8CD01FA96F7F00E5FBF9 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 012E8CCB1FA96F7F00E5FBF9 /* SwiftyJSON.framework */; }; - 012E8CD11FA96F7F00E5FBF9 /* SwiftyJSON.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 012E8CCB1FA96F7F00E5FBF9 /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03BC67AC6E30884EB7537938 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = D7A5D72BEAA73779E76885F1 /* Sparkle */; }; + B9AA74E0B099D54D01C5756F /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = FC2A1B1DFB5B105BACE82F37 /* SwiftyJSON */; }; DD0BFE3D1CE25D1400446474 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0BFE3C1CE25D1400446474 /* AppDelegate.swift */; }; DD0BFE3F1CE25D1400446474 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DD0BFE3E1CE25D1400446474 /* Assets.xcassets */; }; DD0BFE421CE25D1400446474 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DD0BFE401CE25D1400446474 /* MainMenu.xib */; }; @@ -25,8 +21,6 @@ DD0BFE5B1CE268A500446474 /* OvercastController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0BFE5A1CE268A500446474 /* OvercastController.swift */; }; DD0BFE621CE276CF00446474 /* MediaKeysHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0BFE611CE276CF00446474 /* MediaKeysHandler.swift */; }; DD0BFE671CE27D5400446474 /* overcast.js in Resources */ = {isa = PBXBuildFile; fileRef = DD0BFE661CE27D5400446474 /* overcast.js */; }; - DD0BFE731CE2890000446474 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0BFE711CE2890000446474 /* Fabric.framework */; }; - DD0BFE741CE2890000446474 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0BFE721CE2890000446474 /* Crashlytics.framework */; }; DD13C8B81CE8DE9A002174C4 /* PMEventTap.m in Sources */ = {isa = PBXBuildFile; fileRef = DD13C8B71CE8DE9A002174C4 /* PMEventTap.m */; }; DD13C8BB1CE8E4DE002174C4 /* MediaKeysCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13C8BA1CE8E4DE002174C4 /* MediaKeysCoordinator.swift */; }; DD13C8BD1CE8E587002174C4 /* MediaKeysUsers.plist in Resources */ = {isa = PBXBuildFile; fileRef = DD13C8BC1CE8E587002174C4 /* MediaKeysUsers.plist */; }; @@ -74,26 +68,7 @@ }; /* End PBXContainerItemProxy section */ -/* Begin PBXCopyFilesBuildPhase section */ - 012E8CD21FA96F7F00E5FBF9 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 012E8CCD1FA96F7F00E5FBF9 /* IGListKit.framework in Embed Frameworks */, - 012E8CCF1FA96F7F00E5FBF9 /* Sparkle.framework in Embed Frameworks */, - 012E8CD11FA96F7F00E5FBF9 /* SwiftyJSON.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ - 012E8CC91FA96F7E00E5FBF9 /* IGListKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IGListKit.framework; path = Carthage/Build/Mac/IGListKit.framework; sourceTree = ""; }; - 012E8CCA1FA96F7E00E5FBF9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Carthage/Build/Mac/Sparkle.framework; sourceTree = ""; }; - 012E8CCB1FA96F7F00E5FBF9 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = Carthage/Build/Mac/SwiftyJSON.framework; sourceTree = ""; }; DD0BFE391CE25D1400446474 /* PodcastMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PodcastMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; DD0BFE3C1CE25D1400446474 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; DD0BFE3E1CE25D1400446474 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -108,8 +83,6 @@ DD0BFE5A1CE268A500446474 /* OvercastController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OvercastController.swift; sourceTree = ""; }; DD0BFE611CE276CF00446474 /* MediaKeysHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaKeysHandler.swift; sourceTree = ""; }; DD0BFE661CE27D5400446474 /* overcast.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = overcast.js; sourceTree = ""; }; - DD0BFE711CE2890000446474 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = ""; }; - DD0BFE721CE2890000446474 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = ""; }; DD13C8B61CE8DE9A002174C4 /* PMEventTap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PMEventTap.h; sourceTree = ""; }; DD13C8B71CE8DE9A002174C4 /* PMEventTap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PMEventTap.m; sourceTree = ""; }; DD13C8BA1CE8E4DE002174C4 /* MediaKeysCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaKeysCoordinator.swift; sourceTree = ""; }; @@ -159,12 +132,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 012E8CCC1FA96F7F00E5FBF9 /* IGListKit.framework in Frameworks */, - DD0BFE741CE2890000446474 /* Crashlytics.framework in Frameworks */, - DD0BFE731CE2890000446474 /* Fabric.framework in Frameworks */, - 012E8CCE1FA96F7F00E5FBF9 /* Sparkle.framework in Frameworks */, DD5F6DBC1F7FE93400BC57AE /* DFRFoundation.framework in Frameworks */, - 012E8CD01FA96F7F00E5FBF9 /* SwiftyJSON.framework in Frameworks */, + 03BC67AC6E30884EB7537938 /* Sparkle in Frameworks */, + B9AA74E0B099D54D01C5756F /* SwiftyJSON in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -181,11 +151,6 @@ DD0BFE301CE25D1400446474 = { isa = PBXGroup; children = ( - 012E8CC91FA96F7E00E5FBF9 /* IGListKit.framework */, - 012E8CCA1FA96F7E00E5FBF9 /* Sparkle.framework */, - 012E8CCB1FA96F7F00E5FBF9 /* SwiftyJSON.framework */, - DD0BFE711CE2890000446474 /* Fabric.framework */, - DD0BFE721CE2890000446474 /* Crashlytics.framework */, DD0BFE3B1CE25D1400446474 /* PodcastMenu */, DD6DFF5A1DD6A122004954DE /* PodcastMenuTests */, DD0BFE3A1CE25D1400446474 /* Products */, @@ -399,14 +364,16 @@ DD0BFE351CE25D1400446474 /* Sources */, DD0BFE361CE25D1400446474 /* Frameworks */, DD0BFE371CE25D1400446474 /* Resources */, - DD0BFE701CE288E900446474 /* Crashlytics */, - 012E8CD21FA96F7F00E5FBF9 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( ); name = PodcastMenu; + packageProductDependencies = ( + D7A5D72BEAA73779E76885F1 /* Sparkle */, + FC2A1B1DFB5B105BACE82F37 /* SwiftyJSON */, + ); productName = PodcastMenu; productReference = DD0BFE391CE25D1400446474 /* PodcastMenu.app */; productType = "com.apple.product-type.application"; @@ -435,14 +402,14 @@ DD0BFE311CE25D1400446474 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0810; - LastUpgradeCheck = 0810; + LastSwiftUpdateCheck = 2660; + LastUpgradeCheck = 2660; ORGANIZATIONNAME = "Guilherme Rambo"; TargetAttributes = { DD0BFE381CE25D1400446474 = { CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 0810; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; }; DD6DFF581DD6A122004954DE = { CreatedOnToolsVersion = 8.1; @@ -461,6 +428,10 @@ Base, ); mainGroup = DD0BFE301CE25D1400446474; + packageReferences = ( + 3DC82AD77CF9C595250F97F2 /* XCRemoteSwiftPackageReference "Sparkle" */, + 2FEFD829B7B51BE2BE9532A5 /* XCRemoteSwiftPackageReference "SwiftyJSON" */, + ); productRefGroup = DD0BFE3A1CE25D1400446474 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -500,23 +471,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - DD0BFE701CE288E900446474 /* Crashlytics */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = Crashlytics; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "./Fabric.framework/run 69b44b9b0e1f177a7fb1b6199e9a040897e9dfc0 22ecca766b464658a34a8526d5dad0b7a255f04ed7c47ac02769feb213488d25"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ DD0BFE351CE25D1400446474 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -608,10 +562,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = 8C7439RJLG; + DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -628,7 +583,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -656,10 +611,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = 8C7439RJLG; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -670,7 +626,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -682,8 +638,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -691,17 +647,17 @@ "$(PROJECT_DIR)/lib", "$(PROJECT_DIR)", "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = PodcastMenu/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 11.0; + ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "-D DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = br.com.guilhermerambo.PodcastMenu; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "PodcastMenu/PodcastMenu-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -710,8 +666,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -719,15 +675,14 @@ "$(PROJECT_DIR)/lib", "$(PROJECT_DIR)", "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = PodcastMenu/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 11.0; PRODUCT_BUNDLE_IDENTIFIER = br.com.guilhermerambo.PodcastMenu; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "PodcastMenu/PodcastMenu-Bridging-Header.h"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -737,17 +692,18 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = 8C7439RJLG; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = PodcastMenuTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MACOSX_DEPLOYMENT_TARGET = 11.0; PRODUCT_BUNDLE_IDENTIFIER = br.com.guilhermerambo.PodcastMenuTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PodcastMenu.app/Contents/MacOS/PodcastMenu"; }; name = Debug; @@ -758,15 +714,16 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 8C7439RJLG; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = PodcastMenuTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MACOSX_DEPLOYMENT_TARGET = 11.0; PRODUCT_BUNDLE_IDENTIFIER = br.com.guilhermerambo.PodcastMenuTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PodcastMenu.app/Contents/MacOS/PodcastMenu"; }; name = Release; @@ -802,6 +759,38 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 2FEFD829B7B51BE2BE9532A5 /* XCRemoteSwiftPackageReference "SwiftyJSON" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SwiftyJSON/SwiftyJSON"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.0.0; + }; + }; + 3DC82AD77CF9C595250F97F2 /* XCRemoteSwiftPackageReference "Sparkle" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/sparkle-project/Sparkle"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + D7A5D72BEAA73779E76885F1 /* Sparkle */ = { + isa = XCSwiftPackageProductDependency; + package = 3DC82AD77CF9C595250F97F2 /* XCRemoteSwiftPackageReference "Sparkle" */; + productName = Sparkle; + }; + FC2A1B1DFB5B105BACE82F37 /* SwiftyJSON */ = { + isa = XCSwiftPackageProductDependency; + package = 2FEFD829B7B51BE2BE9532A5 /* XCRemoteSwiftPackageReference "SwiftyJSON" */; + productName = SwiftyJSON; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = DD0BFE311CE25D1400446474 /* Project object */; } diff --git a/PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..b13cd57 --- /dev/null +++ b/PodcastMenu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,24 @@ +{ + "originHash" : "da5af24fe8a5831c01bbd789a35962b7195b59f18658567faeadf9ed817ae89f", + "pins" : [ + { + "identity" : "sparkle", + "kind" : "remoteSourceControl", + "location" : "https://github.com/sparkle-project/Sparkle", + "state" : { + "revision" : "d46d456107feacc80711b21847b82b07bd9fb46e", + "version" : "2.9.3" + } + }, + { + "identity" : "swiftyjson", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftyJSON/SwiftyJSON", + "state" : { + "revision" : "af76cf3ef710b6ca5f8c05f3a31307d44a3c5828", + "version" : "5.0.2" + } + } + ], + "version" : 3 +} diff --git a/PodcastMenu/AppDelegate.swift b/PodcastMenu/AppDelegate.swift index b61fc24..d803e0e 100644 --- a/PodcastMenu/AppDelegate.swift +++ b/PodcastMenu/AppDelegate.swift @@ -9,13 +9,11 @@ import Cocoa import Sparkle -import Fabric -import Crashlytics @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - fileprivate var updater = SUUpdater() + let updaterController = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil) fileprivate var statusItem: NSStatusItem! fileprivate lazy var popoverController = StatusPopoverController() @@ -28,14 +26,13 @@ class AppDelegate: NSObject, NSApplicationDelegate { } func applicationDidFinishLaunching(_ aNotification: Notification) { - Fabric.with([Crashlytics.self]) - - statusItem = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength) + statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) statusItem.image = NSImage(named: "podcast")! statusItem.target = self statusItem.action = #selector(statusItemAction(_:)) statusItem.highlightMode = true - + statusItem.button?.sendAction(on: [.leftMouseUp, .rightMouseUp]) + vuController = VUController(statusItem: statusItem) popoverController.webAppController.loudnessDelegate = vuController @@ -45,9 +42,24 @@ class AppDelegate: NSObject, NSApplicationDelegate { } @objc fileprivate func statusItemAction(_ sender: NSStatusBarButton) { - popoverController.showPopoverFromStatusItemButton(sender) + // Right-click (or control-click) shows a small context menu; left-click opens the player popover. + if let event = NSApp.currentEvent, + event.type == .rightMouseUp || event.modifierFlags.contains(.control) { + let location = NSPoint(x: 0, y: sender.bounds.height + 5) + statusMenu.popUp(positioning: nil, at: location, in: sender) + } else { + popoverController.showPopoverFromStatusItemButton(sender) + } } - + + fileprivate lazy var statusMenu: NSMenu = { + let menu = NSMenu() + let quitItem = NSMenuItem(title: "Quit PodcastMenu", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q") + quitItem.target = NSApp + menu.addItem(quitItem) + return menu + }() + fileprivate func registerURLHandler() { NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(handleURLEvent(_:replyEvent:)), forEventClass: UInt32(kInternetEventClass), andEventID: UInt32(kAEGetURL)) } diff --git a/PodcastMenu/ErrorViewController.swift b/PodcastMenu/ErrorViewController.swift index f49afaf..1b34a84 100644 --- a/PodcastMenu/ErrorViewController.swift +++ b/PodcastMenu/ErrorViewController.swift @@ -17,7 +17,7 @@ class ErrorViewController: NSViewController { init(error: NSError) { self.error = error - super.init(nibName: nil, bundle: nil)! + super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { @@ -41,13 +41,13 @@ class ErrorViewController: NSViewController { fileprivate let reloadButton: NSButton = { let b = NSButton(frame: NSZeroRect) - b.image = NSImage(named: NSImageNameRefreshFreestandingTemplate) + b.image = NSImage(named: NSImage.refreshFreestandingTemplateName) b.setButtonType(.momentaryPushIn) b.isBordered = false - b.bezelStyle = NSBezelStyle.shadowlessSquare + b.bezelStyle = .shadowlessSquare b.sizeToFit() b.translatesAutoresizingMaskIntoConstraints = false - b.appearance = NSAppearance(named: NSAppearanceNameAqua) + b.appearance = NSAppearance(named: .aqua) return b }() @@ -58,7 +58,7 @@ class ErrorViewController: NSViewController { view.layer?.backgroundColor = Theme.Colors.tint.cgColor view.addSubview(errorLabel) - errorLabel.setContentCompressionResistancePriority(NSLayoutPriorityDefaultLow, for: .horizontal) + errorLabel.setContentCompressionResistancePriority(NSLayoutConstraint.Priority.defaultLow, for: .horizontal) errorLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true errorLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: Metrics.errorBarMargin).isActive = true diff --git a/PodcastMenu/ImageCache.swift b/PodcastMenu/ImageCache.swift index 6a2c12b..14721ce 100644 --- a/PodcastMenu/ImageCache.swift +++ b/PodcastMenu/ImageCache.swift @@ -24,8 +24,8 @@ final class ImageCache { class func cacheUrl(for imageUrl: URL) -> URL { let filebase = imageUrl.absoluteString.data(using: .utf8)?.base64EncodedString() ?? UUID().uuidString - let limitIndex = filebase.index(filebase.endIndex, offsetBy: -filebase.characters.count/2) - let finalBase = filebase.substring(from: limitIndex).replacingOccurrences(of: "==", with: "") + let limitIndex = filebase.index(filebase.endIndex, offsetBy: -filebase.count/2) + let finalBase = String(filebase[limitIndex...]).replacingOccurrences(of: "==", with: "") let filename = finalBase + "-" + imageUrl.lastPathComponent let path = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first! + "/" + Bundle.main.bundleIdentifier! + "/ImageCache/" + filename + "-" + imageUrl.lastPathComponent diff --git a/PodcastMenu/Info.plist b/PodcastMenu/Info.plist index 1e7066e..5c1946f 100644 --- a/PodcastMenu/Info.plist +++ b/PodcastMenu/Info.plist @@ -41,20 +41,6 @@ CFBundleVersion 10 - Fabric - - APIKey - 69b44b9b0e1f177a7fb1b6199e9a040897e9dfc0 - Kits - - - KitInfo - - KitName - Crashlytics - - - LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) LSUIElement diff --git a/PodcastMenu/MediaKeysCoordinator.swift b/PodcastMenu/MediaKeysCoordinator.swift index cac014f..6486bec 100644 --- a/PodcastMenu/MediaKeysCoordinator.swift +++ b/PodcastMenu/MediaKeysCoordinator.swift @@ -19,24 +19,24 @@ class MediaKeysCoordinator: NSObject { super.init() - NSWorkspace.shared().addObserver(self, forKeyPath: "frontmostApplication", options: [.initial, .new], context: nil) - NSWorkspace.shared().addObserver(self, forKeyPath: "runningApplications", options: [.initial, .new], context: nil) + NSWorkspace.shared.addObserver(self, forKeyPath: "frontmostApplication", options: [.initial, .new], context: nil) + NSWorkspace.shared.addObserver(self, forKeyPath: "runningApplications", options: [.initial, .new], context: nil) } fileprivate var keysOwnedByAnotherApplication = false - func shouldInterceptMediaKeys() -> Bool { + @objc func shouldInterceptMediaKeys() -> Bool { return keysOwnedByAnotherApplication == false || Preferences.mediaKeysPassthroughEnabled } - - func shouldPassthroughMediaKeysEvents() -> Bool { + + @objc func shouldPassthroughMediaKeysEvents() -> Bool { return Preferences.mediaKeysPassthroughEnabled } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "frontmostApplication" { // if frontmost application is one of the apps listed in mediaKeysUsers, disable media keys handling, if It's our app, reenable if disabled - if let identifier = NSWorkspace.shared().frontmostApplication?.bundleIdentifier { + if let identifier = NSWorkspace.shared.frontmostApplication?.bundleIdentifier { if !keysOwnedByAnotherApplication { if (mediaKeysUsers.contains(identifier)) { keysOwnedByAnotherApplication = true @@ -54,7 +54,7 @@ class MediaKeysCoordinator: NSObject { } } } else if keyPath == "runningApplications" { - if !NSWorkspace.shared().runningApplications.reduce(false, { $0 ? $0 : mediaKeysUsers.contains($1.bundleIdentifier ?? "") }) { + if !NSWorkspace.shared.runningApplications.reduce(false, { $0 ? $0 : mediaKeysUsers.contains($1.bundleIdentifier ?? "") }) { // all media keys users have quit, reclaim media keys keysOwnedByAnotherApplication = false #if DEBUG diff --git a/PodcastMenu/OvercastController.swift b/PodcastMenu/OvercastController.swift index c388e27..ea5f0b9 100644 --- a/PodcastMenu/OvercastController.swift +++ b/PodcastMenu/OvercastController.swift @@ -45,7 +45,7 @@ class OvercastController: NSObject, WKNavigationDelegate { fileprivate func startAutomaticRefresh() { Timer.scheduledTimer(timeInterval: TimeInterval(Constants.automaticRefreshInterval), target: self, selector: #selector(self.refresh(timer:)) , userInfo: nil, repeats: true) - NSWorkspace.shared().notificationCenter.addObserver(forName: Notification.Name.NSWorkspaceDidWake, object: NSWorkspace.shared(), queue: nil) { [weak self] _ in + NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.didWakeNotification, object: NSWorkspace.shared, queue: nil) { [weak self] _ in self?.refreshPodcastsIfNeeded() } } @@ -114,7 +114,7 @@ class OvercastController: NSObject, WKNavigationDelegate { // if the user clicked a link to another website, open with the default browser instead of navigating inside the app guard isValidOvercastURL(URL) else { decision = .cancel - NSWorkspace.shared().open(URL) + NSWorkspace.shared.open(URL) return } } @@ -162,7 +162,7 @@ class OvercastController: NSObject, WKNavigationDelegate { guard !NSApp.isActive else { return } NSAnimationContext.beginGrouping() - NSAnimationContext.current().duration = 0.0 + NSAnimationContext.current.duration = 0.0 webView.window?.orderFrontRegardless() webView.window?.alphaValue = 0.0 NSAnimationContext.endGrouping() @@ -172,7 +172,7 @@ class OvercastController: NSObject, WKNavigationDelegate { guard !NSApp.isActive else { return } NSAnimationContext.beginGrouping() - NSAnimationContext.current().duration = 0.0 + NSAnimationContext.current.duration = 0.0 webView.window?.orderOut(nil) NSAnimationContext.endGrouping() } @@ -271,7 +271,7 @@ class OvercastController: NSObject, WKNavigationDelegate { if let superview = webView.superview { errorViewController.view.frame = NSRect(x: 0.0, y: superview.bounds.height - Metrics.errorBarHeight, width: superview.bounds.width, height: Metrics.errorBarHeight) errorViewController.view.alphaValue = 0.0 - errorViewController.view.autoresizingMask = [.viewWidthSizable, .viewMinYMargin] + errorViewController.view.autoresizingMask = [.width, .minYMargin] superview.addSubview(errorViewController.view) } diff --git a/PodcastMenu/PMEventTap.m b/PodcastMenu/PMEventTap.m index 2a9fd45..2e73658 100644 --- a/PodcastMenu/PMEventTap.m +++ b/PodcastMenu/PMEventTap.m @@ -92,10 +92,21 @@ - (void)start CGEventMask mask = CGEventMaskBit(NSSystemDefined); self.eventPort = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, mask, eventTapCallback, (__bridge void *)self); + + // On modern macOS, CGEventTapCreate returns NULL unless the app has been + // granted Accessibility / Input Monitoring permission. Bail out gracefully + // instead of crashing on a NULL port; media keys simply won't be captured + // until the user grants permission and relaunches. + if (self.eventPort == NULL) { + NSLog(@"[PMEventTap] Could not create event tap. Media-key support needs Input Monitoring permission (System Settings ▸ Privacy & Security ▸ Input Monitoring)."); + return; + } + CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, self.eventPort, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); CGEventTapEnable(self.eventPort, true); CFRunLoopRun(); + if (runLoopSource) CFRelease(runLoopSource); }); } diff --git a/PodcastMenu/PMFreestandingButton.swift b/PodcastMenu/PMFreestandingButton.swift index 20fd4e8..c2672c5 100644 --- a/PodcastMenu/PMFreestandingButton.swift +++ b/PodcastMenu/PMFreestandingButton.swift @@ -28,8 +28,9 @@ class PMFreestandingButton: NSButton { return false } - override class func cellClass() -> AnyClass { - return PMFreestandingButtonCell.self + override class var cellClass: AnyClass? { + get { return PMFreestandingButtonCell.self } + set { } } override var isHighlighted: Bool { @@ -45,7 +46,7 @@ final class PMFreestandingButtonCell: NSButtonCell { override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) { guard let image = image else { return } - guard let ctx = NSGraphicsContext.current()?.cgContext else { return } + guard let ctx = NSGraphicsContext.current?.cgContext else { return } ctx.saveGState() let constrainedWidth: CGFloat diff --git a/PodcastMenu/PMWebView.swift b/PodcastMenu/PMWebView.swift index 5a6f22a..ca6a5a4 100644 --- a/PodcastMenu/PMWebView.swift +++ b/PodcastMenu/PMWebView.swift @@ -22,7 +22,7 @@ class PMWebView: WKWebView { scrollCaptureView.webView = self scrollCaptureView.frame = bounds - scrollCaptureView.autoresizingMask = [.viewWidthSizable, .viewHeightSizable] + scrollCaptureView.autoresizingMask = [.width, .height] subviews[0].addSubview(scrollCaptureView) } diff --git a/PodcastMenu/PodcastWebAppViewController.swift b/PodcastMenu/PodcastWebAppViewController.swift index fe22bd3..4e5a16a 100644 --- a/PodcastMenu/PodcastWebAppViewController.swift +++ b/PodcastMenu/PodcastWebAppViewController.swift @@ -18,7 +18,7 @@ class PodcastWebAppViewController: NSViewController { init() { - super.init(nibName: nil, bundle: nil)! + super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { @@ -34,8 +34,8 @@ class PodcastWebAppViewController: NSViewController { b.translatesAutoresizingMaskIntoConstraints = false b.isBordered = false - b.bezelStyle = NSBezelStyle.inline - b.image = NSImage(named: NSImageNameActionTemplate) + b.bezelStyle = .inline + b.image = NSImage(systemSymbolName: "gearshape", accessibilityDescription: "Options") ?? NSImage(named: NSImage.actionTemplateName) b.toolTip = NSLocalizedString("Options", comment: "Options menu tooltip") b.sendAction(on: .leftMouseDown) b.imagePosition = .imageOnly @@ -51,7 +51,7 @@ class PodcastWebAppViewController: NSViewController { b.translatesAutoresizingMaskIntoConstraints = false b.isBordered = false b.bezelStyle = .inline - b.image = NSImage(named: NSImageNameShareTemplate) + b.image = NSImage(named: NSImage.shareTemplateName) b.toolTip = NSLocalizedString("Share", comment: "Share button tooltip") b.sendAction(on: .leftMouseDown) b.imagePosition = .imageOnly @@ -157,7 +157,7 @@ class PodcastWebAppViewController: NSViewController { func openURL(_ URL: Foundation.URL) { guard overcastController.isValidOvercastURL(URL) else { - NSWorkspace.shared().open(URL) + NSWorkspace.shared.open(URL) return } @@ -257,7 +257,7 @@ class PodcastWebAppViewController: NSViewController { guard let jsString = evalResult as? String else { return } guard let jsData = jsString.data(using: .utf8) else { return } - let result = EpisodesAdapter(input: JSON(data: jsData)).adapt() + let result = EpisodesAdapter(input: JSON(parseJSON: jsString)).adapt() switch result { case .success(let episodes): guard Preferences.notificationsEnabled else { return } @@ -273,7 +273,7 @@ class PodcastWebAppViewController: NSViewController { guard let jsString = evalResult as? String else { return } guard let jsData = jsString.data(using: .utf8) else { return } - let result = PodcastsAdapter(input: JSON(data: jsData)).adapt() + let result = PodcastsAdapter(input: JSON(parseJSON: jsString)).adapt() switch result { case .success(let podcasts): self?.touchBarController.podcasts = podcasts @@ -286,7 +286,7 @@ class PodcastWebAppViewController: NSViewController { guard let jsString = evalResult as? String else { return } guard let jsData = jsString.data(using: .utf8) else { return } - let result = PodcastsAdapter(input: JSON(data: jsData)).adapt() + let result = PodcastsAdapter(input: JSON(parseJSON: jsString)).adapt() switch result { case .success(let podcasts): self?.touchBarController.podcasts = podcasts @@ -311,7 +311,7 @@ class PodcastWebAppViewController: NSViewController { guard let jsString = evalResult as? String else { return } guard let jsData = jsString.data(using: .utf8) else { return } - let result = PlaybackInfoAdapter(input: JSON(data: jsData)).adapt() + let result = PlaybackInfoAdapter(input: JSON(parseJSON: jsString)).adapt() DispatchQueue.main.async { completion(result) @@ -321,7 +321,7 @@ class PodcastWebAppViewController: NSViewController { // MARK: - Playback Info - func propagatePlaybackInfo(_ notification: Notification) { + @objc func propagatePlaybackInfo(_ notification: Notification) { fetchPlaybackInfo { [weak self] result in switch result { case .success(let info): @@ -332,7 +332,7 @@ class PodcastWebAppViewController: NSViewController { } } - func stopPlaybackInfoPropagation(_ notification: Notification) { + @objc func stopPlaybackInfoPropagation(_ notification: Notification) { currentPlaybackInfo = nil #if DEBUG @@ -358,15 +358,15 @@ class PodcastWebAppViewController: NSViewController { let vuItem = NSMenuItem(title: NSLocalizedString("Enable VU Meter", comment: "Enable VU Meter"), action: #selector(toggleReflectAudioLevelInIcon(_:)), keyEquivalent: "") vuItem.target = self - vuItem.state = Preferences.enableVU ? NSOnState : NSOffState + vuItem.state = Preferences.enableVU ? NSControl.StateValue.on : NSControl.StateValue.off let passthroughItem = NSMenuItem(title: NSLocalizedString("Don't Own Media Keys", comment: "Don't Own Media Keys"), action: #selector(toggleMediaKeysPassthrough(_:)), keyEquivalent: "") passthroughItem.target = self - passthroughItem.state = Preferences.mediaKeysPassthroughEnabled ? NSOnState : NSOffState + passthroughItem.state = Preferences.mediaKeysPassthroughEnabled ? NSControl.StateValue.on : NSControl.StateValue.off let enableNotificationsItem = NSMenuItem(title: NSLocalizedString("Enable Notifications", comment: "Enable Notifications"), action: #selector(toggleNotifications(_:)), keyEquivalent: "") enableNotificationsItem.target = self - enableNotificationsItem.state = Preferences.notificationsEnabled ? NSOnState : NSOffState + enableNotificationsItem.state = Preferences.notificationsEnabled ? NSControl.StateValue.on : NSControl.StateValue.off let logOutItem = NSMenuItem(title: NSLocalizedString("Log Out", comment: "Log Out"), action: #selector(logOut(_:)), keyEquivalent: "") logOutItem.target = self @@ -402,22 +402,22 @@ class PodcastWebAppViewController: NSViewController { } @objc fileprivate func toggleReflectAudioLevelInIcon(_ sender: NSMenuItem) { - sender.state = sender.state == NSOnState ? NSOffState : NSOnState - Preferences.enableVU = (sender.state == NSOnState) + sender.state = sender.state == NSControl.StateValue.on ? NSControl.StateValue.off : NSControl.StateValue.on + Preferences.enableVU = (sender.state == NSControl.StateValue.on) } @objc fileprivate func toggleMediaKeysPassthrough(_ sender: NSMenuItem) { - sender.state = sender.state == NSOnState ? NSOffState : NSOnState - Preferences.mediaKeysPassthroughEnabled = (sender.state == NSOnState) + sender.state = sender.state == NSControl.StateValue.on ? NSControl.StateValue.off : NSControl.StateValue.on + Preferences.mediaKeysPassthroughEnabled = (sender.state == NSControl.StateValue.on) } @objc fileprivate func toggleNotifications(_ sender: NSMenuItem) { - sender.state = sender.state == NSOnState ? NSOffState : NSOnState - Preferences.enableNotifications = (sender.state == NSOnState) + sender.state = sender.state == NSControl.StateValue.on ? NSControl.StateValue.off : NSControl.StateValue.on + Preferences.notificationsEnabled = (sender.state == NSControl.StateValue.on) } @objc fileprivate func checkForUpdates(_ sender: NSMenuItem) { - SUUpdater.shared().checkForUpdates(sender) + (NSApp.delegate as? AppDelegate)?.updaterController.checkForUpdates(sender) } @objc fileprivate func logOut(_ sender: NSMenuItem) { @@ -490,10 +490,10 @@ private enum ConfigMenuItem: Int { case logOut = 101 } -extension PodcastWebAppViewController: NSMenuDelegate { - - override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { - guard let item = ConfigMenuItem(rawValue: menuItem.tag) else { +extension PodcastWebAppViewController: NSMenuDelegate, NSMenuItemValidation { + + func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { + guard let item = ConfigMenuItem(rawValue: Int(menuItem.tag)) else { return true } diff --git a/PodcastMenu/StatusPopoverController.swift b/PodcastMenu/StatusPopoverController.swift index 17632d7..766000c 100644 --- a/PodcastMenu/StatusPopoverController.swift +++ b/PodcastMenu/StatusPopoverController.swift @@ -42,14 +42,14 @@ class StatusPopoverController: NSObject { fileprivate func installApplicationTerminationListener() { let delayTime = DispatchTime.now() + Double(Int64(2 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) DispatchQueue.main.asyncAfter(deadline: delayTime) { - NotificationCenter.default.addObserver(self, selector: #selector(StatusPopoverController.closePopover), name: NSNotification.Name.NSApplicationDidResignActive, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(StatusPopoverController.closePopover), name: NSApplication.didResignActiveNotification, object: nil) } } fileprivate func updatePopoverAppearance() { guard let popover = popover else { return } - popover.appearance = Theme.isDark ? NSAppearance(named: NSAppearanceNameVibrantDark) : nil + popover.appearance = Theme.isDark ? NSAppearance(named: .vibrantDark) : nil } @objc fileprivate func closePopover() { diff --git a/PodcastMenu/Theme.swift b/PodcastMenu/Theme.swift index 456ae5b..580a758 100644 --- a/PodcastMenu/Theme.swift +++ b/PodcastMenu/Theme.swift @@ -33,7 +33,7 @@ class Theme: NSObject { } static var appearance: NSAppearance? { - return isDark ? NSAppearance(named: NSAppearanceNameVibrantDark) : NSAppearance(named: NSAppearanceNameAqua) + return isDark ? NSAppearance(named: .vibrantDark) : NSAppearance(named: .aqua) } override init() { diff --git a/PodcastMenu/TouchBarController.swift b/PodcastMenu/TouchBarController.swift index 3580995..e61f1e2 100644 --- a/PodcastMenu/TouchBarController.swift +++ b/PodcastMenu/TouchBarController.swift @@ -59,12 +59,12 @@ class TouchBarController: NSObject { @available(OSX 10.12.2, *) lazy var backButton: NSButton = { - return NSButton(title: "", image: NSImage(named: NSImageNameTouchBarGoBackTemplate)!, target: nil, action: #selector(WKWebView.goBack(_:))) + return NSButton(title: "", image: NSImage(named: NSImage.touchBarGoBackTemplateName)!, target: nil, action: #selector(WKWebView.goBack(_:))) }() @available(OSX 10.12.2, *) lazy var forwardButton: NSButton = { - return NSButton(title: "", image: NSImage(named: NSImageNameTouchBarGoForwardTemplate)!, target: nil, action: #selector(WKWebView.goForward(_:))) + return NSButton(title: "", image: NSImage(named: NSImage.touchBarGoForwardTemplateName)!, target: nil, action: #selector(WKWebView.goForward(_:))) }() override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { @@ -103,7 +103,7 @@ class TouchBarController: NSObject { nowPlayingItem.view = NSButton(image: #imageLiteral(resourceName: "controlStripIcon"), target: self, action: #selector(nowPlayingItemActivated)) NSTouchBarItem.addSystemTrayItem(nowPlayingItem) - DFRElementSetControlStripPresenceForIdentifier(NSTouchBarItemIdentifier.nowPlayingControlStrip.rawValue, true); + DFRElementSetControlStripPresenceForIdentifier(NSTouchBarItem.Identifier.nowPlayingControlStrip.rawValue, true); } @available(OSX 10.12.2, *) @@ -113,12 +113,12 @@ class TouchBarController: NSObject { @available(OSX 10.12.2, *) func showTouchBar() { - NSTouchBar.presentSystemModalFunctionBar(nowPlayingTouchBar, placement: 0, systemTrayItemIdentifier: "otherTouchBar") + NSTouchBar.presentSystemModalTouchBar(nowPlayingTouchBar, placement: 0, systemTrayItemIdentifier: "otherTouchBar") } @available(OSX 10.12.2, *) func hideTouchBar() { - NSTouchBar.dismissSystemModalFunctionBar(nowPlayingTouchBar) + NSTouchBar.dismissSystemModalTouchBar(nowPlayingTouchBar) } @available(OSX 10.12.2, *) @@ -134,28 +134,28 @@ class TouchBarController: NSObject { } @available(OSX 10.12.2, *) -extension NSTouchBarItemIdentifier { - static let backButton = NSTouchBarItemIdentifier("br.com.guilhermerambo.podcastmenu.back") - static let forwardButton = NSTouchBarItemIdentifier("br.com.guilhermerambo.podcastmenu.forward") - static let scrubber = NSTouchBarItemIdentifier("br.com.guilhermerambo.podcastmenu.scrubber") - static let nowPlayingControlStrip = NSTouchBarItemIdentifier("br.com.guilhermerambo.podcastmenu.nowPlaying") - static let miniPlayer = NSTouchBarItemIdentifier("br.com.guilhermerambo.podcastmenu.miniPlayer") +extension NSTouchBarItem.Identifier { + static let backButton = NSTouchBarItem.Identifier("br.com.guilhermerambo.podcastmenu.back") + static let forwardButton = NSTouchBarItem.Identifier("br.com.guilhermerambo.podcastmenu.forward") + static let scrubber = NSTouchBarItem.Identifier("br.com.guilhermerambo.podcastmenu.scrubber") + static let nowPlayingControlStrip = NSTouchBarItem.Identifier("br.com.guilhermerambo.podcastmenu.nowPlaying") + static let miniPlayer = NSTouchBarItem.Identifier("br.com.guilhermerambo.podcastmenu.miniPlayer") } @available(OSX 10.12.2, *) extension TouchBarController: NSTouchBarDelegate { - func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? { + func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? { switch identifier { - case NSTouchBarItemIdentifier.backButton: + case NSTouchBarItem.Identifier.backButton: let item = NSCustomTouchBarItem(identifier: .backButton) item.view = backButton return item - case NSTouchBarItemIdentifier.forwardButton: + case NSTouchBarItem.Identifier.forwardButton: let item = NSCustomTouchBarItem(identifier: .forwardButton) item.view = forwardButton return item - case NSTouchBarItemIdentifier.scrubber: + case NSTouchBarItem.Identifier.scrubber: let item = NSCustomTouchBarItem(identifier: .scrubber) item.viewController = scrubberController return item diff --git a/PodcastMenu/TouchBarMiniPlayer.swift b/PodcastMenu/TouchBarMiniPlayer.swift index f1b9fc5..c01cac5 100644 --- a/PodcastMenu/TouchBarMiniPlayer.swift +++ b/PodcastMenu/TouchBarMiniPlayer.swift @@ -18,13 +18,13 @@ final class TouchBarMiniPlayer: NSTouchBar { fatalError("Missing required nib \(nibName), bundle is probably damaged") } - var nibObjects = NSArray() - + var nibObjects: NSArray? + guard nib.instantiate(withOwner: nil, topLevelObjects: &nibObjects) else { fatalError("Unable to load nib, something is seriously wrong") } - - return nibObjects.first(where: { $0 is TouchBarMiniPlayer }) as! TouchBarMiniPlayer + + return nibObjects?.first(where: { $0 is TouchBarMiniPlayer }) as! TouchBarMiniPlayer } override func awakeFromNib() { diff --git a/PodcastMenu/TouchBarPrivate.h b/PodcastMenu/TouchBarPrivate.h index 38d629c..b46208c 100644 --- a/PodcastMenu/TouchBarPrivate.h +++ b/PodcastMenu/TouchBarPrivate.h @@ -20,7 +20,7 @@ extern void DFRSystemModalShowsCloseBoxWhenFrontMost(BOOL); @interface NSTouchBar (Private) -+ (void)presentSystemModalFunctionBar:(NSTouchBar *__nonnull)touchBar placement:(long long)placement systemTrayItemIdentifier:(NSString *__nonnull)identifier; -+ (void)dismissSystemModalFunctionBar:(NSTouchBar *__nonnull)touchBar; ++ (void)presentSystemModalTouchBar:(NSTouchBar *__nonnull)touchBar placement:(long long)placement systemTrayItemIdentifier:(NSString *__nonnull)identifier; ++ (void)dismissSystemModalTouchBar:(NSTouchBar *__nonnull)touchBar; @end diff --git a/PodcastMenu/TouchBarScrubberViewController.swift b/PodcastMenu/TouchBarScrubberViewController.swift index aa5e018..e3e18c5 100644 --- a/PodcastMenu/TouchBarScrubberViewController.swift +++ b/PodcastMenu/TouchBarScrubberViewController.swift @@ -42,7 +42,7 @@ class TouchBarScrubberViewController: NSViewController { weak var delegate: TouchBarScrubberViewControllerDelegate? init() { - super.init(nibName: nil, bundle: nil)! + super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { @@ -57,7 +57,7 @@ class TouchBarScrubberViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() - scrubber.register(ScrubberRemoteImageItemView.self, forItemIdentifier: Constants.itemIdentifier) + scrubber.register(ScrubberRemoteImageItemView.self, forItemIdentifier: NSUserInterfaceItemIdentifier(Constants.itemIdentifier)) } var currentEpisodeTitle: String? = nil { @@ -112,7 +112,7 @@ class TouchBarScrubberViewController: NSViewController { s.showsAdditionalContentIndicators = true s.dataSource = self s.delegate = self - s.autoresizingMask = [.viewWidthSizable, .viewHeightSizable] + s.autoresizingMask = [.width, .height] return s }() @@ -131,12 +131,12 @@ extension TouchBarScrubberViewController: NSScrubberDataSource, NSScrubberDelega } func scrubber(_ scrubber: NSScrubber, viewForItemAt index: Int) -> NSScrubberItemView { - var item = scrubber.makeItem(withIdentifier: Constants.itemIdentifier, owner: scrubber) as? ScrubberRemoteImageItemView - + var item = scrubber.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(Constants.itemIdentifier), owner: scrubber) as? ScrubberRemoteImageItemView + if item == nil { item = ScrubberRemoteImageItemView() - item?.identifier = Constants.itemIdentifier - item?.imageAlignment = .alignTop + item?.identifier = NSUserInterfaceItemIdentifier(Constants.itemIdentifier) + item?.imageAlignment = NSImageAlignment.alignTop } item?.indexInScrubber = index diff --git a/PodcastMenu/VUController.swift b/PodcastMenu/VUController.swift index ee87005..155d6c2 100644 --- a/PodcastMenu/VUController.swift +++ b/PodcastMenu/VUController.swift @@ -39,7 +39,7 @@ class VUController: OvercastLoudnessDelegate { image.lockFocus() - let ctx = NSGraphicsContext.current()!.cgContext + let ctx = NSGraphicsContext.current!.cgContext let maskBounds = CGRect(x: 0.0, y: 0.0, width: w, height: h) ctx.clip(to: maskBounds, mask: baseImageCG) diff --git a/Readme.md b/Readme.md index 3484196..d2d6f82 100644 --- a/Readme.md +++ b/Readme.md @@ -25,7 +25,11 @@ NOTE: This app is free and open source but its license prohibits anyone from dis ## Compatibility -PodcastMenu is only available for OS X 10.11 or later. +PodcastMenu runs natively on both Apple Silicon and Intel Macs (universal binary) and requires macOS 11 (Big Sur) or later. + +## Building + +Dependencies are managed with Swift Package Manager and resolve automatically when you open the project in Xcode — just open `PodcastMenu.xcodeproj` and build. (Earlier versions used Carthage; that is no longer required.) # Get Overcast diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100755 index 0d7e03b..0000000 --- a/bootstrap.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -carthage bootstrap --platform macOS