├── .gitignore ├── .gitmodules ├── HockeySDK-iOS ├── BuildAgent ├── HockeySDK.embeddedframework │ ├── HockeySDK.framework │ │ ├── Headers │ │ │ ├── BITAuthenticator.h │ │ │ ├── BITCrashAttachment.h │ │ │ ├── BITCrashDetails.h │ │ │ ├── BITCrashManager.h │ │ │ ├── BITCrashManagerDelegate.h │ │ │ ├── BITCrashMetaData.h │ │ │ ├── BITHockeyAttachment.h │ │ │ ├── BITHockeyBaseManager.h │ │ │ ├── BITHockeyBaseViewController.h │ │ │ ├── BITHockeyManager.h │ │ │ ├── BITHockeyManagerDelegate.h │ │ │ ├── BITMetricsManager.h │ │ │ ├── BITStoreUpdateManager.h │ │ │ ├── BITStoreUpdateManagerDelegate.h │ │ │ ├── BITUpdateManager.h │ │ │ ├── BITUpdateManagerDelegate.h │ │ │ ├── BITUpdateViewController.h │ │ │ ├── HockeySDK.h │ │ │ ├── HockeySDKEnums.h │ │ │ ├── HockeySDKFeatureConfig.h │ │ │ └── HockeySDKNullability.h │ │ ├── HockeySDK │ │ └── Modules │ │ │ └── module.modulemap │ └── HockeySDKResources.bundle │ │ ├── AppIconPlaceHolder.png │ │ ├── Arrow.png │ │ ├── Arrow@2x.png │ │ ├── Arrow@3x.png │ │ ├── Blur.png │ │ ├── Blur@2x.png │ │ ├── Blur@3x.png │ │ ├── Cancel.png │ │ ├── Cancel@2x.png │ │ ├── Cancel@3x.png │ │ ├── FeedbackPlaceholder.png │ │ ├── IconGradient.png │ │ ├── IconGradient@2x.png │ │ ├── Info.plist │ │ ├── Ok.png │ │ ├── Ok@2x.png │ │ ├── Ok@3x.png │ │ ├── Rectangle.png │ │ ├── Rectangle@2x.png │ │ ├── Rectangle@3x.png │ │ ├── authorize_denied.png │ │ ├── authorize_denied@2x.png │ │ ├── authorize_denied@3x.png │ │ ├── bg.png │ │ ├── buttonRoundedDelete.png │ │ ├── buttonRoundedDelete@2x.png │ │ ├── buttonRoundedDeleteHighlighted.png │ │ ├── buttonRoundedDeleteHighlighted@2x.png │ │ ├── buttonRoundedRegular.png │ │ ├── buttonRoundedRegular@2x.png │ │ ├── buttonRoundedRegularHighlighted.png │ │ ├── buttonRoundedRegularHighlighted@2x.png │ │ ├── de.lproj │ │ └── HockeySDK.strings │ │ ├── en.lproj │ │ └── HockeySDK.strings │ │ ├── es.lproj │ │ └── HockeySDK.strings │ │ ├── fa.lproj │ │ └── HockeySDK.strings │ │ ├── feedbackActivity.png │ │ ├── feedbackActivity@2x.png │ │ ├── feedbackActivity@2x~ipad.png │ │ ├── feedbackActivity@3x.png │ │ ├── feedbackActivity~ipad.png │ │ ├── fr.lproj │ │ └── HockeySDK.strings │ │ ├── hr.lproj │ │ └── HockeySDK.strings │ │ ├── hu.lproj │ │ └── HockeySDK.strings │ │ ├── iconCamera.png │ │ ├── iconCamera@2x.png │ │ ├── it.lproj │ │ └── HockeySDK.strings │ │ ├── ja.lproj │ │ └── HockeySDK.strings │ │ ├── nb.lproj │ │ └── HockeySDK.strings │ │ ├── nl.lproj │ │ └── HockeySDK.strings │ │ ├── pt-PT.lproj │ │ └── HockeySDK.strings │ │ ├── pt.lproj │ │ └── HockeySDK.strings │ │ ├── ru.lproj │ │ └── HockeySDK.strings │ │ └── zh-Hans.lproj │ │ └── HockeySDK.strings └── LICENSE ├── Icon ├── Icon-60.png ├── Icon-60@2x.png ├── Icon-60@3x.png ├── Icon-72.png ├── Icon-72@2x.png ├── Icon-76.png ├── Icon-76@2x.png ├── Icon-76@3x.png ├── Icon-Small-50.png ├── Icon-Small-50@2x.png ├── Icon-Small.png ├── Icon-Small@2x.png ├── Icon-Small@3x.png ├── Icon-Spotlight-40.png ├── Icon-Spotlight-40@2x.png ├── Icon-Spotlight-40@3x.png ├── Icon-iPadPro@2x.png ├── Icon.png └── Icon@2x.png ├── README.md ├── screenshots ├── 5.5-inch │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png ├── large │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png └── small │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png ├── standardnotes-Bridging-Header.h ├── standardnotes.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── standardnotes.xcscmblueprint │ └── xcuserdata │ │ ├── mo.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── mobitar.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── mo.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ ├── standardnotes.xcscheme │ │ └── xcschememanagement.plist │ └── mobitar.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── standardnotes.xcscheme │ └── xcschememanagement.plist └── standardnotes ├── AccountViewController.swift ├── ApiController.swift ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ ├── Icon-60.png │ ├── Icon-60@2x.png │ ├── Icon-60@3x.png │ ├── Icon-72.png │ ├── Icon-72@2x.png │ ├── Icon-76.png │ ├── Icon-76@2x.png │ ├── Icon-76@3x.png │ ├── Icon-Small-50.png │ ├── Icon-Small-50@2x.png │ ├── Icon-Small.png │ ├── Icon-Small@2x copy.png │ ├── Icon-Small@2x.png │ ├── Icon-Small@3x.png │ ├── Icon-Spotlight-40.png │ ├── Icon-Spotlight-40@2x copy.png │ ├── Icon-Spotlight-40@2x.png │ ├── Icon-Spotlight-40@3x.png │ ├── Icon-iPadPro@2x.png │ ├── Icon.png │ └── Icon@2x.png ├── Contents.json ├── ico-account.imageset │ ├── Contents.json │ ├── ico-account@2x.png │ └── ico-account@3x.png └── ico-list.imageset │ ├── Contents.json │ ├── ico-list@2x.png │ └── ico-list@3x.png ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── ComposeViewController.swift ├── Crypto.swift ├── EncryptionViewController.swift ├── Info.plist ├── Item+CoreDataClass.swift ├── Item+CoreDataProperties.swift ├── ItemManager.swift ├── LockedViewController.swift ├── NSData+Crypto.h ├── NSData+Crypto.m ├── Note+CoreDataClass.swift ├── Note+CoreDataProperties.swift ├── Note.swift ├── NoteTableViewCell.swift ├── NotesViewController.swift ├── SyncController.swift ├── TabBarViewController.swift ├── Tag+CoreDataClass.swift ├── Tag+CoreDataProperties.swift ├── TagTableViewCell.swift ├── TagsViewController.swift ├── Theme.swift ├── UserManager.swift ├── ViewController+Util.swift └── standardnotes.xcdatamodeld ├── .xccurrentversion └── standardnotes.xcdatamodel └── contents /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata/ 3 | .xcuserstate 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/Alamofire"] 2 | path = vendor/Alamofire 3 | url = https://github.com/Alamofire/Alamofire.git 4 | [submodule "vendor/SwiftyJSON"] 5 | path = vendor/SwiftyJSON 6 | url = https://github.com/SwiftyJSON/SwiftyJSON.git 7 | -------------------------------------------------------------------------------- /HockeySDK-iOS/BuildAgent: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/BuildAgent -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITCrashAttachment.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import "BITHockeyAttachment.h" 30 | 31 | /** 32 | Deprecated: Provides support to add binary attachments to crash reports 33 | 34 | This class is not needed any longer and exists for compatibility purposes with 35 | HockeySDK-iOS 3.5.5. 36 | 37 | It is a subclass of `BITHockeyAttachment` which only provides an initializer 38 | that is compatible with the one of HockeySDK-iOS 3.5.5. 39 | 40 | This is used by `[BITCrashManagerDelegate attachmentForCrashManager:]` 41 | 42 | @see BITHockeyAttachment 43 | */ 44 | @interface BITCrashAttachment : BITHockeyAttachment 45 | 46 | /** 47 | Create an BITCrashAttachment instance with a given filename and NSData object 48 | 49 | @param filename The filename the attachment should get 50 | @param crashAttachmentData The attachment data as NSData 51 | @param contentType The content type of your data as MIME type 52 | 53 | @return An instance of BITCrashAttachment 54 | */ 55 | - (instancetype)initWithFilename:(NSString *)filename 56 | crashAttachmentData:(NSData *)crashAttachmentData 57 | contentType:(NSString *)contentType; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITCrashDetails.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | /** 32 | * Provides details about the crash that occurred in the previous app session 33 | */ 34 | @interface BITCrashDetails : NSObject 35 | 36 | /** 37 | * UUID for the crash report 38 | */ 39 | @property (nonatomic, readonly, strong) NSString *incidentIdentifier; 40 | 41 | /** 42 | * UUID for the app installation on the device 43 | */ 44 | @property (nonatomic, readonly, strong) NSString *reporterKey; 45 | 46 | /** 47 | * Signal that caused the crash 48 | */ 49 | @property (nonatomic, readonly, strong) NSString *signal; 50 | 51 | /** 52 | * Exception name that triggered the crash, nil if the crash was not caused by an exception 53 | */ 54 | @property (nonatomic, readonly, strong) NSString *exceptionName; 55 | 56 | /** 57 | * Exception reason, nil if the crash was not caused by an exception 58 | */ 59 | @property (nonatomic, readonly, strong) NSString *exceptionReason; 60 | 61 | /** 62 | * Date and time the app started, nil if unknown 63 | */ 64 | @property (nonatomic, readonly, strong) NSDate *appStartTime; 65 | 66 | /** 67 | * Date and time the crash occurred, nil if unknown 68 | */ 69 | @property (nonatomic, readonly, strong) NSDate *crashTime; 70 | 71 | /** 72 | * Operation System version string the app was running on when it crashed. 73 | */ 74 | @property (nonatomic, readonly, strong) NSString *osVersion; 75 | 76 | /** 77 | * Operation System build string the app was running on when it crashed 78 | * 79 | * This may be unavailable. 80 | */ 81 | @property (nonatomic, readonly, strong) NSString *osBuild; 82 | 83 | /** 84 | * CFBundleShortVersionString value of the app that crashed 85 | * 86 | * Can be `nil` if the crash was captured with an older version of the SDK 87 | * or if the app doesn't set the value. 88 | */ 89 | @property (nonatomic, readonly, strong) NSString *appVersion; 90 | 91 | /** 92 | * CFBundleVersion value of the app that crashed 93 | */ 94 | @property (nonatomic, readonly, strong) NSString *appBuild; 95 | 96 | /** 97 | * Identifier of the app process that crashed 98 | */ 99 | @property (nonatomic, readonly, assign) NSUInteger appProcessIdentifier; 100 | 101 | /** 102 | Indicates if the app was killed while being in foreground from the iOS 103 | 104 | If `[BITCrashManager enableAppNotTerminatingCleanlyDetection]` is enabled, use this on startup 105 | to check if the app starts the first time after it was killed by iOS in the previous session. 106 | 107 | This can happen if it consumed too much memory or the watchdog killed the app because it 108 | took too long to startup or blocks the main thread for too long, or other reasons. See Apple 109 | documentation: https://developer.apple.com/library/ios/qa/qa1693/_index.html 110 | 111 | See `[BITCrashManager enableAppNotTerminatingCleanlyDetection]` for more details about which kind of kills can be detected. 112 | 113 | @warning This property only has a correct value, once `[BITHockeyManager startManager]` was 114 | invoked! In addition, it is automatically disabled while a debugger session is active! 115 | 116 | @see `[BITCrashManager enableAppNotTerminatingCleanlyDetection]` 117 | @see `[BITCrashManager didReceiveMemoryWarningInLastSession]` 118 | 119 | @return YES if the details represent an app kill instead of a crash 120 | */ 121 | - (BOOL)isAppKill; 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITCrashManagerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | @class BITCrashManager; 32 | @class BITHockeyAttachment; 33 | 34 | /** 35 | The `BITCrashManagerDelegate` formal protocol defines methods further configuring 36 | the behaviour of `BITCrashManager`. 37 | */ 38 | 39 | @protocol BITCrashManagerDelegate 40 | 41 | @optional 42 | 43 | 44 | ///----------------------------------------------------------------------------- 45 | /// @name Additional meta data 46 | ///----------------------------------------------------------------------------- 47 | 48 | /** Return any log string based data the crash report being processed should contain 49 | 50 | @param crashManager The `BITCrashManager` instance invoking this delegate 51 | @see attachmentForCrashManager: 52 | @see BITHockeyManagerDelegate userNameForHockeyManager:componentManager: 53 | @see BITHockeyManagerDelegate userEmailForHockeyManager:componentManager: 54 | */ 55 | -(NSString *)applicationLogForCrashManager:(BITCrashManager *)crashManager; 56 | 57 | 58 | /** Return a BITHockeyAttachment object providing an NSData object the crash report 59 | being processed should contain 60 | 61 | Please limit your attachments to reasonable files to avoid high traffic costs for your users. 62 | 63 | Example implementation: 64 | 65 | - (BITHockeyAttachment *)attachmentForCrashManager:(BITCrashManager *)crashManager { 66 | NSData *data = [NSData dataWithContentsOfURL:@"mydatafile"]; 67 | 68 | BITHockeyAttachment *attachment = [[BITHockeyAttachment alloc] initWithFilename:@"myfile.data" 69 | hockeyAttachmentData:data 70 | contentType:@"'application/octet-stream"]; 71 | return attachment; 72 | } 73 | 74 | @param crashManager The `BITCrashManager` instance invoking this delegate 75 | @see BITHockeyAttachment 76 | @see applicationLogForCrashManager: 77 | @see BITHockeyManagerDelegate userNameForHockeyManager:componentManager: 78 | @see BITHockeyManagerDelegate userEmailForHockeyManager:componentManager: 79 | */ 80 | -(BITHockeyAttachment *)attachmentForCrashManager:(BITCrashManager *)crashManager; 81 | 82 | 83 | 84 | ///----------------------------------------------------------------------------- 85 | /// @name Alert 86 | ///----------------------------------------------------------------------------- 87 | 88 | /** Invoked before the user is asked to send a crash report, so you can do additional actions. 89 | E.g. to make sure not to ask the user for an app rating :) 90 | 91 | @param crashManager The `BITCrashManager` instance invoking this delegate 92 | */ 93 | -(void)crashManagerWillShowSubmitCrashReportAlert:(BITCrashManager *)crashManager; 94 | 95 | 96 | /** Invoked after the user did choose _NOT_ to send a crash in the alert 97 | 98 | @param crashManager The `BITCrashManager` instance invoking this delegate 99 | */ 100 | -(void)crashManagerWillCancelSendingCrashReport:(BITCrashManager *)crashManager; 101 | 102 | 103 | /** Invoked after the user did choose to send crashes always in the alert 104 | 105 | @param crashManager The `BITCrashManager` instance invoking this delegate 106 | */ 107 | -(void)crashManagerWillSendCrashReportsAlways:(BITCrashManager *)crashManager; 108 | 109 | 110 | ///----------------------------------------------------------------------------- 111 | /// @name Networking 112 | ///----------------------------------------------------------------------------- 113 | 114 | /** Invoked right before sending crash reports will start 115 | 116 | @param crashManager The `BITCrashManager` instance invoking this delegate 117 | */ 118 | - (void)crashManagerWillSendCrashReport:(BITCrashManager *)crashManager; 119 | 120 | /** Invoked after sending crash reports failed 121 | 122 | @param crashManager The `BITCrashManager` instance invoking this delegate 123 | @param error The error returned from the NSURLConnection/NSURLSession call or `kBITCrashErrorDomain` 124 | with reason of type `BITCrashErrorReason`. 125 | */ 126 | - (void)crashManager:(BITCrashManager *)crashManager didFailWithError:(NSError *)error; 127 | 128 | /** Invoked after sending crash reports succeeded 129 | 130 | @param crashManager The `BITCrashManager` instance invoking this delegate 131 | */ 132 | - (void)crashManagerDidFinishSendingCrashReport:(BITCrashManager *)crashManager; 133 | 134 | ///----------------------------------------------------------------------------- 135 | /// @name Experimental 136 | ///----------------------------------------------------------------------------- 137 | 138 | /** Define if a report should be considered as a crash report 139 | 140 | Due to the risk, that these reports may be false positives, this delegates allows the 141 | developer to influence which reports detected by the heuristic should actually be reported. 142 | 143 | The developer can use the following property to get more information about the crash scenario: 144 | - `[BITCrashManager didReceiveMemoryWarningInLastSession]`: Did the app receive a low memory warning 145 | 146 | This allows only reports to be considered where at least one low memory warning notification was 147 | received by the app to reduce to possibility of having false positives. 148 | 149 | @param crashManager The `BITCrashManager` instance invoking this delegate 150 | @return `YES` if the heuristic based detected report should be reported, otherwise `NO` 151 | @see `[BITCrashManager didReceiveMemoryWarningInLastSession]` 152 | */ 153 | -(BOOL)considerAppNotTerminatedCleanlyReportForCrashManager:(BITCrashManager *)crashManager; 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITCrashMetaData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | 32 | /** 33 | * This class provides properties that can be attached to a crash report via a custom alert view flow 34 | */ 35 | @interface BITCrashMetaData : NSObject 36 | 37 | /** 38 | * User provided description that should be attached to the crash report as plain text 39 | */ 40 | @property (nonatomic, copy) NSString *userProvidedDescription; 41 | 42 | /** 43 | * User name that should be attached to the crash report 44 | */ 45 | @property (nonatomic, copy) NSString *userName; 46 | 47 | /** 48 | * User email that should be attached to the crash report 49 | */ 50 | @property (nonatomic, copy) NSString *userEmail; 51 | 52 | /** 53 | * User ID that should be attached to the crash report 54 | */ 55 | @property (nonatomic, copy) NSString *userID; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITHockeyAttachment.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | /** 32 | Provides support to add binary attachments to crash reports and feedback messages 33 | 34 | This is used by `[BITCrashManagerDelegate attachmentForCrashManager:]`, 35 | `[BITFeedbackComposeViewController prepareWithItems:]` and 36 | `[BITFeedbackManager showFeedbackComposeViewWithPreparedItems:]` 37 | */ 38 | @interface BITHockeyAttachment : NSObject 39 | 40 | /** 41 | The filename the attachment should get 42 | */ 43 | @property (nonatomic, readonly, strong) NSString *filename; 44 | 45 | /** 46 | The attachment data as NSData object 47 | */ 48 | @property (nonatomic, readonly, strong) NSData *hockeyAttachmentData; 49 | 50 | /** 51 | The content type of your data as MIME type 52 | */ 53 | @property (nonatomic, readonly, strong) NSString *contentType; 54 | 55 | /** 56 | Create an BITHockeyAttachment instance with a given filename and NSData object 57 | 58 | @param filename The filename the attachment should get. If nil will get a automatically generated filename 59 | @param hockeyAttachmentData The attachment data as NSData. The instance will be ignore if this is set to nil! 60 | @param contentType The content type of your data as MIME type. If nil will be set to "application/octet-stream" 61 | 62 | @return An instance of BITHockeyAttachment. 63 | */ 64 | - (instancetype)initWithFilename:(NSString *)filename 65 | hockeyAttachmentData:(NSData *)hockeyAttachmentData 66 | contentType:(NSString *)contentType; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITHockeyBaseManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | #import 31 | 32 | 33 | /** 34 | The internal superclass for all component managers 35 | 36 | */ 37 | 38 | @interface BITHockeyBaseManager : NSObject 39 | 40 | ///----------------------------------------------------------------------------- 41 | /// @name Modules 42 | ///----------------------------------------------------------------------------- 43 | 44 | 45 | /** 46 | Defines the server URL to send data to or request data from 47 | 48 | By default this is set to the HockeyApp servers and there rarely should be a 49 | need to modify that. 50 | */ 51 | @property (nonatomic, copy) NSString *serverURL; 52 | 53 | 54 | ///----------------------------------------------------------------------------- 55 | /// @name User Interface 56 | ///----------------------------------------------------------------------------- 57 | 58 | /** 59 | The UIBarStyle of the update user interface navigation bar. 60 | 61 | Default is UIBarStyleBlackOpaque 62 | @see navigationBarTintColor 63 | */ 64 | @property (nonatomic, assign) UIBarStyle barStyle; 65 | 66 | /** 67 | The navigationbar tint color of the update user interface navigation bar. 68 | 69 | The navigationBarTintColor is used by default, you can either overwrite it `navigationBarTintColor` 70 | or define another `barStyle` instead. 71 | 72 | Default is RGB(25, 25, 25) 73 | @see barStyle 74 | */ 75 | @property (nonatomic, strong) UIColor *navigationBarTintColor; 76 | 77 | /** 78 | The UIModalPresentationStyle for showing the update user interface when invoked 79 | with the update alert. 80 | */ 81 | @property (nonatomic, assign) UIModalPresentationStyle modalPresentationStyle; 82 | 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITHockeyBaseViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | @interface BITHockeyBaseViewController : UITableViewController 32 | 33 | @property (nonatomic, readwrite) BOOL modalAnimated; 34 | 35 | - (instancetype)initWithModalStyle:(BOOL)modal; 36 | - (instancetype)initWithStyle:(UITableViewStyle)style modal:(BOOL)modal; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITHockeyManagerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | #import "HockeySDKFeatureConfig.h" 31 | 32 | #if HOCKEYSDK_FEATURE_CRASH_REPORTER 33 | #import "BITCrashManagerDelegate.h" 34 | #endif 35 | 36 | #if HOCKEYSDK_FEATURE_UPDATES 37 | #import "BITUpdateManagerDelegate.h" 38 | #endif 39 | 40 | #if HOCKEYSDK_FEATURE_FEEDBACK 41 | #import "BITFeedbackManagerDelegate.h" 42 | #endif 43 | 44 | #if HOCKEYSDK_FEATURE_AUTHENTICATOR 45 | #import "BITAuthenticator.h" 46 | #endif 47 | 48 | @class BITHockeyManager; 49 | @class BITHockeyBaseManager; 50 | 51 | /** 52 | The `BITHockeyManagerDelegate` formal protocol defines methods further configuring 53 | the behaviour of `BITHockeyManager`, as well as the delegate of the modules it manages. 54 | */ 55 | 56 | @protocol BITHockeyManagerDelegate 70 | 71 | @optional 72 | 73 | 74 | ///----------------------------------------------------------------------------- 75 | /// @name App Identifier usage 76 | ///----------------------------------------------------------------------------- 77 | 78 | /** 79 | Implement to force the usage of the live identifier 80 | 81 | This is useful if you are e.g. distributing an enterprise app inside your company 82 | and want to use the `liveIdentifier` for that even though it is not running from 83 | the App Store. 84 | 85 | Example: 86 | 87 | - (BOOL)shouldUseLiveIdentifierForHockeyManager:(BITHockeyManager *)hockeyManager { 88 | #ifdef (CONFIGURATION_AppStore) 89 | return YES; 90 | #endif 91 | return NO; 92 | } 93 | 94 | @param hockeyManager BITHockeyManager instance 95 | */ 96 | - (BOOL)shouldUseLiveIdentifierForHockeyManager:(BITHockeyManager *)hockeyManager; 97 | 98 | 99 | ///----------------------------------------------------------------------------- 100 | /// @name UI presentation 101 | ///----------------------------------------------------------------------------- 102 | 103 | 104 | // optional parent view controller for the feedback screen when invoked via the alert view, default is the root UIWindow instance 105 | /** 106 | Return a custom parent view controller for presenting modal sheets 107 | 108 | By default the SDK is using the root UIWindow instance to present any required 109 | view controllers. Overwrite this if this doesn't result in a satisfying 110 | behavior or if you want to define any other parent view controller. 111 | 112 | @param hockeyManager The `BITHockeyManager` HockeyManager instance invoking this delegate 113 | @param componentManager The `BITHockeyBaseManager` component instance invoking this delegate, can be `BITCrashManager` or `BITFeedbackManager` 114 | */ 115 | - (UIViewController *)viewControllerForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager; 116 | 117 | 118 | ///----------------------------------------------------------------------------- 119 | /// @name Additional meta data 120 | ///----------------------------------------------------------------------------- 121 | 122 | 123 | /** Return the userid that should used in the SDK components 124 | 125 | Right now this is used by the `BITCrashManager` to attach to a crash report. 126 | `BITFeedbackManager` uses it too for assigning the user to a discussion thread. 127 | 128 | In addition, if this returns not nil for `BITFeedbackManager` the user will 129 | not be asked for any user details by the component, including userName or userEmail. 130 | 131 | You can find out the component requesting the userID like this: 132 | 133 | - (NSString *)userIDForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager { 134 | if (componentManager == hockeyManager.feedbackManager) { 135 | return UserIDForFeedback; 136 | } else if (componentManager == hockeyManager.crashManager) { 137 | return UserIDForCrashReports; 138 | } else { 139 | return nil; 140 | } 141 | } 142 | 143 | For crash reports, this delegate is invoked on the startup after the crash! 144 | 145 | Alternatively you can also use `[BITHockeyManager userID]` which will cache the value in the keychain. 146 | 147 | @warning When returning a non nil value for the `BITCrashManager` component, crash reports 148 | are not anonymous any more and the crash alerts will not show the word "anonymous"! 149 | 150 | @param hockeyManager The `BITHockeyManager` HockeyManager instance invoking this delegate 151 | @param componentManager The `BITHockeyBaseManager` component instance invoking this delegate, can be `BITCrashManager` or `BITFeedbackManager` 152 | @see userNameForHockeyManager:componentManager: 153 | @see userEmailForHockeyManager:componentManager: 154 | @see [BITHockeyManager userID] 155 | */ 156 | - (NSString *)userIDForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager; 157 | 158 | 159 | /** Return the user name that should used in the SDK components 160 | 161 | Right now this is used by the `BITCrashManager` to attach to a crash report. 162 | `BITFeedbackManager` uses it too for assigning the user to a discussion thread. 163 | 164 | In addition, if this returns not nil for `BITFeedbackManager` the user will 165 | not be asked for any user details by the component, including userName or userEmail. 166 | 167 | You can find out the component requesting the user name like this: 168 | 169 | - (NSString *)userNameForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager { 170 | if (componentManager == hockeyManager.feedbackManager) { 171 | return UserNameForFeedback; 172 | } else if (componentManager == hockeyManager.crashManager) { 173 | return UserNameForCrashReports; 174 | } else { 175 | return nil; 176 | } 177 | } 178 | 179 | For crash reports, this delegate is invoked on the startup after the crash! 180 | 181 | Alternatively you can also use `[BITHockeyManager userName]` which will cache the value in the keychain. 182 | 183 | @warning When returning a non nil value for the `BITCrashManager` component, crash reports 184 | are not anonymous any more and the crash alerts will not show the word "anonymous"! 185 | 186 | @param hockeyManager The `BITHockeyManager` HockeyManager instance invoking this delegate 187 | @param componentManager The `BITHockeyBaseManager` component instance invoking this delegate, can be `BITCrashManager` or `BITFeedbackManager` 188 | @see userIDForHockeyManager:componentManager: 189 | @see userEmailForHockeyManager:componentManager: 190 | @see [BITHockeyManager userName] 191 | */ 192 | - (NSString *)userNameForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager; 193 | 194 | 195 | /** Return the users email address that should used in the SDK components 196 | 197 | Right now this is used by the `BITCrashManager` to attach to a crash report. 198 | `BITFeedbackManager` uses it too for assigning the user to a discussion thread. 199 | 200 | In addition, if this returns not nil for `BITFeedbackManager` the user will 201 | not be asked for any user details by the component, including userName or userEmail. 202 | 203 | You can find out the component requesting the user email like this: 204 | 205 | - (NSString *)userEmailForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager { 206 | if (componentManager == hockeyManager.feedbackManager) { 207 | return UserEmailForFeedback; 208 | } else if (componentManager == hockeyManager.crashManager) { 209 | return UserEmailForCrashReports; 210 | } else { 211 | return nil; 212 | } 213 | } 214 | 215 | For crash reports, this delegate is invoked on the startup after the crash! 216 | 217 | Alternatively you can also use `[BITHockeyManager userEmail]` which will cache the value in the keychain. 218 | 219 | @warning When returning a non nil value for the `BITCrashManager` component, crash reports 220 | are not anonymous any more and the crash alerts will not show the word "anonymous"! 221 | 222 | @param hockeyManager The `BITHockeyManager` HockeyManager instance invoking this delegate 223 | @param componentManager The `BITHockeyBaseManager` component instance invoking this delegate, can be `BITCrashManager` or `BITFeedbackManager` 224 | @see userIDForHockeyManager:componentManager: 225 | @see userNameForHockeyManager:componentManager: 226 | @see [BITHockeyManager userEmail] 227 | */ 228 | - (NSString *)userEmailForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager; 229 | 230 | @end 231 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITMetricsManager.h: -------------------------------------------------------------------------------- 1 | #import "HockeySDKFeatureConfig.h" 2 | 3 | #if HOCKEYSDK_FEATURE_METRICS 4 | 5 | #import 6 | #import "BITHockeyBaseManager.h" 7 | 8 | #import "HockeySDKNullability.h" 9 | NS_ASSUME_NONNULL_BEGIN 10 | 11 | /** 12 | The metrics module. 13 | 14 | This is the HockeySDK module that handles users, sessions and events tracking. 15 | 16 | Unless disabled, this module automatically tracks users and session of your app to give you 17 | better insights about how your app is being used. 18 | Users are tracked in a completely anonymous way without collecting any personally identifiable 19 | information. 20 | 21 | Before starting to track events, ask yourself the questions that you want to get answers to. 22 | For instance, you might be interested in business, performance/quality or user experience aspects. 23 | Name your events in a meaningful way and keep in mind that you will use these names 24 | when searching for events in the HockeyApp web portal. 25 | 26 | It is your reponsibility to not collect personal information as part of the events tracking or get 27 | prior consent from your users as necessary. 28 | */ 29 | @interface BITMetricsManager : BITHockeyBaseManager 30 | 31 | /** 32 | * A property indicating whether the BITMetricsManager instance is disabled. 33 | */ 34 | @property (nonatomic, assign) BOOL disabled; 35 | 36 | /** 37 | * This method allows to track an event that happened in your app. 38 | * Remember to choose meaningful event names to have the best experience when diagnosing your app 39 | * in the HockeyApp web portal. 40 | * 41 | * @param eventName The event's name as a string. 42 | */ 43 | - (void)trackEventWithName:(nonnull NSString *)eventName; 44 | 45 | /** 46 | * This method allows to track an event that happened in your app. 47 | * Remember to choose meaningful event names to have the best experience when diagnosing your app 48 | * in the web portal. 49 | * 50 | * @param eventName the name of the event, which should be tracked. 51 | * @param properties key value pairs with additional info about the event. 52 | * @param measurements key value pairs, which contain custom metrics. 53 | */ 54 | - (void)trackEventWithName:(nonnull NSString *)eventName properties:(nullable NSDictionary *)properties measurements:(nullable NSDictionary *)measurements; 55 | 56 | @end 57 | 58 | NS_ASSUME_NONNULL_END 59 | 60 | #endif /* HOCKEYSDK_FEATURE_METRICS */ 61 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITStoreUpdateManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2013-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | 30 | #import 31 | #import "BITHockeyBaseManager.h" 32 | 33 | 34 | /** 35 | * Defines the update check intervals 36 | */ 37 | typedef NS_ENUM(NSInteger, BITStoreUpdateSetting) { 38 | /** 39 | * Check every day 40 | */ 41 | BITStoreUpdateCheckDaily = 0, 42 | /** 43 | * Check every week 44 | */ 45 | BITStoreUpdateCheckWeekly = 1, 46 | /** 47 | * Check manually 48 | */ 49 | BITStoreUpdateCheckManually = 2 50 | }; 51 | 52 | @protocol BITStoreUpdateManagerDelegate; 53 | 54 | /** 55 | The store update manager module. 56 | 57 | This is the HockeySDK module for handling app updates when having your app released in the App Store. 58 | By default the module uses the current users locale to define the app store to check for updates. You 59 | can modify this using the `countryCode` property. See the property documentation for details on its usage. 60 | 61 | When an update is detected, this module will show an alert asking the user if he/she wants to update or 62 | ignore this version. If update was chosen, it will open the apps page in the app store app. 63 | 64 | You need to enable this module using `[BITHockeyManager enableStoreUpdateManager]` if you want to use this 65 | feature. By default this module is disabled! 66 | 67 | When this module is enabled and **NOT** running in an App Store build/environment, it won't do any checks! 68 | 69 | The `BITStoreUpdateManagerDelegate` protocol informs the app about new detected app versions. 70 | 71 | @warning This module can **NOT** check if the current device and OS version match the minimum requirements of 72 | the new app version! 73 | 74 | */ 75 | 76 | @interface BITStoreUpdateManager : BITHockeyBaseManager 77 | 78 | ///----------------------------------------------------------------------------- 79 | /// @name Update Checking 80 | ///----------------------------------------------------------------------------- 81 | 82 | /** 83 | When to check for new updates. 84 | 85 | Defines when a the SDK should check if there is a new update available on the 86 | server. This must be assigned one of the following, see `BITStoreUpdateSetting`: 87 | 88 | - `BITStoreUpdateCheckDaily`: Once a day 89 | - `BITStoreUpdateCheckWeekly`: Once a week 90 | - `BITStoreUpdateCheckManually`: Manually 91 | 92 | **Default**: BITStoreUpdateCheckWeekly 93 | 94 | @warning When setting this to `BITStoreUpdateCheckManually` you need to either 95 | invoke the update checking process yourself with `checkForUpdate` somehow, e.g. by 96 | proving an update check button for the user or integrating the Update View into your 97 | user interface. 98 | @see BITStoreUpdateSetting 99 | @see countryCode 100 | @see checkForUpdateOnLaunch 101 | @see checkForUpdate 102 | */ 103 | @property (nonatomic, assign) BITStoreUpdateSetting updateSetting; 104 | 105 | 106 | /** 107 | Defines the store country the app is always available in, otherwise uses the users locale 108 | 109 | If this value is not defined, then it uses the device country if the current locale. 110 | 111 | If you are pre-defining a country and are releasing a new version on a specific date, 112 | it can happen that users get an alert but the update is not yet available in their country! 113 | 114 | But if a user downloaded the app from another appstore than the locale is set and the app is not 115 | available in the locales app store, then the user will never receive an update notification! 116 | 117 | More information about possible country codes is available here: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 118 | 119 | @see updateSetting 120 | @see checkForUpdateOnLaunch 121 | @see checkForUpdate 122 | */ 123 | @property (nonatomic, strong) NSString *countryCode; 124 | 125 | 126 | /** 127 | Flag that determines whether the automatic update checks should be done. 128 | 129 | If this is enabled the update checks will be performed automatically depending on the 130 | `updateSetting` property. If this is disabled the `updateSetting` property will have 131 | no effect, and checking for updates is totally up to be done by yourself. 132 | 133 | *Default*: _YES_ 134 | 135 | @warning When setting this to `NO` you need to invoke update checks yourself! 136 | @see updateSetting 137 | @see countryCode 138 | @see checkForUpdate 139 | */ 140 | @property (nonatomic, assign, getter=isCheckingForUpdateOnLaunch) BOOL checkForUpdateOnLaunch; 141 | 142 | 143 | ///----------------------------------------------------------------------------- 144 | /// @name User Interface 145 | ///----------------------------------------------------------------------------- 146 | 147 | 148 | /** 149 | Flag that determines if the integrated update alert should be used 150 | 151 | If enabled, the integrated UIAlert based update notification will be used to inform 152 | the user about a new update being available in the App Store. 153 | 154 | If disabled, you need to implement the `BITStoreUpdateManagerDelegate` protocol with 155 | the method `[BITStoreUpdateManagerDelegate detectedUpdateFromStoreUpdateManager:newVersion:storeURL:]` 156 | to be notified about new version and proceed yourself. 157 | The manager will consider this identical to an `Ignore` user action using the alert 158 | and not inform about this particular version any more, unless the app is updated 159 | and this very same version shows up at a later time again as a new version. 160 | 161 | *Default*: _YES_ 162 | 163 | @warning If the HockeySDKResources bundle is missing in the application package, then the internal 164 | update alert is also disabled and be treated identical to manually disabling this 165 | property. 166 | @see updateSetting 167 | */ 168 | @property (nonatomic, assign, getter=isUpdateUIEnabled) BOOL updateUIEnabled; 169 | 170 | ///----------------------------------------------------------------------------- 171 | /// @name Manual update checking 172 | ///----------------------------------------------------------------------------- 173 | 174 | /** 175 | Check for an update 176 | 177 | Call this to trigger a check if there is a new update available on the HockeyApp servers. 178 | 179 | @see updateSetting 180 | @see countryCode 181 | @see checkForUpdateOnLaunch 182 | */ 183 | - (void)checkForUpdate; 184 | 185 | 186 | @end 187 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITStoreUpdateManagerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2013-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | @class BITStoreUpdateManager; 32 | 33 | /** 34 | The `BITStoreUpdateManagerDelegate` formal protocol defines methods for 35 | more interaction with `BITStoreUpdateManager`. 36 | */ 37 | 38 | @protocol BITStoreUpdateManagerDelegate 39 | 40 | @optional 41 | 42 | 43 | ///----------------------------------------------------------------------------- 44 | /// @name Update information 45 | ///----------------------------------------------------------------------------- 46 | 47 | /** Informs which new version has been reported to be available 48 | 49 | @warning If this is invoked with a simulated new version, the storeURL could be _NIL_ if the current builds 50 | bundle identifier is different to the bundle identifier used in the app store build. 51 | @param storeUpdateManager The `BITStoreUpdateManager` instance invoking this delegate 52 | @param newVersion The new version string reported by the App Store 53 | @param storeURL The App Store URL for this app that could be invoked to let them perform the update. 54 | */ 55 | -(void)detectedUpdateFromStoreUpdateManager:(BITStoreUpdateManager *)storeUpdateManager newVersion:(NSString *)newVersion storeURL:(NSURL *)storeURL; 56 | 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITUpdateManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * Peter Steinberger 4 | * 5 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 6 | * Copyright (c) 2011 Andreas Linde. 7 | * All rights reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person 10 | * obtaining a copy of this software and associated documentation 11 | * files (the "Software"), to deal in the Software without 12 | * restriction, including without limitation the rights to use, 13 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | * copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following 16 | * conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be 19 | * included in all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | * OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | 32 | #import "BITHockeyBaseManager.h" 33 | 34 | 35 | /** 36 | * Update check interval 37 | */ 38 | typedef NS_ENUM (NSUInteger, BITUpdateSetting) { 39 | /** 40 | * On every startup or or when the app comes to the foreground 41 | */ 42 | BITUpdateCheckStartup = 0, 43 | /** 44 | * Once a day 45 | */ 46 | BITUpdateCheckDaily = 1, 47 | /** 48 | * Manually 49 | */ 50 | BITUpdateCheckManually = 2 51 | }; 52 | 53 | @protocol BITUpdateManagerDelegate; 54 | 55 | @class BITAppVersionMetaInfo; 56 | @class BITUpdateViewController; 57 | 58 | /** 59 | The update manager module. 60 | 61 | This is the HockeySDK module for handling app updates when using Ad-Hoc or Enterprise provisioning profiles. 62 | This module handles version updates, presents update and version information in an App Store like user interface, 63 | collects usage information and provides additional authorization options when using Ad-Hoc provisioning profiles. 64 | 65 | By default, this module automatically disables itself when running in an App Store build! 66 | 67 | The protocol `BITUpdateManagerDelegate` provides delegates to inform about events and adjust a few behaviors. 68 | 69 | To use the server side restriction feature, to provide updates only to specific users, you need to setup the 70 | `BITAuthenticator` class. This allows the update request to tell the server which user is using the app on the 71 | current device and then let the server decide which updates the device may see. 72 | 73 | */ 74 | 75 | @interface BITUpdateManager : BITHockeyBaseManager 76 | 77 | ///----------------------------------------------------------------------------- 78 | /// @name Update Checking 79 | ///----------------------------------------------------------------------------- 80 | 81 | // see HockeyUpdateSetting-enum. Will be saved in user defaults. 82 | // default value: HockeyUpdateCheckStartup 83 | /** 84 | When to check for new updates. 85 | 86 | Defines when the SDK should check if there is a new update available on the 87 | server. This must be assigned one of the following, see `BITUpdateSetting`: 88 | 89 | - `BITUpdateCheckStartup`: On every startup or or when the app comes to the foreground 90 | - `BITUpdateCheckDaily`: Once a day 91 | - `BITUpdateCheckManually`: Manually 92 | 93 | When running the app from the App Store, this setting is ignored. 94 | 95 | **Default**: BITUpdateCheckStartup 96 | 97 | @warning When setting this to `BITUpdateCheckManually` you need to either 98 | invoke the update checking process yourself with `checkForUpdate` somehow, e.g. by 99 | proving an update check button for the user or integrating the Update View into your 100 | user interface. 101 | @see BITUpdateSetting 102 | @see checkForUpdateOnLaunch 103 | @see checkForUpdate 104 | */ 105 | @property (nonatomic, assign) BITUpdateSetting updateSetting; 106 | 107 | 108 | /** 109 | Flag that determines whether the automatic update checks should be done. 110 | 111 | If this is enabled the update checks will be performed automatically depending on the 112 | `updateSetting` property. If this is disabled the `updateSetting` property will have 113 | no effect, and checking for updates is totally up to be done by yourself. 114 | 115 | When running the app from the App Store, this setting is ignored. 116 | 117 | *Default*: _YES_ 118 | 119 | @warning When setting this to `NO` you need to invoke update checks yourself! 120 | @see updateSetting 121 | @see checkForUpdate 122 | */ 123 | @property (nonatomic, assign, getter=isCheckForUpdateOnLaunch) BOOL checkForUpdateOnLaunch; 124 | 125 | 126 | // manually start an update check 127 | /** 128 | Check for an update 129 | 130 | Call this to trigger a check if there is a new update available on the HockeyApp servers. 131 | 132 | When running the app from the App Store, this method call is ignored. 133 | 134 | @see updateSetting 135 | @see checkForUpdateOnLaunch 136 | */ 137 | - (void)checkForUpdate; 138 | 139 | 140 | ///----------------------------------------------------------------------------- 141 | /// @name Update Notification 142 | ///----------------------------------------------------------------------------- 143 | 144 | /** 145 | Flag that determines if update alerts should be repeatedly shown 146 | 147 | If enabled the update alert shows on every startup and whenever the app becomes active, 148 | until the update is installed. 149 | If disabled the update alert is only shown once ever and it is up to you to provide an 150 | alternate way for the user to navigate to the update UI or update in another way. 151 | 152 | When running the app from the App Store, this setting is ignored. 153 | 154 | *Default*: _YES_ 155 | */ 156 | @property (nonatomic, assign) BOOL alwaysShowUpdateReminder; 157 | 158 | 159 | /** 160 | Flag that determines if the update alert should show a direct install option 161 | 162 | If enabled the update alert shows an additional option which allows to invoke the update 163 | installation process directly instead of viewing the update UI first. 164 | By default the alert only shows a `Show` and `Ignore` option. 165 | 166 | When running the app from the App Store, this setting is ignored. 167 | 168 | *Default*: _NO_ 169 | */ 170 | @property (nonatomic, assign, getter=isShowingDirectInstallOption) BOOL showDirectInstallOption; 171 | 172 | 173 | ///----------------------------------------------------------------------------- 174 | /// @name Expiry 175 | ///----------------------------------------------------------------------------- 176 | 177 | /** 178 | Expiry date of the current app version 179 | 180 | If set, the app will get unusable at the given date by presenting a blocking view on 181 | top of the apps UI so that no interaction is possible. To present a custom UI, check 182 | the documentation of the 183 | `[BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:]` delegate. 184 | 185 | Once the expiry date is reached, the app will no longer check for updates or 186 | send any usage data to the server! 187 | 188 | When running the app from the App Store, this setting is ignored. 189 | 190 | *Default*: nil 191 | @see disableUpdateCheckOptionWhenExpired 192 | @see [BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:] 193 | @see [BITUpdateManagerDelegate didDisplayExpiryAlertForUpdateManager:] 194 | @warning This only works when using Ad-Hoc provisioning profiles! 195 | */ 196 | @property (nonatomic, strong) NSDate *expiryDate; 197 | 198 | /** 199 | Disable the update check button from expiry screen or alerts 200 | 201 | If do not want your users to be able to check for updates once a version is expired, 202 | then enable this property. 203 | 204 | If this is not enabled, the users will be able to check for updates and install them 205 | if any is available for the current device. 206 | 207 | *Default*: NO 208 | @see expiryDate 209 | @see [BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:] 210 | @see [BITUpdateManagerDelegate didDisplayExpiryAlertForUpdateManager:] 211 | @warning This only works when using Ad-Hoc provisioning profiles! 212 | */ 213 | @property (nonatomic) BOOL disableUpdateCheckOptionWhenExpired; 214 | 215 | 216 | ///----------------------------------------------------------------------------- 217 | /// @name User Interface 218 | ///----------------------------------------------------------------------------- 219 | 220 | 221 | /** 222 | Present the modal update user interface. 223 | 224 | @warning Make sure to call this method from the main thread! 225 | */ 226 | - (void)showUpdateView; 227 | 228 | 229 | /** 230 | Create an update view 231 | 232 | @param modal Return a view which is ready for modal presentation with an integrated navigation bar 233 | @return BITUpdateViewController The update user interface view controller, 234 | e.g. to push it onto a navigation stack. 235 | */ 236 | - (BITUpdateViewController *)hockeyViewController:(BOOL)modal; 237 | 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITUpdateManagerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #import 30 | 31 | @class BITUpdateManager; 32 | 33 | /** 34 | The `BITUpdateManagerDelegate` formal protocol defines methods further configuring 35 | the behaviour of `BITUpdateManager`. 36 | */ 37 | 38 | @protocol BITUpdateManagerDelegate 39 | 40 | @optional 41 | 42 | ///----------------------------------------------------------------------------- 43 | /// @name Update 44 | ///----------------------------------------------------------------------------- 45 | 46 | /** 47 | Return if update alert should be shown 48 | 49 | If you want to display your own user interface when there is an update available, 50 | implement this method, present your user interface and return _NO_. In this case 51 | it is your responsibility to call `BITUpdateManager showUpdateView` 52 | 53 | Note: This delegate will be invoked on startup and every time the app becomes 54 | active again! 55 | 56 | When returning _YES_ the default blocking UI will be shown. 57 | 58 | When running the app from the App Store, this delegate is ignored. 59 | 60 | @param updateManager The `BITUpdateManager` instance invoking this delegate 61 | @param shortVersion The latest available version 62 | @param version The latest available version 63 | */ 64 | - (BOOL)shouldDisplayUpdateAlertForUpdateManager:(BITUpdateManager *)updateManager forShortVersion:(NSString *)shortVersion forVersion:(NSString *)version; 65 | 66 | ///----------------------------------------------------------------------------- 67 | /// @name Expiry 68 | ///----------------------------------------------------------------------------- 69 | 70 | /** 71 | Return if expiry alert should be shown if date is reached 72 | 73 | If you want to display your own user interface when the expiry date is reached, 74 | implement this method, present your user interface and return _NO_. In this case 75 | it is your responsibility to make the app unusable! 76 | 77 | Note: This delegate will be invoked on startup and every time the app becomes 78 | active again! 79 | 80 | When returning _YES_ the default blocking UI will be shown. 81 | 82 | When running the app from the App Store, this delegate is ignored. 83 | 84 | @param updateManager The `BITUpdateManager` instance invoking this delegate 85 | @see [BITUpdateManager expiryDate] 86 | @see [BITUpdateManagerDelegate didDisplayExpiryAlertForUpdateManager:] 87 | */ 88 | - (BOOL)shouldDisplayExpiryAlertForUpdateManager:(BITUpdateManager *)updateManager; 89 | 90 | 91 | /** 92 | Invoked once a default expiry alert is shown 93 | 94 | Once expiry date is reached and the default blocking UI is shown, 95 | this delegate method is invoked to provide you the possibility to do any 96 | desired additional processing. 97 | 98 | @param updateManager The `BITUpdateManager` instance invoking this delegate 99 | @see [BITUpdateManager expiryDate] 100 | @see [BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:] 101 | */ 102 | - (void)didDisplayExpiryAlertForUpdateManager:(BITUpdateManager *)updateManager; 103 | 104 | 105 | ///----------------------------------------------------------------------------- 106 | /// @name Privacy 107 | ///----------------------------------------------------------------------------- 108 | 109 | /** Return NO if usage data should not be send 110 | 111 | The update module send usage data by default, if the application is _NOT_ 112 | running in an App Store version. Implement this delegate and 113 | return NO if you want to disable this. 114 | 115 | If you intend to implement a user setting to let them enable or disable 116 | sending usage data, this delegate should be used to return that value. 117 | 118 | Usage data contains the following information: 119 | - App Version 120 | - iOS Version 121 | - Device type 122 | - Language 123 | - Installation timestamp 124 | - Usage time 125 | 126 | @param updateManager The `BITUpdateManager` instance invoking this delegate 127 | @warning When setting this to `NO`, you will _NOT_ know if this user is actually testing! 128 | */ 129 | - (BOOL)updateManagerShouldSendUsageData:(BITUpdateManager *)updateManager; 130 | 131 | 132 | ///----------------------------------------------------------------------------- 133 | /// @name Privacy 134 | ///----------------------------------------------------------------------------- 135 | 136 | /** Implement this method to be notified before an update starts. 137 | 138 | The update manager will send this delegate message _just_ before the system 139 | call to update the application is placed, but after the user has already chosen 140 | to install the update. 141 | 142 | There is no guarantee that the update will actually start after this delegate 143 | message is sent. 144 | 145 | @param updateManager The `BITUpdateManager` instance invoking this delegate 146 | */ 147 | - (BOOL)willStartDownloadAndUpdate:(BITUpdateManager *)updateManager; 148 | 149 | /** 150 | Invoked right before the app will exit to allow app update to start (>= iOS8 only) 151 | 152 | The iOS installation mechanism only starts if the app the should be updated is currently 153 | not running. On all iOS versions up to iOS 7, the system did automatically exit the app 154 | in these cases. Since iOS 8 this isn't done any longer. 155 | 156 | @param updateManager The `BITUpdateManager` instance invoking this delegate 157 | */ 158 | - (void)updateManagerWillExitApp:(BITUpdateManager *)updateManager; 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/BITUpdateViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * Peter Steinberger 4 | * 5 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 6 | * Copyright (c) 2011 Andreas Linde, Peter Steinberger. 7 | * All rights reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person 10 | * obtaining a copy of this software and associated documentation 11 | * files (the "Software"), to deal in the Software without 12 | * restriction, including without limitation the rights to use, 13 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | * copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following 16 | * conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be 19 | * included in all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | * OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | #import 32 | 33 | #import "BITHockeyBaseViewController.h" 34 | 35 | 36 | @interface BITUpdateViewController : BITHockeyBaseViewController 37 | @end 38 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/HockeySDK.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH. 5 | * Copyright (c) 2011 Andreas Linde. 6 | * All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person 9 | * obtaining a copy of this software and associated documentation 10 | * files (the "Software"), to deal in the Software without 11 | * restriction, including without limitation the rights to use, 12 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the 14 | * Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be 18 | * included in all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 22 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 24 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 25 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 | * OTHER DEALINGS IN THE SOFTWARE. 28 | */ 29 | 30 | #import 31 | 32 | 33 | #if !defined (TARGET_OS_IOS) // Defined starting in iOS 9 34 | #define TARGET_OS_IOS 1 35 | #endif 36 | 37 | 38 | #import "HockeySDKFeatureConfig.h" 39 | #import "HockeySDKEnums.h" 40 | #import "HockeySDKNullability.h" 41 | 42 | #import "BITHockeyManager.h" 43 | #import "BITHockeyManagerDelegate.h" 44 | 45 | #if HOCKEYSDK_FEATURE_CRASH_REPORTER || HOCKEYSDK_FEATURE_FEEDBACK 46 | #import "BITHockeyAttachment.h" 47 | #endif 48 | 49 | #if HOCKEYSDK_FEATURE_CRASH_REPORTER 50 | #import "BITCrashManager.h" 51 | #import "BITCrashAttachment.h" 52 | #import "BITCrashManagerDelegate.h" 53 | #import "BITCrashDetails.h" 54 | #import "BITCrashMetaData.h" 55 | #endif /* HOCKEYSDK_FEATURE_CRASH_REPORTER */ 56 | 57 | #if HOCKEYSDK_FEATURE_UPDATES 58 | #import "BITUpdateManager.h" 59 | #import "BITUpdateManagerDelegate.h" 60 | #import "BITUpdateViewController.h" 61 | #endif /* HOCKEYSDK_FEATURE_UPDATES */ 62 | 63 | #if HOCKEYSDK_FEATURE_STORE_UPDATES 64 | #import "BITStoreUpdateManager.h" 65 | #import "BITStoreUpdateManagerDelegate.h" 66 | #endif /* HOCKEYSDK_FEATURE_STORE_UPDATES */ 67 | 68 | #if HOCKEYSDK_FEATURE_FEEDBACK 69 | #import "BITFeedbackManager.h" 70 | #import "BITFeedbackManagerDelegate.h" 71 | #import "BITFeedbackActivity.h" 72 | #import "BITFeedbackComposeViewController.h" 73 | #import "BITFeedbackComposeViewControllerDelegate.h" 74 | #import "BITFeedbackListViewController.h" 75 | #endif /* HOCKEYSDK_FEATURE_FEEDBACK */ 76 | 77 | #if HOCKEYSDK_FEATURE_AUTHENTICATOR 78 | #import "BITAuthenticator.h" 79 | #endif /* HOCKEYSDK_FEATURE_AUTHENTICATOR */ 80 | 81 | #if HOCKEYSDK_FEATURE_METRICS 82 | #import "BITMetricsManager.h" 83 | #endif /* HOCKEYSDK_FEATURE_METRICS */ 84 | 85 | // Notification message which HockeyManager is listening to, to retry requesting updated from the server. 86 | // This can be used by app developers to trigger additional points where the HockeySDK can try sending 87 | // pending crash reports or feedback messages. 88 | // By default the SDK retries sending pending data only when the app becomes active. 89 | #define BITHockeyNetworkDidBecomeReachableNotification @"BITHockeyNetworkDidBecomeReachable" 90 | 91 | extern NSString *const __attribute__((unused)) kBITCrashErrorDomain; 92 | extern NSString *const __attribute__((unused)) kBITUpdateErrorDomain; 93 | extern NSString *const __attribute__((unused)) kBITFeedbackErrorDomain; 94 | extern NSString *const __attribute__((unused)) kBITAuthenticatorErrorDomain; 95 | extern NSString *const __attribute__((unused)) kBITHockeyErrorDomain; 96 | 97 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/HockeySDKEnums.h: -------------------------------------------------------------------------------- 1 | // 2 | // HockeySDKEnums.h 3 | // HockeySDK 4 | // 5 | // Created by Lukas Spieß on 08/10/15. 6 | // 7 | // 8 | 9 | #ifndef HockeySDK_HockeyEnums_h 10 | #define HockeySDK_HockeyEnums_h 11 | 12 | /** 13 | * HockeySDK Log Levels 14 | */ 15 | typedef NS_ENUM(NSUInteger, BITLogLevel) { 16 | /** 17 | * Logging is disabled 18 | */ 19 | BITLogLevelNone = 0, 20 | /** 21 | * Only errors will be logged 22 | */ 23 | BITLogLevelError = 1, 24 | /** 25 | * Errors and warnings will be logged 26 | */ 27 | BITLogLevelWarning = 2, 28 | /** 29 | * Debug information will be logged 30 | */ 31 | BITLogLevelDebug = 3, 32 | /** 33 | * Logging will be very chatty 34 | */ 35 | BITLogLevelVerbose = 4 36 | }; 37 | 38 | typedef NSString *(^BITLogMessageProvider)(void); 39 | typedef void (^BITLogHandler)(BITLogMessageProvider messageProvider, BITLogLevel logLevel, const char *file, const char *function, uint line); 40 | 41 | /** 42 | * HockeySDK App environment 43 | */ 44 | typedef NS_ENUM(NSInteger, BITEnvironment) { 45 | /** 46 | * App has been downloaded from the AppStore 47 | */ 48 | BITEnvironmentAppStore = 0, 49 | /** 50 | * App has been downloaded from TestFlight 51 | */ 52 | BITEnvironmentTestFlight = 1, 53 | /** 54 | * App has been installed by some other mechanism. 55 | * This could be Ad-Hoc, Enterprise, etc. 56 | */ 57 | BITEnvironmentOther = 99 58 | }; 59 | 60 | /** 61 | * HockeySDK Crash Reporter error domain 62 | */ 63 | typedef NS_ENUM (NSInteger, BITCrashErrorReason) { 64 | /** 65 | * Unknown error 66 | */ 67 | BITCrashErrorUnknown, 68 | /** 69 | * API Server rejected app version 70 | */ 71 | BITCrashAPIAppVersionRejected, 72 | /** 73 | * API Server returned empty response 74 | */ 75 | BITCrashAPIReceivedEmptyResponse, 76 | /** 77 | * Connection error with status code 78 | */ 79 | BITCrashAPIErrorWithStatusCode 80 | }; 81 | 82 | /** 83 | * HockeySDK Update error domain 84 | */ 85 | typedef NS_ENUM (NSInteger, BITUpdateErrorReason) { 86 | /** 87 | * Unknown error 88 | */ 89 | BITUpdateErrorUnknown, 90 | /** 91 | * API Server returned invalid status 92 | */ 93 | BITUpdateAPIServerReturnedInvalidStatus, 94 | /** 95 | * API Server returned invalid data 96 | */ 97 | BITUpdateAPIServerReturnedInvalidData, 98 | /** 99 | * API Server returned empty response 100 | */ 101 | BITUpdateAPIServerReturnedEmptyResponse, 102 | /** 103 | * Authorization secret missing 104 | */ 105 | BITUpdateAPIClientAuthorizationMissingSecret, 106 | /** 107 | * No internet connection 108 | */ 109 | BITUpdateAPIClientCannotCreateConnection 110 | }; 111 | 112 | /** 113 | * HockeySDK Feedback error domain 114 | */ 115 | typedef NS_ENUM(NSInteger, BITFeedbackErrorReason) { 116 | /** 117 | * Unknown error 118 | */ 119 | BITFeedbackErrorUnknown, 120 | /** 121 | * API Server returned invalid status 122 | */ 123 | BITFeedbackAPIServerReturnedInvalidStatus, 124 | /** 125 | * API Server returned invalid data 126 | */ 127 | BITFeedbackAPIServerReturnedInvalidData, 128 | /** 129 | * API Server returned empty response 130 | */ 131 | BITFeedbackAPIServerReturnedEmptyResponse, 132 | /** 133 | * Authorization secret missing 134 | */ 135 | BITFeedbackAPIClientAuthorizationMissingSecret, 136 | /** 137 | * No internet connection 138 | */ 139 | BITFeedbackAPIClientCannotCreateConnection 140 | }; 141 | 142 | /** 143 | * HockeySDK Authenticator error domain 144 | */ 145 | typedef NS_ENUM(NSInteger, BITAuthenticatorReason) { 146 | /** 147 | * Unknown error 148 | */ 149 | BITAuthenticatorErrorUnknown, 150 | /** 151 | * Network error 152 | */ 153 | BITAuthenticatorNetworkError, 154 | 155 | /** 156 | * API Server returned invalid response 157 | */ 158 | BITAuthenticatorAPIServerReturnedInvalidResponse, 159 | /** 160 | * Not Authorized 161 | */ 162 | BITAuthenticatorNotAuthorized, 163 | /** 164 | * Unknown Application ID (configuration error) 165 | */ 166 | BITAuthenticatorUnknownApplicationID, 167 | /** 168 | * Authorization secret missing 169 | */ 170 | BITAuthenticatorAuthorizationSecretMissing, 171 | /** 172 | * Not yet identified 173 | */ 174 | BITAuthenticatorNotIdentified, 175 | }; 176 | 177 | /** 178 | * HockeySDK global error domain 179 | */ 180 | typedef NS_ENUM(NSInteger, BITHockeyErrorReason) { 181 | /** 182 | * Unknown error 183 | */ 184 | BITHockeyErrorUnknown 185 | }; 186 | 187 | #endif /* HockeySDK_HockeyEnums_h */ 188 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/HockeySDKFeatureConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Andreas Linde 3 | * 4 | * Copyright (c) 2013-2014 HockeyApp, Bit Stadium GmbH. 5 | * All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | /** 30 | * This is the template feature config that is used for debug builds and during development. 31 | * For the Distribution target, we are using separate configs that will be copied over in our build script. 32 | */ 33 | 34 | 35 | #ifndef HockeySDK_HockeySDKFeatureConfig_h 36 | #define HockeySDK_HockeySDKFeatureConfig_h 37 | 38 | /** 39 | * If true, include support for handling crash reports 40 | * 41 | * _Default_: Enabled 42 | */ 43 | #ifndef HOCKEYSDK_FEATURE_CRASH_REPORTER 44 | # define HOCKEYSDK_FEATURE_CRASH_REPORTER 1 45 | #endif /* HOCKEYSDK_FEATURE_CRASH_REPORTER */ 46 | 47 | 48 | /** 49 | * If true, include support for managing user feedback 50 | * 51 | * _Default_: Enabled 52 | */ 53 | #ifndef HOCKEYSDK_FEATURE_FEEDBACK 54 | # define HOCKEYSDK_FEATURE_FEEDBACK 0 55 | #endif /* HOCKEYSDK_FEATURE_FEEDBACK */ 56 | 57 | 58 | /** 59 | * If true, include support for informing the user about new updates pending in the App Store 60 | * 61 | * _Default_: Enabled 62 | */ 63 | #ifndef HOCKEYSDK_FEATURE_STORE_UPDATES 64 | # define HOCKEYSDK_FEATURE_STORE_UPDATES 1 65 | #endif /* HOCKEYSDK_FEATURE_STORE_UPDATES */ 66 | 67 | 68 | /** 69 | * If true, include support for authentication installations for Ad-Hoc and Enterprise builds 70 | * 71 | * _Default_: Enabled 72 | */ 73 | #ifndef HOCKEYSDK_FEATURE_AUTHENTICATOR 74 | # define HOCKEYSDK_FEATURE_AUTHENTICATOR 1 75 | #endif /* HOCKEYSDK_FEATURE_AUTHENTICATOR */ 76 | 77 | 78 | /** 79 | * If true, include support for handling in-app updates for Ad-Hoc and Enterprise builds 80 | * 81 | * _Default_: Enabled 82 | */ 83 | #ifndef HOCKEYSDK_FEATURE_UPDATES 84 | # define HOCKEYSDK_FEATURE_UPDATES 1 85 | #endif /* HOCKEYSDK_FEATURE_UPDATES */ 86 | 87 | 88 | /** 89 | * If true, include support for auto collecting metrics data such as sessions and user 90 | * 91 | * _Default_: Enabled 92 | */ 93 | #ifndef HOCKEYSDK_FEATURE_METRICS 94 | # define HOCKEYSDK_FEATURE_METRICS 1 95 | #endif /* HOCKEYSDK_FEATURE_METRICS */ 96 | 97 | #endif /* HockeySDK_HockeySDKFeatureConfig_h */ 98 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Headers/HockeySDKNullability.h: -------------------------------------------------------------------------------- 1 | // 2 | // HockeyNullability.h 3 | // HockeySDK 4 | // 5 | // Created by Andreas Linde on 12/06/15. 6 | // 7 | // 8 | 9 | #ifndef HockeySDK_HockeyNullability_h 10 | #define HockeySDK_HockeyNullability_h 11 | 12 | // Define nullability fallback for backwards compatibility 13 | #if !__has_feature(nullability) 14 | #define NS_ASSUME_NONNULL_BEGIN 15 | #define NS_ASSUME_NONNULL_END 16 | #define nullable 17 | #define nonnull 18 | #define null_unspecified 19 | #define null_resettable 20 | #define _Nullable 21 | #define _Nonnull 22 | #define __nullable 23 | #define __nonnull 24 | #define __null_unspecified 25 | #endif 26 | 27 | // Fallback for convenience syntax which might not be available in older SDKs 28 | #ifndef NS_ASSUME_NONNULL_BEGIN 29 | #define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 30 | #endif 31 | #ifndef NS_ASSUME_NONNULL_END 32 | #define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 33 | #endif 34 | 35 | #endif /* HockeySDK_HockeyNullability_h */ 36 | -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/HockeySDK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/HockeySDK -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module HockeySDK { 2 | umbrella header "HockeySDK.h" 3 | 4 | export * 5 | module * { export * } 6 | 7 | link framework "CoreTelephony" 8 | link framework "CoreGraphics" 9 | link framework "Foundation" 10 | link framework "MobileCoreServices" 11 | link framework "QuartzCore" 12 | link framework "QuickLook" 13 | link framework "Security" 14 | link framework "SystemConfiguration" 15 | link framework "UIKit" 16 | link "c++" 17 | link "z" 18 | } -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/AppIconPlaceHolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/AppIconPlaceHolder.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Arrow.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Arrow@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Arrow@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Blur.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Blur@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Blur@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Blur@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Blur@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Cancel.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Cancel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Cancel@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Cancel@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Cancel@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/FeedbackPlaceholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/FeedbackPlaceholder.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/IconGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/IconGradient.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/IconGradient@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/IconGradient@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Info.plist -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Ok.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Ok@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Ok@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Ok@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Ok@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Rectangle.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Rectangle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Rectangle@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Rectangle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/Rectangle@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/authorize_denied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/authorize_denied.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/authorize_denied@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/authorize_denied@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/authorize_denied@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/authorize_denied@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/bg.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDelete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDelete.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDelete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDelete@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDeleteHighlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDeleteHighlighted.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDeleteHighlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedDeleteHighlighted@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegular.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegular@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegular@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegularHighlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegularHighlighted.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegularHighlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/buttonRoundedRegularHighlighted@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/de.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/de.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/en.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/en.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/es.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/es.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/fa.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/fa.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity@2x~ipad.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity@3x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/feedbackActivity~ipad.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/fr.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/fr.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/hr.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/hr.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/hu.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/hu.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/iconCamera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/iconCamera.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/iconCamera@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/iconCamera@2x.png -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/it.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/it.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/ja.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/ja.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/nb.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/nb.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/nl.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/nl.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/pt-PT.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/pt-PT.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/pt.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/pt.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/ru.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/ru.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/zh-Hans.lproj/HockeySDK.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDKResources.bundle/zh-Hans.lproj/HockeySDK.strings -------------------------------------------------------------------------------- /HockeySDK-iOS/LICENSE: -------------------------------------------------------------------------------- 1 | ## Licenses 2 | 3 | The Hockey SDK is provided under the following license: 4 | 5 | The MIT License 6 | Copyright (c) Microsoft Corporation. 7 | All rights reserved. 8 | 9 | Permission is hereby granted, free of charge, to any person 10 | obtaining a copy of this software and associated documentation 11 | files (the "Software"), to deal in the Software without 12 | restriction, including without limitation the rights to use, 13 | copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following 16 | conditions: 17 | 18 | The above copyright notice and this permission notice shall be 19 | included in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | Except as noted below, PLCrashReporter 31 | is provided under the following license: 32 | 33 | Copyright (c) 2008 - 2015 Plausible Labs Cooperative, Inc. 34 | Copyright (c) 2012 - 2015 HockeyApp, Bit Stadium GmbH. 35 | All rights reserved. 36 | 37 | Permission is hereby granted, free of charge, to any person 38 | obtaining a copy of this software and associated documentation 39 | files (the "Software"), to deal in the Software without 40 | restriction, including without limitation the rights to use, 41 | copy, modify, merge, publish, distribute, sublicense, and/or sell 42 | copies of the Software, and to permit persons to whom the 43 | Software is furnished to do so, subject to the following 44 | conditions: 45 | 46 | The above copyright notice and this permission notice shall be 47 | included in all copies or substantial portions of the Software. 48 | 49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 50 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 51 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 52 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 53 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 54 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 55 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 56 | OTHER DEALINGS IN THE SOFTWARE. 57 | 58 | The protobuf-c library, as well as the PLCrashLogWriterEncoding.c 59 | file are licensed as follows: 60 | 61 | Copyright 2008, Dave Benson. 62 | 63 | Licensed under the Apache License, Version 2.0 (the "License"); 64 | you may not use this file except in compliance with 65 | the License. You may obtain a copy of the License 66 | at http://www.apache.org/licenses/LICENSE-2.0 Unless 67 | required by applicable law or agreed to in writing, 68 | software distributed under the License is distributed on 69 | an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 70 | KIND, either express or implied. See the License for the 71 | specific language governing permissions and limitations 72 | under the License. 73 | 74 | TTTAttributedLabel is licensed as follows: 75 | 76 | Copyright (c) 2011 Mattt Thompson (http://mattt.me/) 77 | 78 | Permission is hereby granted, free of charge, to any person 79 | obtaining a copy of this software and associated documentation 80 | files (the "Software"), to deal in the Software without 81 | restriction, including without limitation the rights to use, 82 | copy, modify, merge, publish, distribute, sublicense, and/or sell 83 | copies of the Software, and to permit persons to whom the 84 | Software is furnished to do so, subject to the following 85 | conditions: 86 | 87 | The above copyright notice and this permission notice shall be 88 | included in all copies or substantial portions of the Software. 89 | 90 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 91 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 92 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 93 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 94 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 95 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 96 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 97 | OTHER DEALINGS IN THE SOFTWARE. 98 | 99 | SFHFKeychainUtils is licensed as follows: 100 | 101 | Created by Buzz Andersen on 10/20/08. 102 | Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone. 103 | Copyright 2008 Sci-Fi Hi-Fi. All rights reserved. 104 | 105 | Permission is hereby granted, free of charge, to any person 106 | obtaining a copy of this software and associated documentation 107 | files (the "Software"), to deal in the Software without 108 | restriction, including without limitation the rights to use, 109 | copy, modify, merge, publish, distribute, sublicense, and/or sell 110 | copies of the Software, and to permit persons to whom the 111 | Software is furnished to do so, subject to the following 112 | conditions: 113 | 114 | The above copyright notice and this permission notice shall be 115 | included in all copies or substantial portions of the Software. 116 | 117 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 118 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 119 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 120 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 121 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 122 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 123 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 124 | OTHER DEALINGS IN THE SOFTWARE. 125 | 126 | GZIP is licensed as follow: 127 | 128 | Created by Nick Lockwood on 03/06/2012. 129 | Copyright (C) 2012 Charcoal Design 130 | 131 | Distributed under the permissive zlib License 132 | Get the latest version from here: 133 | 134 | https://github.com/nicklockwood/GZIP 135 | 136 | This software is provided 'as-is', without any express or implied 137 | warranty. In no event will the authors be held liable for any damages 138 | arising from the use of this software. 139 | 140 | Permission is granted to anyone to use this software for any purpose, 141 | including commercial applications, and to alter it and redistribute it 142 | freely, subject to the following restrictions: 143 | 144 | 1. The origin of this software must not be misrepresented; you must not 145 | claim that you wrote the original software. If you use this software 146 | in a product, an acknowledgment in the product documentation would be 147 | appreciated but is not required. 148 | 149 | 2. Altered source versions must be plainly marked as such, and must not be 150 | misrepresented as being the original software. 151 | 152 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /Icon/Icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-60.png -------------------------------------------------------------------------------- /Icon/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-60@2x.png -------------------------------------------------------------------------------- /Icon/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-60@3x.png -------------------------------------------------------------------------------- /Icon/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-72.png -------------------------------------------------------------------------------- /Icon/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-72@2x.png -------------------------------------------------------------------------------- /Icon/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-76.png -------------------------------------------------------------------------------- /Icon/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-76@2x.png -------------------------------------------------------------------------------- /Icon/Icon-76@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-76@3x.png -------------------------------------------------------------------------------- /Icon/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Small-50.png -------------------------------------------------------------------------------- /Icon/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /Icon/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Small.png -------------------------------------------------------------------------------- /Icon/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Small@2x.png -------------------------------------------------------------------------------- /Icon/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Small@3x.png -------------------------------------------------------------------------------- /Icon/Icon-Spotlight-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Spotlight-40.png -------------------------------------------------------------------------------- /Icon/Icon-Spotlight-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Spotlight-40@2x.png -------------------------------------------------------------------------------- /Icon/Icon-Spotlight-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-Spotlight-40@3x.png -------------------------------------------------------------------------------- /Icon/Icon-iPadPro@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon-iPadPro@2x.png -------------------------------------------------------------------------------- /Icon/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon.png -------------------------------------------------------------------------------- /Icon/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/Icon/Icon@2x.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | __This codebase has been deprecated in favor of our new implementation, found here:__ 4 | 5 | [https://github.com/standardnotes/mobile](https://github.com/standardnotes/mobile) 6 | 7 | What follows remains online for historical reasons. 8 | 9 | # Standard Notes for iOS (Classic) 10 | 11 | Run the app from Xcode on your device. 12 | 13 | Simply clone this repo, then update git submodules: 14 | 15 | ``` 16 | git clone https://github.com/standardnotes/iOS.git 17 | cd iOS 18 | git submodule update --init 19 | ``` 20 | 21 | ![app](https://github.com/standardnotes/iOS/blob/master/screenshots/small/1.png?raw=true) 22 | ![app](https://github.com/standardnotes/iOS/blob/master/screenshots/small/2.png?raw=true) 23 | ![app](https://github.com/standardnotes/iOS/blob/master/screenshots/small/3.png?raw=true) 24 | ![app](https://github.com/standardnotes/iOS/blob/master/screenshots/small/4.png?raw=true) 25 | 26 | ## License 27 | 28 | Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html 29 | -------------------------------------------------------------------------------- /screenshots/5.5-inch/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/5.5-inch/1.png -------------------------------------------------------------------------------- /screenshots/5.5-inch/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/5.5-inch/2.png -------------------------------------------------------------------------------- /screenshots/5.5-inch/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/5.5-inch/3.png -------------------------------------------------------------------------------- /screenshots/5.5-inch/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/5.5-inch/4.png -------------------------------------------------------------------------------- /screenshots/large/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/large/1.png -------------------------------------------------------------------------------- /screenshots/large/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/large/2.png -------------------------------------------------------------------------------- /screenshots/large/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/large/3.png -------------------------------------------------------------------------------- /screenshots/large/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/large/4.png -------------------------------------------------------------------------------- /screenshots/small/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/small/1.png -------------------------------------------------------------------------------- /screenshots/small/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/small/2.png -------------------------------------------------------------------------------- /screenshots/small/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/small/3.png -------------------------------------------------------------------------------- /screenshots/small/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/screenshots/small/4.png -------------------------------------------------------------------------------- /standardnotes-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import 6 | #import "NSData+Crypto.h" 7 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/project.xcworkspace/xcshareddata/standardnotes.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "79E4DA54FAC41C8AFB3B666E164C71E775A27450", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "79E4DA54FAC41C8AFB3B666E164C71E775A27450" : 9223372036854775807, 8 | "DEDD58F0BAF28034A74179391A23AC2E0219CDC3" : 9223372036854775807, 9 | "C3D8ED1CB28D809ADCE2C0DE74935E8A502ACD53" : 9223372036854775807, 10 | "C861FC00CEE0F6A6BE81FCFF6785FAA78C58EBB3" : 9223372036854775807, 11 | "67620B5EFA902936DF04070AF595B76AB0333747" : 9223372036854775807 12 | }, 13 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "6614577D-AFD4-48D3-837E-693D8F3C5232", 14 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 15 | "79E4DA54FAC41C8AFB3B666E164C71E775A27450" : "iOS\/", 16 | "DEDD58F0BAF28034A74179391A23AC2E0219CDC3" : "standardnotes\/vendor\/RNCryptor\/", 17 | "C3D8ED1CB28D809ADCE2C0DE74935E8A502ACD53" : "standardnotes\/vendor\/CryptoSwift\/", 18 | "C861FC00CEE0F6A6BE81FCFF6785FAA78C58EBB3" : "iOS\/vendor\/SwiftyJSON\/", 19 | "67620B5EFA902936DF04070AF595B76AB0333747" : "iOS\/vendor\/Alamofire\/" 20 | }, 21 | "DVTSourceControlWorkspaceBlueprintNameKey" : "standardnotes", 22 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 23 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "standardnotes.xcodeproj", 24 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 25 | { 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/Alamofire\/Alamofire.git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 28 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "67620B5EFA902936DF04070AF595B76AB0333747" 29 | }, 30 | { 31 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/standardnotes\/ios-client.git", 32 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 33 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "79E4DA54FAC41C8AFB3B666E164C71E775A27450" 34 | }, 35 | { 36 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/krzyzanowskim\/CryptoSwift.git", 37 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 38 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "C3D8ED1CB28D809ADCE2C0DE74935E8A502ACD53" 39 | }, 40 | { 41 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/SwiftyJSON\/SwiftyJSON.git", 42 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 43 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "C861FC00CEE0F6A6BE81FCFF6785FAA78C58EBB3" 44 | }, 45 | { 46 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/RNCryptor\/RNCryptor.git", 47 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 48 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "DEDD58F0BAF28034A74179391A23AC2E0219CDC3" 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /standardnotes.xcodeproj/project.xcworkspace/xcuserdata/mo.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes.xcodeproj/project.xcworkspace/xcuserdata/mo.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /standardnotes.xcodeproj/project.xcworkspace/xcuserdata/mobitar.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes.xcodeproj/project.xcworkspace/xcuserdata/mobitar.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /standardnotes.xcodeproj/xcuserdata/mo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/xcuserdata/mo.xcuserdatad/xcschemes/standardnotes.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/xcuserdata/mo.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | standardnotes.xcscheme 8 | 9 | orderHint 10 | 5 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | B82B6DF61E08AA660025C3EC 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/xcuserdata/mobitar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/xcuserdata/mobitar.xcuserdatad/xcschemes/standardnotes.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /standardnotes.xcodeproj/xcuserdata/mobitar.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | standardnotes.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | B82B6DF61E08AA660025C3EC 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /standardnotes/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/19/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreData 11 | import LocalAuthentication 12 | import HockeySDK 13 | import StoreKit 14 | 15 | @UIApplicationMain 16 | class AppDelegate: UIResponder, UIApplicationDelegate { 17 | 18 | var window: UIWindow? 19 | weak var lockOutAlertVC: UIAlertController? 20 | 21 | let numRunsBeforeAskingForReview = [5, 20, 50] 22 | 23 | var runCount: Int { 24 | get { 25 | return UserDefaults.standard.integer(forKey: "runCount") 26 | } 27 | set { 28 | UserDefaults.standard.set(newValue, forKey: "runCount") 29 | UserDefaults.standard.synchronize() 30 | } 31 | } 32 | 33 | static let sharedContext: NSManagedObjectContext = { 34 | let appDelegate = UIApplication.shared.delegate as! AppDelegate 35 | return appDelegate.persistentContainer.viewContext 36 | }() 37 | 38 | static let sharedInstance: AppDelegate = { 39 | return UIApplication.shared.delegate as! AppDelegate 40 | }() 41 | 42 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 43 | Theme.Initialize() 44 | ItemManager.initializeSharedInstance(context: self.persistentContainer.viewContext) 45 | attemptFingerPrint() 46 | initializeCrashReporting() 47 | SyncController.sharedInstance.startSyncing() 48 | handleAppStoreReviewLogic() 49 | return true 50 | } 51 | 52 | func handleAppStoreReviewLogic() { 53 | if #available(iOS 10.3, *) { 54 | runCount += 1 55 | if(numRunsBeforeAskingForReview.contains(runCount)) { 56 | SKStoreReviewController.requestReview() 57 | } 58 | } 59 | } 60 | 61 | func initializeCrashReporting() { 62 | BITHockeyManager.shared().configure(withIdentifier: "f6d12c22bdad48e5a07aa578822b4620") 63 | BITHockeyManager.shared().isMetricsManagerDisabled = true 64 | BITHockeyManager.shared().start() 65 | BITHockeyManager.shared().authenticator.authenticateInstallation() 66 | } 67 | 68 | func applicationWillResignActive(_ application: UIApplication) { 69 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 70 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 71 | } 72 | 73 | func applicationDidEnterBackground(_ application: UIApplication) { 74 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 75 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 76 | 77 | if UserManager.sharedInstance.touchIDEnabled { 78 | showLockedController() 79 | } 80 | SyncController.sharedInstance.stopSyncing() 81 | } 82 | 83 | func applicationWillEnterForeground(_ application: UIApplication) { 84 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 85 | attemptFingerPrint() 86 | SyncController.sharedInstance.startSyncing() 87 | } 88 | 89 | func applicationDidBecomeActive(_ application: UIApplication) { 90 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 91 | 92 | } 93 | 94 | func applicationWillTerminate(_ application: UIApplication) { 95 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 96 | // Saves changes in the application's managed object context before the application terminates. 97 | self.saveContext() 98 | } 99 | 100 | // MARK: - Core Data stack 101 | 102 | lazy var persistentContainer: NSPersistentContainer = { 103 | 104 | let container = NSPersistentContainer(name: "standardnotes") 105 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in 106 | if let error = error as NSError? { 107 | 108 | fatalError("Unresolved error \(error), \(error.userInfo)") 109 | } 110 | }) 111 | return container 112 | }() 113 | 114 | // MARK: - Core Data Saving support 115 | 116 | func saveContext () { 117 | 118 | let context = persistentContainer.viewContext 119 | if context.hasChanges { 120 | do { 121 | try context.save() 122 | } catch { 123 | let nserror = error as NSError 124 | fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 125 | } 126 | } 127 | } 128 | 129 | var lockedVC: LockedViewController? 130 | 131 | func showLockedController() { 132 | if self.lockedVC != nil { 133 | return 134 | } 135 | 136 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 137 | self.lockedVC = storyboard.instantiateViewController(withIdentifier: "LockedVC") as? LockedViewController 138 | (UIApplication.shared.keyWindow?.rootViewController?.topMostViewController())?.present(self.lockedVC!, animated: false, completion: nil) 139 | } 140 | 141 | func hideLockedController(afterDelay: Double) { 142 | // return tab to accounts page 143 | delay(afterDelay) { 144 | self.lockedVC?.dismiss(animated: true, completion: nil) 145 | self.lockedVC = nil 146 | } 147 | } 148 | 149 | func attemptFingerPrint(){ 150 | lockOutAlertVC?.dismiss(animated: false, completion: nil) 151 | lockOutAlertVC = nil 152 | guard UserManager.sharedInstance.touchIDEnabled else { return } 153 | UIApplication.shared.beginIgnoringInteractionEvents() 154 | 155 | delay(0.01) { 156 | self.showLockedController() 157 | } 158 | 159 | let touchIDContext = LAContext() 160 | var error : NSError? 161 | let reasonString = "Authentication is needed to access your notes." 162 | if touchIDContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error){ 163 | touchIDContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { [weak self] (success, touchIDError) in 164 | guard success else { 165 | print(error?.localizedDescription ?? "Touch ID Error") 166 | OperationQueue.main.addOperation { 167 | UIApplication.shared.endIgnoringInteractionEvents() 168 | self?.presentLockAlert() 169 | } 170 | return 171 | } 172 | UIApplication.shared.endIgnoringInteractionEvents() 173 | self?.hideLockedController(afterDelay: 0.01) 174 | }) 175 | } else { 176 | print(error?.localizedDescription ?? "Touch ID Error") 177 | 178 | // Do PIN code auth 179 | let context = LAContext() 180 | context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reasonString, reply: { [weak self] (success, error) in 181 | guard success else { 182 | print(error?.localizedDescription ?? "Touch ID Error") 183 | OperationQueue.main.addOperation { 184 | UIApplication.shared.endIgnoringInteractionEvents() 185 | self?.presentLockAlert() 186 | } 187 | return 188 | } 189 | UIApplication.shared.endIgnoringInteractionEvents() 190 | self?.hideLockedController(afterDelay: 0.01) 191 | 192 | }) 193 | } 194 | 195 | } 196 | 197 | func presentLockAlert(){ 198 | guard lockOutAlertVC == nil else { 199 | return 200 | } 201 | let alertController = UIAlertController(title: "Fingerprint Required", message: "Notes are locked with Touch ID. Please try again.", preferredStyle: .alert) 202 | let retryTouchIDAction = UIAlertAction(title: "Try Again", style: .default, handler: { [weak self] 203 | alert -> Void in 204 | self?.attemptFingerPrint() 205 | }) 206 | alertController.addAction(retryTouchIDAction) 207 | self.lockedVC?.present(alertController, animated: true, completion: nil) 208 | lockOutAlertVC = alertController 209 | 210 | } 211 | 212 | } 213 | 214 | -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "size" : "29x29", 15 | "idiom" : "iphone", 16 | "filename" : "Icon-Small@2x.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "Icon-Small@3x.png", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "40x40", 27 | "idiom" : "iphone", 28 | "filename" : "Icon-Spotlight-40@2x.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "size" : "40x40", 33 | "idiom" : "iphone", 34 | "filename" : "Icon-Spotlight-40@3x.png", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "size" : "60x60", 39 | "idiom" : "iphone", 40 | "filename" : "Icon-60@2x.png", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "size" : "60x60", 45 | "idiom" : "iphone", 46 | "filename" : "Icon-60@3x.png", 47 | "scale" : "3x" 48 | }, 49 | { 50 | "idiom" : "ipad", 51 | "size" : "20x20", 52 | "scale" : "1x" 53 | }, 54 | { 55 | "idiom" : "ipad", 56 | "size" : "20x20", 57 | "scale" : "2x" 58 | }, 59 | { 60 | "size" : "29x29", 61 | "idiom" : "ipad", 62 | "filename" : "Icon-Small.png", 63 | "scale" : "1x" 64 | }, 65 | { 66 | "size" : "29x29", 67 | "idiom" : "ipad", 68 | "filename" : "Icon-Small@2x copy.png", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "size" : "40x40", 73 | "idiom" : "ipad", 74 | "filename" : "Icon-Spotlight-40.png", 75 | "scale" : "1x" 76 | }, 77 | { 78 | "size" : "40x40", 79 | "idiom" : "ipad", 80 | "filename" : "Icon-Spotlight-40@2x copy.png", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "size" : "76x76", 85 | "idiom" : "ipad", 86 | "filename" : "Icon-76.png", 87 | "scale" : "1x" 88 | }, 89 | { 90 | "size" : "76x76", 91 | "idiom" : "ipad", 92 | "filename" : "Icon-76@2x.png", 93 | "scale" : "2x" 94 | }, 95 | { 96 | "size" : "83.5x83.5", 97 | "idiom" : "ipad", 98 | "filename" : "Icon-iPadPro@2x.png", 99 | "scale" : "2x" 100 | } 101 | ], 102 | "info" : { 103 | "version" : 1, 104 | "author" : "xcode" 105 | } 106 | } -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-60.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-76@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-76@3x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x copy.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x copy.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon-iPadPro@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/ico-account.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ico-account@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ico-account@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/ico-account.imageset/ico-account@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/ico-account.imageset/ico-account@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/ico-account.imageset/ico-account@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/ico-account.imageset/ico-account@3x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/ico-list.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ico-list@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ico-list@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/ico-list.imageset/ico-list@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/ico-list.imageset/ico-list@2x.png -------------------------------------------------------------------------------- /standardnotes/Assets.xcassets/ico-list.imageset/ico-list@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standardnotes/iOS-classic/ea80d5001c72c4bf5d8c45ec9faff50873e7f70a/standardnotes/Assets.xcassets/ico-list.imageset/ico-list@3x.png -------------------------------------------------------------------------------- /standardnotes/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /standardnotes/ComposeViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComposeViewController.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/21/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreData 11 | 12 | class ComposeViewController: UIViewController { 13 | 14 | @IBOutlet weak var titleTextField: UITextField! 15 | @IBOutlet weak var textView: UITextView! 16 | var note: Note! 17 | var saving: Bool = false 18 | var saved: Bool = false 19 | var saveTimer: Timer! 20 | var ignoreKVO = false 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | self.automaticallyAdjustsScrollViewInsets = false 25 | 26 | textView.layoutManager.delegate = self 27 | textView.textContainerInset = UIEdgeInsetsMake(12, 12, 12, 12) 28 | 29 | configureNote() 30 | configureNavBar() 31 | configureKeyboardNotifications() 32 | 33 | titleTextField.text = self.note?.safeTitle() 34 | textView.text = self.note?.safeText() 35 | 36 | self.note.addObserver(self, forKeyPath: "text", options: [.new], context: nil) 37 | self.note.addObserver(self, forKeyPath: "title", options: [.new], context: nil) 38 | } 39 | 40 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 41 | 42 | if(ignoreKVO) { 43 | return 44 | } 45 | 46 | if(keyPath == "text") { 47 | textView.text = (object as! Note).safeText() 48 | } else if(keyPath == "title") { 49 | titleTextField.text = (object as! Note).safeTitle() 50 | } 51 | } 52 | 53 | deinit { 54 | self.note.removeObserver(self, forKeyPath: "text") 55 | self.note.removeObserver(self, forKeyPath: "title") 56 | } 57 | 58 | func configureKeyboardNotifications() { 59 | NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(aNotification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil) 60 | NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(aNotification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil) 61 | } 62 | 63 | func keyboardWasShown(aNotification:NSNotification) { 64 | let info = aNotification.userInfo 65 | let infoNSValue = info![UIKeyboardFrameEndUserInfoKey] as! NSValue 66 | let kbSize = infoNSValue.cgRectValue.size 67 | let contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0) 68 | textView.contentInset = contentInsets 69 | textView.scrollIndicatorInsets = contentInsets 70 | } 71 | 72 | func keyboardWillBeHidden(aNotification:NSNotification) { 73 | let contentInsets = UIEdgeInsets.zero 74 | textView.contentInset = contentInsets 75 | textView.scrollIndicatorInsets = contentInsets 76 | } 77 | 78 | override func viewDidLayoutSubviews() { 79 | super.viewDidLayoutSubviews() 80 | } 81 | 82 | override func viewWillAppear(_ animated: Bool) { 83 | super.viewWillAppear(animated) 84 | if self.note.text == nil { 85 | self.textView.becomeFirstResponder() 86 | } 87 | } 88 | 89 | override func viewDidAppear(_ animated: Bool) { 90 | super.viewDidAppear(animated) 91 | } 92 | 93 | func configureNavBar() { 94 | let tagsTitle = note.tags!.count > 0 ? "Tags (\(note.tags!.count))" : "Tags" 95 | self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: tagsTitle, style: .plain, target: self, action: #selector(tagsPressed)) 96 | } 97 | 98 | func reloadTitleBar(offline: Bool) { 99 | let titleString = NSMutableAttributedString(string: "Compose" + (saving || saved ? "\n" : ""), attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 17.0)]) 100 | 101 | if saving || saved { 102 | let subtitleAttribute = [NSForegroundColorAttributeName: offline ? UIColor.red : UIColor.gray , NSFontAttributeName: UIFont.systemFont(ofSize: 12.0)] 103 | let string = offline ? "Offline" : (saving ? "Saving..." : "All changes saved") 104 | let subtitleString = NSAttributedString(string: string, attributes: subtitleAttribute) 105 | titleString.append(subtitleString) 106 | } 107 | 108 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: titleString.size().width, height: 44)) 109 | label.numberOfLines = 0 110 | label.textAlignment = NSTextAlignment.center 111 | label.attributedText = titleString 112 | self.navigationItem.titleView = label 113 | } 114 | 115 | let NoteTitlePlaceholder = "" 116 | 117 | func configureNote() { 118 | if self.note == nil { 119 | self.note = NSEntityDescription.insertNewObject(forEntityName: "Note", into: AppDelegate.sharedContext) as! Note 120 | self.note.title = NoteTitlePlaceholder 121 | self.note.dirty = true 122 | self.note.draft = true 123 | } 124 | } 125 | 126 | func tagsPressed() { 127 | let tags = self.storyboard?.instantiateViewController(withIdentifier: "Tags") as! TagsViewController 128 | tags.setInitialSelectedTags(tags: self.note.tags?.allObjects as! [Tag]) 129 | tags.hasSortType = false 130 | tags.selectionCompletion = { tags, sort in 131 | self.note.replaceTags(withTags: tags) 132 | self.configureNavBar() 133 | self.save() 134 | } 135 | 136 | self.navigationController?.pushViewController(tags, animated: true) 137 | } 138 | 139 | func save() { 140 | saving = true 141 | saved = false 142 | reloadTitleBar(offline: false) 143 | 144 | ignoreKVO = true 145 | self.note.title = self.titleTextField.text 146 | self.note.text = self.textView.text 147 | ignoreKVO = false 148 | 149 | self.note.draft = false 150 | self.note.dirty = true 151 | ApiController.sharedInstance.sync { error in 152 | self.saving = false 153 | self.saved = true 154 | 155 | if error == nil { 156 | delay(0.1, closure: { 157 | self.reloadTitleBar(offline: false) 158 | }) 159 | } else { 160 | delay(0.2, closure: { 161 | self.reloadTitleBar(offline: true) 162 | }) 163 | 164 | if(!SyncController.sharedInstance.didShowOfflineErrorAlert) { 165 | self.showAlert(title: "Oops", message: "There was an error saving your data to the server. Please check your server settings and try again.") 166 | SyncController.sharedInstance.didShowOfflineErrorAlert = true 167 | } 168 | } 169 | } 170 | } 171 | 172 | @IBAction func titleFieldEditingChanged(_ sender: Any) { 173 | beginSaveTimer() 174 | } 175 | 176 | } 177 | 178 | extension ComposeViewController : NSLayoutManagerDelegate { 179 | 180 | func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat { 181 | return 2 182 | } 183 | 184 | } 185 | 186 | extension ComposeViewController : UITextViewDelegate { 187 | func beginSaveTimer() { 188 | if saveTimer != nil { 189 | saveTimer.invalidate() 190 | } 191 | saveTimer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: false, block: { (timer) in 192 | self.save() 193 | }) 194 | } 195 | 196 | func textViewDidChange(_ textView: UITextView) { 197 | beginSaveTimer() 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /standardnotes/EncryptionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EncryptionViewController.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 4/26/17. 6 | // Copyright © 2017 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class EncryptionViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /standardnotes/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | S. Notes 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.3.4 19 | CFBundleVersion 20 | 13 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /standardnotes/Item+CoreDataClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Item+CoreDataClass.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/19/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | public class Item: NSManagedObject { 13 | 14 | public override func awakeFromInsert() { 15 | super.awakeFromInsert() 16 | if self.uuid == nil { 17 | self.uuid = UUID().uuidString 18 | } 19 | 20 | self.createdAt = Date() 21 | self.updatedAt = Date() 22 | } 23 | 24 | func updateFromJSON(json: JSON) { 25 | self.uuid = json["uuid"].string! 26 | self.contentType = json["content_type"].string! 27 | 28 | if json["enc_item_key"] != JSON.null { 29 | self.encItemKey = json["enc_item_key"].string 30 | } 31 | 32 | if let errorDecrypting = json["error_decrypting"].bool { 33 | self.errorDecrypting = errorDecrypting 34 | } else { 35 | self.errorDecrypting = false 36 | } 37 | 38 | self.createdAt = dateFromString(string: json["created_at"].string!) 39 | self.updatedAt = dateFromString(string: json["updated_at"].string!) 40 | 41 | if json["content"] != JSON.null { 42 | self.content = json["content"].string! 43 | mapContentToLocalProperties(contentObject: contentObject) 44 | } 45 | } 46 | 47 | func dateFromString(string: String) -> Date { 48 | let dateFormatter = DateFormatter() 49 | dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 50 | let date = dateFormatter.date(from: string) 51 | return date != nil ? date! : Date() 52 | } 53 | 54 | func stringFromDate(date: Date) -> String { 55 | let dateFormatter = DateFormatter() 56 | dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 57 | let string = dateFormatter.string(from: date) 58 | return string 59 | } 60 | 61 | func humanReadableCreateDate() -> String { 62 | let dateFormatter = DateFormatter() 63 | dateFormatter.dateStyle = .short 64 | dateFormatter.timeStyle = .short 65 | let string = dateFormatter.string(from: self.createdAt) 66 | return string 67 | } 68 | 69 | var contentObject: JSON { 70 | return JSON(content!.data(using: .utf8, allowLossyConversion: false)!) 71 | } 72 | 73 | func createContentJSONFromProperties() -> JSON { 74 | return self.buildFullContentObject() 75 | } 76 | 77 | func canDelete() -> Bool { 78 | return true 79 | } 80 | 81 | // called when sharing an item and related items should be synced as well 82 | func markRelatedItemsAsDirty() { 83 | // override 84 | } 85 | 86 | func mapContentToLocalProperties(contentObject: JSON) { 87 | 88 | } 89 | 90 | func addItemAsRelationship(item: Item) { 91 | 92 | } 93 | 94 | func clearReferences() { 95 | 96 | } 97 | 98 | func buildFullContentObject() -> JSON { 99 | var params = [String : Any]() 100 | params.merge(with: structureParams()) 101 | return JSON(params) 102 | } 103 | 104 | func referencesParams() -> [[String : String]] { 105 | fatalError("This method must be overridden") 106 | } 107 | 108 | func structureParams() -> [String : Any] { 109 | return ["references" : referencesParams()] 110 | } 111 | 112 | var encryptionEnabled: Bool { 113 | return self.encItemKey != nil 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /standardnotes/Item+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Item+CoreDataProperties.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/19/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | extension Item { 14 | 15 | @nonobjc public class func fetchRequest() -> NSFetchRequest { 16 | return NSFetchRequest(entityName: "Item"); 17 | } 18 | 19 | @NSManaged public var uuid: String! 20 | @NSManaged public var content: String? 21 | @NSManaged public var contentType: String! 22 | @NSManaged public var encItemKey: String? 23 | @NSManaged public var dirty: Bool 24 | @NSManaged public var draft: Bool 25 | @NSManaged public var modelDeleted: Bool 26 | @NSManaged public var errorDecrypting: Bool 27 | 28 | @NSManaged public var createdAt: Date 29 | @NSManaged public var updatedAt: Date 30 | } 31 | -------------------------------------------------------------------------------- /standardnotes/ItemManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ItemManager.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/20/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | class ItemManager { 13 | 14 | let context: NSManagedObjectContext! 15 | 16 | init(context: NSManagedObjectContext) { 17 | self.context = context 18 | } 19 | 20 | private static var _sharedInstance: ItemManager! 21 | 22 | static let sharedInstance : ItemManager = { 23 | return _sharedInstance 24 | }() 25 | 26 | static func initializeSharedInstance(context: NSManagedObjectContext) { 27 | _sharedInstance = ItemManager(context: context) 28 | } 29 | 30 | lazy var supportedItemTypes: [String] = { 31 | return AppDelegate.sharedInstance.persistentContainer.managedObjectModel.entities.map({ (entity) -> String in 32 | return entity.name! 33 | }) 34 | }() 35 | 36 | func mapResponseItemsToLocalItems(responseItems: [JSON], omitFields: [String]?) -> [Item] { 37 | var items: [Item] = [] 38 | for var responseItem in responseItems { 39 | let contentType = responseItem["content_type"].string 40 | if contentType == nil || supportedItemTypes.contains(contentType!) == false { 41 | continue; 42 | } 43 | if responseItem["deleted"].boolValue == true { 44 | let item = findItem(uuid: responseItem["uuid"].string!, contentType: contentType!) 45 | if item != nil { 46 | context.delete(item!) 47 | } 48 | continue 49 | } 50 | let item = findOrCreateItem(uuid: responseItem["uuid"].string!, contentType: contentType!) 51 | if omitFields != nil { 52 | for omitField in omitFields! { 53 | responseItem[omitField] = JSON.null 54 | } 55 | } 56 | item.updateFromJSON(json: responseItem) 57 | if responseItem["content"] != JSON.null { 58 | resolveReferences(forItem: item) 59 | } 60 | items.append(item) 61 | } 62 | self.saveContext() 63 | return items 64 | } 65 | 66 | func findOrCreateItem(uuid: String, contentType: String) -> Item { 67 | var item = findItem(uuid: uuid, contentType: contentType) 68 | if item == nil { 69 | item = NSEntityDescription.insertNewObject(forEntityName: contentType, into: self.context) as? Item 70 | } 71 | 72 | assert(item != nil) 73 | return item! 74 | } 75 | 76 | func createItem(json: JSON) -> Item { 77 | let item = NSEntityDescription.insertNewObject(forEntityName: json["content_type"].string!, into: self.context) as! Item 78 | item.updateFromJSON(json: json) 79 | if json["content"] != JSON.null { 80 | resolveReferences(forItem: item) 81 | } 82 | return item 83 | } 84 | 85 | func findItem(uuid: String, contentType: String) -> Item? { 86 | let fetchRequest = NSFetchRequest(entityName: contentType) 87 | fetchRequest.predicate = NSPredicate(format: "uuid = %@", uuid) 88 | do { 89 | let results = try self.context.fetch(fetchRequest) 90 | if results.count > 0 { 91 | return results.first as? Item 92 | } 93 | } 94 | catch { 95 | print("Error finding item: \(error)") 96 | } 97 | 98 | return nil 99 | } 100 | 101 | func findTag(byTitle title: String) -> Tag? { 102 | let fetchRequest = NSFetchRequest(entityName: "Tag") 103 | fetchRequest.predicate = NSPredicate(format: "title = %@", title) 104 | do { 105 | let results = try self.context.fetch(fetchRequest) 106 | if results.count > 0 { 107 | return results.first! as Tag 108 | } 109 | } 110 | catch { 111 | print("Error finding item: \(error)") 112 | } 113 | 114 | return nil 115 | } 116 | 117 | func createTag(title: String) -> Tag { 118 | let tag = NSEntityDescription.insertNewObject(forEntityName: "Tag", into: self.context) as! Tag 119 | tag.title = title 120 | return tag 121 | } 122 | 123 | func fetchDirty() -> [Item] { 124 | let dirty = NSFetchRequest(entityName: "Item") 125 | dirty.predicate = NSPredicate(format: "dirty == true AND draft == false") 126 | do { 127 | let items = try AppDelegate.sharedContext.fetch(dirty) 128 | return items 129 | } 130 | catch { 131 | fatalError("Error fetching items.") 132 | } 133 | } 134 | 135 | func clearDirty(items: [Item]) { 136 | for item in items { 137 | item.dirty = false 138 | } 139 | saveContext() 140 | } 141 | 142 | func resolveReferences(forItem item: Item) { 143 | item.clearReferences() 144 | let references = item.contentObject["references"].arrayValue 145 | for reference in references { 146 | let uuid = reference["uuid"].stringValue 147 | let contentType = reference["content_type"].stringValue 148 | let referencedItem = findItem(uuid: uuid, contentType: contentType) 149 | if referencedItem != nil { 150 | item.addItemAsRelationship(item: referencedItem!) 151 | } else { 152 | // print("Unable to find referenced item.") 153 | } 154 | } 155 | } 156 | 157 | func saveContext () { 158 | if context.hasChanges { 159 | do { 160 | try context.save() 161 | print("Successfully saved context.") 162 | } catch { 163 | let nserror = error as NSError 164 | fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 165 | } 166 | } 167 | } 168 | 169 | func setItemToBeDeleted(item: Item) { 170 | item.modelDeleted = true 171 | item.dirty = true 172 | } 173 | 174 | func removeItemFromCoreData(item: Item) { 175 | context.delete(item) 176 | saveContext() 177 | } 178 | 179 | func deleteAllItemsForEntityName(name: String) { 180 | let fetchRequest = NSFetchRequest(entityName: name) 181 | let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) 182 | let coordinator = AppDelegate.sharedInstance.persistentContainer.persistentStoreCoordinator 183 | do { 184 | try coordinator.execute(deleteRequest, with: context) 185 | } catch let error as NSError { 186 | print("Error deleting items: \(error)") 187 | } 188 | } 189 | 190 | func signOut() { 191 | deleteAllItemsForEntityName(name: "Item") 192 | } 193 | 194 | func itemsExportJSONData(encrypted: Bool) -> Data { 195 | let fetchRequest = NSFetchRequest(entityName: "Item") 196 | do { 197 | let items = try AppDelegate.sharedContext.fetch(fetchRequest) 198 | let params = items.map { (item) -> [String : Any] in 199 | return ApiController.sharedInstance.exportParamsForItem(item: item, encrypted: encrypted) 200 | } 201 | var json = JSON(["items" : params]) 202 | if encrypted { 203 | json["auth_params"] = JSON(UserManager.sharedInstance.authParams!) 204 | } 205 | let data = try JSONSerialization.data(withJSONObject: json.object, options: .prettyPrinted) 206 | return data 207 | } 208 | catch { 209 | fatalError("Error fetching items.") 210 | } 211 | 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /standardnotes/LockedViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LockedViewController.swift 3 | // standardnotes 4 | // 5 | // Created by mo on 8/23/17. 6 | // Copyright © 2017 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LockedViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /standardnotes/NSData+Crypto.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Crypto.h 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/20/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSData * AES128CBC(NSString *op, NSData * data, NSData * key, NSData *iv); 12 | extern NSData *HMAC256(NSData *data, NSData *keyData); 13 | extern NSData *SHA1(NSData *messageData); 14 | -------------------------------------------------------------------------------- /standardnotes/NSData+Crypto.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Crypto.m 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/20/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | #import "NSData+Crypto.h" 10 | #import 11 | 12 | extern NSData * AES128CBC(NSString *op, NSData * data, NSData * key, NSData *iv) { 13 | CCCryptorStatus err; 14 | NSMutableData * result; 15 | size_t resultLength; 16 | 17 | // NSLog(@"Key length is: %lu Should be: %i", (unsigned long)key.length, kCCKeySizeAES256); 18 | 19 | NSCParameterAssert(key.length == kCCKeySizeAES256); 20 | // NSCParameterAssert(iv.length == kCCBlockSizeAES128); 21 | 22 | // Padding can expand the data, so we have to allocate space for that. The rule for block 23 | // cyphers, like AES, is that the padding only adds space on encryption (on decryption it 24 | // can reduce space, obviously, but we don't need to account for that) and it will only add 25 | // at most one block size worth of space. 26 | 27 | result = [[NSMutableData alloc] initWithLength:[data length] + kCCBlockSizeAES128]; 28 | 29 | err = CCCrypt( 30 | [op isEqualToString:@"encrypt"] ? kCCEncrypt : kCCDecrypt, 31 | kCCAlgorithmAES128, 32 | kCCOptionPKCS7Padding, 33 | key.bytes, key.length, 34 | iv.bytes, 35 | data.bytes, data.length, 36 | result.mutableBytes, result.length, 37 | &resultLength 38 | ); 39 | assert(err == kCCSuccess); 40 | 41 | // Set the output length to the value returned by CCCrypt. This is necessary because 42 | // we have padding enabled, meaning that we might have allocated more space than we needed. 43 | 44 | [result setLength:resultLength]; 45 | 46 | return result; 47 | } 48 | 49 | extern NSData *HMAC256(NSData *messageData, NSData *keyData) { 50 | NSMutableData *result = [[NSMutableData alloc] initWithLength:CC_SHA256_DIGEST_LENGTH]; 51 | CCHmac(kCCHmacAlgSHA256, keyData.bytes, keyData.length, messageData.bytes, messageData.length, result.mutableBytes); 52 | return result; 53 | } 54 | 55 | extern NSData *SHA1(NSData *messageData) { 56 | NSMutableData *result = [[NSMutableData alloc] initWithLength:CC_SHA1_DIGEST_LENGTH]; 57 | CC_SHA1(messageData.bytes, (u_int32_t)messageData.length, result.mutableBytes); 58 | return result; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /standardnotes/Note+CoreDataClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Note+CoreDataClass.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/20/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | public class Note: Item { 14 | 15 | override func mapContentToLocalProperties(contentObject: JSON) { 16 | super.mapContentToLocalProperties(contentObject: contentObject) 17 | self.title = contentObject["title"].string 18 | self.text = contentObject["text"].string 19 | } 20 | 21 | public override func awakeFromInsert() { 22 | super.awakeFromInsert() 23 | self.contentType = "Note" 24 | } 25 | 26 | override func structureParams() -> [String : Any] { 27 | return [ 28 | "title" : safeTitle(), 29 | "text" : safeText() 30 | ].merged(with: super.structureParams()) 31 | } 32 | 33 | override func referencesParams() -> [[String : String]] { 34 | var references = [[String : String]]() 35 | for tag in self.tags?.allObjects as! [Tag] { 36 | references.append(["uuid" : tag.uuid, "content_type" : tag.contentType]) 37 | } 38 | return references 39 | } 40 | 41 | override func addItemAsRelationship(item: Item) { 42 | if item.contentType == "Tag" { 43 | self.addToTags(item as! Tag) 44 | } 45 | super.addItemAsRelationship(item: item) 46 | } 47 | 48 | func replaceTags(withTags tags: [Tag]) { 49 | for currentTag in self.tags?.allObjects as! [Tag] { 50 | currentTag.dirty = true 51 | } 52 | for newTag in tags { 53 | newTag.dirty = true 54 | } 55 | 56 | self.removeFromTags(self.tags!) 57 | self.addToTags(NSSet(array: tags)) 58 | } 59 | 60 | override func markRelatedItemsAsDirty() { 61 | 62 | } 63 | 64 | override func clearReferences() { 65 | self.removeFromTags(self.tags!) 66 | super.clearReferences() 67 | } 68 | 69 | func safeTitle() -> String { 70 | return (self.title != nil) ? self.title! : "" 71 | } 72 | 73 | func safeText() -> String { 74 | return (self.text != nil) ? self.text! : "" 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /standardnotes/Note+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Note+CoreDataProperties.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/20/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | extension Note { 14 | 15 | @nonobjc public class func fetchRequest() -> NSFetchRequest { 16 | return NSFetchRequest(entityName: "Note"); 17 | } 18 | 19 | @NSManaged public var title: String? 20 | @NSManaged public var text: String? 21 | 22 | @NSManaged public var tags: NSSet? 23 | 24 | } 25 | 26 | // MARK: Generated accessors for tags 27 | extension Note { 28 | 29 | @objc(addTagsObject:) 30 | @NSManaged public func addToTags(_ value: Tag) 31 | 32 | @objc(removeTagsObject:) 33 | @NSManaged public func removeFromTags(_ value: Tag) 34 | 35 | @objc(addTags:) 36 | @NSManaged public func addToTags(_ values: NSSet) 37 | 38 | @objc(removeTags:) 39 | @NSManaged public func removeFromTags(_ values: NSSet) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /standardnotes/Note.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Note.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/20/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class Note : Structure { 12 | 13 | var title: String! 14 | var text: String! 15 | 16 | override func mapContentToLocalProperties() { 17 | super.mapContentToLocalProperties() 18 | self.title = self.content["title"].string! 19 | self.text = self.content["text"].string! 20 | 21 | print("Set title: \(self.title) text: \(self.text)") 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /standardnotes/NoteTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NoteTableViewCell.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/23/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class NoteTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var titleLabel: UILabel! 14 | @IBOutlet weak var contentLabel: UILabel! 15 | @IBOutlet weak var dateLabel: UILabel! 16 | 17 | var note: Note! 18 | var longPressHandler: ((NoteTableViewCell) -> ())! 19 | var longPress: UILongPressGestureRecognizer! 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | configureLongPress() 24 | } 25 | 26 | func configureLongPress() { 27 | longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressStateDidChange(gesture:))) 28 | addGestureRecognizer(longPress) 29 | } 30 | 31 | func longPressStateDidChange(gesture: UIGestureRecognizer) { 32 | if gesture.state == .began { 33 | longPressHandler(self) 34 | } 35 | } 36 | 37 | override func layoutSubviews() { 38 | super.layoutSubviews() 39 | 40 | if note.errorDecrypting { 41 | titleLabel.textColor = UIColor.red 42 | } else { 43 | titleLabel.textColor = UIColor.black 44 | } 45 | } 46 | 47 | override func setSelected(_ selected: Bool, animated: Bool) { 48 | super.setSelected(selected, animated: animated) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /standardnotes/SyncController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SyncController.swift 3 | // standardnotes 4 | // 5 | // Created by Jay Zisch on 2017/02/04. 6 | // Copyright © 2017 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class SyncController { 12 | 13 | static var sharedInstance = SyncController() 14 | 15 | var didShowOfflineErrorAlert = false 16 | 17 | var syncTimer : Timer? 18 | let syncTimeInterval : TimeInterval = 30 19 | 20 | func startSyncing() { 21 | syncTimer?.invalidate() 22 | syncTimer = Timer.scheduledTimer(withTimeInterval: syncTimeInterval, repeats: true, block: { (timer) in 23 | self.performSync() 24 | }) 25 | } 26 | 27 | func performSync() { 28 | ApiController.sharedInstance.sync(completion: { (error) in}) 29 | } 30 | 31 | func stopSyncing() { 32 | syncTimer?.invalidate() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /standardnotes/TabBarViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarViewController.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/23/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TabBarViewController: UITabBarController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | if UserManager.sharedInstance.signedIn == false { 17 | self.selectedIndex = 1 18 | } 19 | 20 | if let accountNav = self.viewControllers!.last as? UINavigationController { 21 | if let accountVc = accountNav.viewControllers.first as? AccountViewController { 22 | accountVc.accountStatusChanged = { signIn in 23 | if signIn { 24 | self.selectedIndex = 0 25 | } 26 | } 27 | } 28 | } 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /standardnotes/Tag+CoreDataClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tag+CoreDataClass.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/22/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | public class Tag: Item { 14 | 15 | override func mapContentToLocalProperties(contentObject: JSON) { 16 | super.mapContentToLocalProperties(contentObject: contentObject) 17 | self.title = contentObject["title"].string 18 | } 19 | 20 | public override func awakeFromInsert() { 21 | super.awakeFromInsert() 22 | self.contentType = "Tag" 23 | } 24 | 25 | override func structureParams() -> [String : Any] { 26 | return [ 27 | "title" : safeTitle(), 28 | ].merged(with: super.structureParams()) 29 | } 30 | 31 | override func referencesParams() -> [[String : String]] { 32 | var references = [[String : String]]() 33 | for note in self.notes?.allObjects as! [Note] { 34 | references.append(["uuid" : note.uuid, "content_type" : note.contentType]) 35 | } 36 | return references 37 | } 38 | 39 | override func addItemAsRelationship(item: Item) { 40 | if item.contentType == "Note" { 41 | self.addToNotes(item as! Note) 42 | } 43 | } 44 | 45 | override func markRelatedItemsAsDirty() { 46 | for note in self.notes!.allObjects as! [Note] { 47 | note.dirty = true 48 | } 49 | } 50 | 51 | override func clearReferences() { 52 | self.removeFromNotes(self.notes!) 53 | super.clearReferences() 54 | } 55 | 56 | override func canDelete() -> Bool { 57 | return self.notes!.count == 0 58 | } 59 | 60 | func safeTitle() -> String { 61 | return (self.title != nil) ? self.title! : "" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /standardnotes/Tag+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tag+CoreDataProperties.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/22/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | extension Tag { 14 | 15 | @nonobjc public class func fetchRequest() -> NSFetchRequest { 16 | return NSFetchRequest(entityName: "Tag"); 17 | } 18 | 19 | @NSManaged public var title: String? 20 | @NSManaged public var notes: NSSet? 21 | 22 | } 23 | 24 | // MARK: Generated accessors for notes 25 | extension Tag { 26 | 27 | @objc(addNotesObject:) 28 | @NSManaged public func addToNotes(_ value: Note) 29 | 30 | @objc(removeNotesObject:) 31 | @NSManaged public func removeFromNotes(_ value: Note) 32 | 33 | @objc(addNotes:) 34 | @NSManaged public func addToNotes(_ values: NSSet) 35 | 36 | @objc(removeNotes:) 37 | @NSManaged public func removeFromNotes(_ values: NSSet) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /standardnotes/TagTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TagTableViewCell.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/23/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TagTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var titleLabel: UILabel! 14 | @IBOutlet weak var `switch`: UISwitch! 15 | var tagObject: Tag! 16 | var selectionStateChanged: ((TagTableViewCell, Bool) -> ())! 17 | 18 | var longPressHandler: ((TagTableViewCell) -> ())! 19 | var longPress: UILongPressGestureRecognizer! 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | configureLongPress() 24 | } 25 | 26 | func configureLongPress() { 27 | longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressStateDidChange(gesture:))) 28 | addGestureRecognizer(longPress) 29 | } 30 | 31 | func longPressStateDidChange(gesture: UIGestureRecognizer) { 32 | if gesture.state == .began { 33 | longPressHandler(self) 34 | } 35 | } 36 | 37 | @IBAction func switchValueChanged(_ sender: UISwitch) { 38 | self.selectionStateChanged(self, sender.isOn) 39 | } 40 | 41 | override func setSelected(_ selected: Bool, animated: Bool) { 42 | super.setSelected(selected, animated: animated) 43 | 44 | // Configure the view for the selected state 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /standardnotes/TagsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TagsViewController.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/22/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreData 11 | 12 | 13 | class TagsViewController: UIViewController { 14 | 15 | enum Section: Int { 16 | case Sort = 0 17 | case Tags = 1 18 | case Count 19 | } 20 | 21 | var hasSortType = true 22 | var sort: SortType! 23 | 24 | internal var selectedTags = NSMutableSet() 25 | var selectionCompletion: (([Tag], SortType?) -> ())? 26 | 27 | @IBOutlet weak var tableView: UITableView! 28 | 29 | var resultsController: NSFetchedResultsController! 30 | 31 | func setInitialSelectedTags(tags: [Tag]) { 32 | selectedTags = NSMutableSet(array: tags) 33 | } 34 | 35 | override func viewDidLoad() { 36 | super.viewDidLoad() 37 | configureResultsController() 38 | configureNavBar() 39 | } 40 | 41 | var isModal: Bool { 42 | return self.presentingViewController?.presentedViewController == self 43 | || (self.navigationController != nil && self.navigationController?.presentingViewController?.presentedViewController == self.navigationController) 44 | || self.tabBarController?.presentingViewController is UITabBarController 45 | } 46 | 47 | func configureNavBar() { 48 | self.title = hasSortType ? "Filter" : "Tags" 49 | if self.isModal { 50 | self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(donePressed)) 51 | } 52 | self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "New", style: .plain, target: self, action: #selector(newTagPressed)) 53 | } 54 | 55 | func newTagPressed() { 56 | let alertController = UIAlertController(title: "Add New Tag", message: "", preferredStyle: .alert) 57 | 58 | let saveAction = UIAlertAction(title: "Save", style: .default, handler: { 59 | alert -> Void in 60 | 61 | let textField = alertController.textFields![0] as UITextField 62 | let tagTitle = textField.text! 63 | let tag = ItemManager.sharedInstance.findTag(byTitle: tagTitle) 64 | if tag == nil { 65 | let createdTag = ItemManager.sharedInstance.createTag(title: tagTitle) 66 | createdTag.dirty = true 67 | NotificationCenter.default.post(name: NSNotification.Name(rawValue: ApiController.DirtyChangeMadeNotification), object: nil) 68 | } 69 | }) 70 | 71 | let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: { 72 | (action : UIAlertAction!) -> Void in 73 | 74 | }) 75 | 76 | alertController.addTextField { (textField : UITextField!) -> Void in 77 | textField.placeholder = "Tag Name" 78 | } 79 | 80 | alertController.addAction(cancelAction) 81 | alertController.addAction(saveAction) 82 | 83 | self.present(alertController, animated: true, completion: nil) 84 | } 85 | 86 | func donePressed() { 87 | self.selectionCompletion?(self.selectedTags.allObjects as! [Tag], sort) 88 | self.dismiss(animated: true, completion: nil) 89 | } 90 | 91 | override func viewDidDisappear(_ animated: Bool) { 92 | super.viewWillDisappear(animated) 93 | 94 | if !self.isModal { 95 | self.selectionCompletion?(self.selectedTags.allObjects as! [Tag], sort) 96 | } 97 | } 98 | 99 | func configureResultsController() { 100 | let fetchRequest = NSFetchRequest(entityName: "Tag") 101 | let sort = NSSortDescriptor(key: "title", ascending: true) 102 | fetchRequest.sortDescriptors = [sort] 103 | resultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: AppDelegate.sharedContext, sectionNameKeyPath: nil, cacheName: nil) 104 | resultsController.delegate = self 105 | do { 106 | try resultsController.performFetch() 107 | } 108 | catch { 109 | print("Error fetching: \(error)") 110 | } 111 | } 112 | 113 | func mapFRCIndexPathToTableIndexPath(indexPath: IndexPath) -> IndexPath { 114 | return IndexPath(row: indexPath.row, section: hasSortType ? Section.Tags.rawValue : 0) 115 | } 116 | 117 | func isTagSelected(tag: Tag) -> Bool { 118 | return selectedTags.contains(tag) 119 | } 120 | 121 | func setTagEnabled(tag: Tag, enabled: Bool) { 122 | if !enabled { 123 | selectedTags.remove(tag) 124 | } else { 125 | selectedTags.addObjects(from: [tag]) 126 | } 127 | } 128 | 129 | func presentActionSheetForTag(tag: Tag) { 130 | let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) 131 | 132 | let cell = self.tableView.cellForRow(at: self.resultsController.indexPath(forObject: tag)!) 133 | alertController.popoverPresentationController?.sourceView = cell 134 | 135 | let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { 136 | alert -> Void in 137 | if !tag.canDelete() { 138 | self.showAlert(title: "Cannot Delete", message: "To delete this tag, first delete all the notes that belong to this tag.") 139 | } else { 140 | self.showDestructiveAlert(title: "Confirm Deletion", message: "Are you sure you want to delete this tag?", buttonString: "Delete", block: { 141 | self.deleteTag(tag: tag) 142 | }) 143 | } 144 | }) 145 | 146 | let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { 147 | (action : UIAlertAction!) -> Void in 148 | 149 | }) 150 | 151 | alertController.addAction(deleteAction) 152 | alertController.addAction(cancelAction) 153 | 154 | self.present(alertController, animated: true, completion: nil) 155 | } 156 | 157 | func deleteTag(tag: Tag) { 158 | ItemManager.sharedInstance.setItemToBeDeleted(item: tag) 159 | ApiController.sharedInstance.sync { (error) in 160 | if error == nil { 161 | ItemManager.sharedInstance.removeItemFromCoreData(item: tag) 162 | } else { 163 | self.showAlert(title: "Oops", message: "There was an error deleting this tag. Please try again.") 164 | } 165 | } 166 | } 167 | 168 | func tagAtIndexPath(indexPath: IndexPath) -> Tag { 169 | return resultsController.object(at: IndexPath(row: indexPath.row, section: 0)) as Tag 170 | } 171 | 172 | } 173 | 174 | 175 | extension TagsViewController : UITableViewDelegate, UITableViewDataSource { 176 | 177 | func configureTagCell(cell: TagTableViewCell, indexPath: NSIndexPath) { 178 | let sectionInfo = resultsController.sections![0] 179 | if sectionInfo.numberOfObjects <= indexPath.row { 180 | return 181 | } 182 | 183 | let selectedObject = tagAtIndexPath(indexPath: indexPath as IndexPath) 184 | cell.titleLabel?.text = "\(selectedObject.safeTitle())" 185 | cell.switch.setOn(isTagSelected(tag: selectedObject), animated: false) 186 | cell.tagObject = selectedObject 187 | cell.selectionStyle = .none 188 | cell.selectionStateChanged = {changedCell, status in 189 | self.setTagEnabled(tag: cell.tagObject, enabled: status) 190 | } 191 | cell.longPressHandler = { cell in 192 | self.presentActionSheetForTag(tag: cell.tagObject) 193 | } 194 | } 195 | 196 | func configureSortCell(cell: UITableViewCell, indexPath: NSIndexPath) { 197 | let sortType = SortType(rawValue: indexPath.row)! 198 | switch sortType { 199 | case .Created: 200 | cell.textLabel?.text = "Date Created" 201 | break 202 | case .Modified: 203 | cell.textLabel?.text = "Date Modified" 204 | break 205 | case .Title: 206 | cell.textLabel?.text = "Title" 207 | break 208 | default: 209 | break 210 | } 211 | 212 | cell.selectionStyle = .none 213 | cell.accessoryType = sortType == sort ? UITableViewCellAccessoryType.checkmark : UITableViewCellAccessoryType.none 214 | } 215 | 216 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 217 | if hasSortType && indexPath.section == Section.Sort.rawValue { 218 | let cell = tableView.dequeueReusableCell(withIdentifier: "SortCell", for: indexPath) 219 | configureSortCell(cell: cell, indexPath: indexPath as NSIndexPath) 220 | return cell 221 | } else { 222 | let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) 223 | configureTagCell(cell: cell as! TagTableViewCell, indexPath: indexPath as NSIndexPath) 224 | return cell 225 | } 226 | } 227 | 228 | func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 229 | if hasSortType && section == Section.Sort.rawValue { 230 | return "Sort by" 231 | } else if hasSortType { 232 | return "Tags" 233 | } 234 | return nil 235 | } 236 | 237 | func numberOfSections(in tableView: UITableView) -> Int { 238 | if hasSortType { 239 | return Section.Count.rawValue 240 | } else { 241 | return 1 242 | } 243 | } 244 | 245 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 246 | if hasSortType && section == Section.Sort.rawValue { 247 | return SortType.TypeCount.rawValue 248 | } 249 | 250 | guard let sections = resultsController.sections else { 251 | fatalError("No sections in fetchedResultsController") 252 | } 253 | let sectionInfo = sections[0] 254 | // print("Returning number of row: \(sectionInfo.numberOfObjects)") 255 | return sectionInfo.numberOfObjects 256 | } 257 | 258 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 259 | if hasSortType && indexPath.section == Section.Sort.rawValue { 260 | sort = SortType(rawValue: indexPath.row)! 261 | tableView.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: .none) 262 | } else { 263 | let selectedObject = tagAtIndexPath(indexPath: mapFRCIndexPathToTableIndexPath(indexPath: indexPath)) 264 | setTagEnabled(tag: selectedObject, enabled: !isTagSelected(tag: selectedObject)) 265 | tableView.reloadRows(at: [indexPath], with: .none) 266 | tableView.deselectRow(at: indexPath, animated: true) 267 | } 268 | } 269 | } 270 | 271 | extension TagsViewController : NSFetchedResultsControllerDelegate { 272 | func controllerWillChangeContent(_ controller: NSFetchedResultsController) { 273 | tableView.beginUpdates() 274 | } 275 | 276 | func controller(_ controller: NSFetchedResultsController, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) { 277 | switch type { 278 | case .insert: 279 | tableView.insertSections(NSIndexSet(index: hasSortType ? Section.Tags.rawValue : 0) as IndexSet, with: .fade) 280 | case .delete: 281 | tableView.deleteSections(NSIndexSet(index: hasSortType ? Section.Tags.rawValue : 0) as IndexSet, with: .fade) 282 | case .move: 283 | break 284 | case .update: 285 | break 286 | } 287 | } 288 | 289 | func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 290 | switch type { 291 | case .insert: 292 | tableView.insertRows(at: [mapFRCIndexPathToTableIndexPath(indexPath: newIndexPath!)], with: .fade) 293 | case .delete: 294 | tableView.deleteRows(at: [mapFRCIndexPathToTableIndexPath(indexPath: indexPath!)], with 295 | : .fade) 296 | case .update: 297 | if let cell = tableView.cellForRow(at: mapFRCIndexPathToTableIndexPath(indexPath: indexPath!)) as? TagTableViewCell { 298 | configureTagCell(cell: cell, indexPath: mapFRCIndexPathToTableIndexPath(indexPath: indexPath!) as NSIndexPath) 299 | } 300 | case .move: 301 | tableView.moveRow(at: mapFRCIndexPathToTableIndexPath(indexPath: indexPath!), to: mapFRCIndexPathToTableIndexPath(indexPath: newIndexPath!)) 302 | } 303 | } 304 | 305 | func controllerDidChangeContent(_ controller: NSFetchedResultsController) { 306 | tableView.endUpdates() 307 | } 308 | } 309 | 310 | -------------------------------------------------------------------------------- /standardnotes/Theme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Theme.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 1/14/17. 6 | // Copyright © 2017 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class Theme { 12 | 13 | static func Initialize() { 14 | let red = UIColor(red: 250.0/255.0, green: 20.0/255.0, blue: 27.0/255.0, alpha: 1.0) 15 | UINavigationBar.appearance().tintColor = red 16 | UITabBar.appearance().tintColor = red 17 | UIButton.appearance().tintColor = red 18 | 19 | UITextField.appearance().tintColor = red 20 | UITextView.appearance().tintColor = red 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /standardnotes/UserManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserManager.swift 3 | // standardnotes 4 | // 5 | // Created by Mo Bitar on 12/23/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Keys { 12 | var encryptionKey: String 13 | var authKey: String! 14 | } 15 | 16 | class UserManager { 17 | 18 | static let LogoutNotification = "LogoutNotification" 19 | 20 | static let sharedInstance : UserManager = { 21 | return UserManager() 22 | }() 23 | 24 | init() { 25 | email = UserDefaults.standard.object(forKey: "email") as! String? 26 | server = UserDefaults.standard.object(forKey: "server") as! String? 27 | jwt = UserDefaults.standard.object(forKey: "jwt") as! String? 28 | mk = UserDefaults.standard.object(forKey: "mk") as! String? 29 | ak = UserDefaults.standard.object(forKey: "ak") as! String? 30 | if server == nil { 31 | server = "https://sync.standardnotes.org" 32 | } 33 | } 34 | 35 | var email: String! 36 | var server: String! 37 | var jwt: String! 38 | var mk: String! 39 | var ak: String! 40 | 41 | var _keys: Keys! 42 | var keys: Keys { 43 | get { 44 | if(_keys == nil) { 45 | _keys = Keys.init(encryptionKey: mk, authKey: ak) 46 | } 47 | return _keys 48 | } 49 | } 50 | 51 | func protocolVersion() -> String { 52 | if let version = authParams?["version"] { 53 | return version as! String 54 | } 55 | 56 | if (keys.authKey != nil) { 57 | return "002" 58 | } else { 59 | return "001" 60 | } 61 | } 62 | 63 | //#MARK TouchID modifies User default 64 | var touchIDEnabled: Bool { 65 | get{ 66 | return UserDefaults.standard.bool(forKey: "touchIDEnabled") 67 | } 68 | set{ 69 | UserDefaults.standard.set(newValue, forKey: "touchIDEnabled") 70 | UserDefaults.standard.synchronize() 71 | } 72 | } 73 | 74 | public func toggleTouchID(){ 75 | touchIDEnabled = !touchIDEnabled 76 | } 77 | 78 | private var _authParams: [String : Any]? 79 | var authParams: [String : Any]? { 80 | get { 81 | if _authParams == nil { 82 | return UserDefaults.standard.object(forKey: "authParams") as! [String : Any]? 83 | } 84 | 85 | return _authParams 86 | } 87 | 88 | set { 89 | _authParams = newValue 90 | 91 | // clear null values 92 | if _authParams != nil { 93 | let keysToRemove = Array(_authParams!.keys).filter { 94 | return _authParams?[$0]! == nil || _authParams?[$0]! is NSNull 95 | } 96 | 97 | for key in keysToRemove { 98 | _authParams!.removeValue(forKey: key) 99 | } 100 | } 101 | 102 | UserDefaults.standard.setValue(_authParams, forKey: "authParams") 103 | } 104 | } 105 | 106 | func save() { 107 | UserDefaults.standard.set(email, forKey: "email") 108 | UserDefaults.standard.set(server, forKey: "server") 109 | UserDefaults.standard.set(jwt, forKey: "jwt") 110 | UserDefaults.standard.set(mk, forKey: "mk") 111 | UserDefaults.standard.set(ak, forKey: "ak") 112 | 113 | persist() 114 | } 115 | 116 | func persist() { 117 | UserDefaults.standard.synchronize() 118 | } 119 | 120 | var signedIn : Bool { 121 | return self.jwt != nil 122 | } 123 | 124 | func clear() { 125 | UserDefaults.standard.removeObject(forKey: "email") 126 | UserDefaults.standard.removeObject(forKey: "password") 127 | UserDefaults.standard.removeObject(forKey: "jwt") 128 | UserDefaults.standard.removeObject(forKey: "mk") 129 | UserDefaults.standard.removeObject(forKey: "ak") 130 | UserDefaults.standard.removeObject(forKey: "touchIDEnabled") 131 | 132 | self.email = nil 133 | self.mk = nil 134 | self.ak = nil 135 | self.jwt = nil 136 | _keys = nil 137 | _authParams = nil 138 | 139 | persist() 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /standardnotes/ViewController+Util.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController+Util.swift 3 | // standardnotes 4 | // 5 | // Created by mo on 12/23/16. 6 | // Copyright © 2016 Standard Notes. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController { 12 | func showAlert(title: String, message: String) { 13 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 14 | let defaultAction = UIAlertAction(title: "Ok", style: .default, handler: { 15 | (action : UIAlertAction!) -> Void in 16 | 17 | }) 18 | alertController.addAction(defaultAction) 19 | self.present(alertController, animated: true, completion: nil) 20 | } 21 | 22 | func showConfirmationAlert(style: UIAlertControllerStyle, sourceView: UIView?, title: String, message: String, confirmString: String, confirmBlock: @escaping (() -> ())) { 23 | 24 | let alertController = UIAlertController(title: title, message: message, preferredStyle: style) 25 | if style == .actionSheet { 26 | alertController.popoverPresentationController?.sourceView = sourceView 27 | } 28 | 29 | let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 30 | let confirmAction = UIAlertAction(title: confirmString, style: .default, handler: { 31 | (action : UIAlertAction!) -> Void in 32 | confirmBlock() 33 | }) 34 | alertController.addAction(cancelAction) 35 | alertController.addAction(confirmAction) 36 | self.present(alertController, animated: true, completion: nil) 37 | } 38 | 39 | func showDestructiveAlert(title: String, message: String, buttonString: String, block: @escaping (() -> ())) { 40 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 41 | let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 42 | let confirmAction = UIAlertAction(title: buttonString, style: .destructive, handler: { 43 | (action : UIAlertAction!) -> Void in 44 | block() 45 | }) 46 | alertController.addAction(cancelAction) 47 | alertController.addAction(confirmAction) 48 | self.present(alertController, animated: true, completion: nil) 49 | } 50 | 51 | 52 | func topMostViewController() -> UIViewController { 53 | // Handling Modal views 54 | if let presentedViewController = self.presentedViewController { 55 | return presentedViewController.topMostViewController() 56 | } 57 | // Handling UIViewController's added as subviews to some other views. 58 | else { 59 | for view in self.view.subviews 60 | { 61 | // Key property which most of us are unaware of / rarely use. 62 | if let subViewController = view.next { 63 | if subViewController is UIViewController { 64 | let viewController = subViewController as! UIViewController 65 | return viewController.topMostViewController() 66 | } 67 | } 68 | } 69 | return self 70 | } 71 | } 72 | 73 | 74 | } 75 | 76 | extension UIAlertController { 77 | 78 | class func showConfirmationAlertOnRootController(title: String, message: String, confirmString: String, confirmBlock: @escaping (() -> ())) { 79 | 80 | AppDelegate.sharedInstance.window?.rootViewController?.showConfirmationAlert(style: .alert, sourceView: nil, title: title, message: message, confirmString: confirmString, confirmBlock: confirmBlock) 81 | 82 | } 83 | 84 | class func showAlertOnRootController(title: String, message: String) { 85 | AppDelegate.sharedInstance.window?.rootViewController?.showAlert(title: title, message: message) 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /standardnotes/standardnotes.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | standardnotes.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /standardnotes/standardnotes.xcdatamodeld/standardnotes.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | --------------------------------------------------------------------------------