├── VERSION ├── .swift-version ├── CHANGELOG.md ├── Example ├── iOS Example │ ├── Resources │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ └── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ ├── Supporting files │ │ └── Info.plist │ ├── AppDelegate.swift │ └── ViewController.swift └── iOS Example.xcodeproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ └── xcschemes │ │ └── iOS Example.xcscheme │ └── project.pbxproj ├── Klendario.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ └── Klendario iOS.xcscheme └── project.pbxproj ├── Klendario.xcworkspace ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── Source ├── Info.plist ├── Klendario.h ├── KDError.swift └── Klendario.swift ├── Klendario.podspec ├── LICENSE ├── .gitignore └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 1.0.1 2 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.2 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Klendario CHANGELOG 2 | 3 | ## 1.0.1 4 | 5 | * Added license to individual files. 6 | 7 | ## 1.0.0 8 | 9 | Initial release. -------------------------------------------------------------------------------- /Example/iOS Example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Klendario.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Klendario.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Klendario.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Klendario.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/iOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.1 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Klendario.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = 'Klendario' 5 | s.version = File.read('VERSION') 6 | s.summary = 'A Swift wrapper over the EventKit framework' 7 | s.description = <<-DESC 8 | Klendario is a Swift wrapper over the EventKit framework. It adds simplicity to the task of managing events in the iOS Calendar by providing handfull functions, extensions and the semi-automatic managment of the user authorization request to access the iOS calendar. 9 | DESC 10 | 11 | s.homepage = 'https://github.com/thxou/Klendario' 12 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 13 | s.license = { :type => 'MIT', :file => 'LICENSE' } 14 | s.author = { 'thxou' => 'yo@thxou.com' } 15 | s.source = { :git => 'https://github.com/thxou/Klendario.git', :tag => s.version.to_s } 16 | s.social_media_url = 'https://twitter.com/thxou' 17 | 18 | s.ios.deployment_target = '9.0' 19 | s.platform = :ios, '9.0' 20 | s.requires_arc = true 21 | 22 | s.source_files = 'Source/*.swift' 23 | 24 | end 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Luis Cardenas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/Klendario.h: -------------------------------------------------------------------------------- 1 | // 2 | // Klendario.h 3 | // 4 | // Copyright © 2018 Luis Cardenas. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | //! Project version number for Klendario. 28 | FOUNDATION_EXPORT double KlendarioVersionNumber; 29 | 30 | //! Project version string for Klendario. 31 | FOUNDATION_EXPORT const unsigned char KlendarioVersionString[]; 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /Example/iOS Example/Resources/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 | -------------------------------------------------------------------------------- /Example/iOS Example/Supporting files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Klendario 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleVersion 20 | 1 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 | NSCalendarsUsageDescription 45 | Klendario wants to access your calendar to add events 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/iOS Example/Resources/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 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Source/KDError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KDError.swift 3 | // 4 | // Copyright © 2018 Luis Cardenas. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | public enum KDError: Error { 28 | case authorizationFailed(reason: AuthorizationFailureReason) 29 | 30 | public enum AuthorizationFailureReason { 31 | case authorizationDenied 32 | case authorizationRestricted 33 | } 34 | } 35 | 36 | 37 | // MARK: - Error Descriptions 38 | extension KDError: LocalizedError { 39 | public var errorDescription: String? { 40 | switch self { 41 | case .authorizationFailed(let reason): 42 | return reason.localizedDescription 43 | } 44 | } 45 | } 46 | 47 | extension KDError.AuthorizationFailureReason { 48 | var localizedDescription: String { 49 | switch self { 50 | case .authorizationDenied: 51 | return NSLocalizedString("authorization_denied", comment: "Calendar access authorization was denied") 52 | case .authorizationRestricted: 53 | return NSLocalizedString("authorization_restricted", comment: "Calendar access authorization is restricted") 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Klendario.xcodeproj/xcshareddata/xcschemes/Klendario iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Example/iOS Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 4 | // Copyright © 2018 Luis Cardenas. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import UIKit 26 | 27 | @UIApplicationMain 28 | class AppDelegate: UIResponder, UIApplicationDelegate { 29 | 30 | var window: UIWindow? 31 | 32 | 33 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 34 | // Override point for customization after application launch. 35 | return true 36 | } 37 | 38 | func applicationWillResignActive(_ application: UIApplication) { 39 | // 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. 40 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 41 | } 42 | 43 | func applicationDidEnterBackground(_ application: UIApplication) { 44 | // 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. 45 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 46 | } 47 | 48 | func applicationWillEnterForeground(_ application: UIApplication) { 49 | // 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. 50 | } 51 | 52 | func applicationDidBecomeActive(_ application: UIApplication) { 53 | // 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. 54 | } 55 | 56 | func applicationWillTerminate(_ application: UIApplication) { 57 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 58 | } 59 | 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Example/iOS Example.xcodeproj/xcshareddata/xcschemes/iOS Example.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 | -------------------------------------------------------------------------------- /Example/iOS Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // 4 | // Copyright © 2018 Luis Cardenas. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import UIKit 26 | import EventKit 27 | import Klendario 28 | 29 | class ViewController: UIViewController { 30 | 31 | @IBOutlet weak var tableView: UITableView? 32 | 33 | fileprivate var events = [EKEvent]() 34 | fileprivate static let formatter: DateFormatter = { 35 | let formatter = DateFormatter() 36 | formatter.dateFormat = "dd/MM/yyyy HH:mm" 37 | return formatter 38 | }() 39 | 40 | 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | 44 | setup() 45 | } 46 | 47 | 48 | // MARK: - Setup 49 | fileprivate func setup() { 50 | getEvents() 51 | } 52 | 53 | 54 | // MARK: - Helpers 55 | fileprivate func reload() { 56 | tableView?.reloadData() 57 | } 58 | 59 | fileprivate func getEvents() { 60 | // Getting events 61 | Klendario.getEvents(from: Date(), to: Date() + 60*60) { (events, error) in 62 | guard let events = events else { 63 | print("error getting events: \(String(describing: error))") 64 | return 65 | } 66 | 67 | self.events = events 68 | self.reload() 69 | } 70 | } 71 | 72 | fileprivate func createEvent(with title: String) { 73 | // Create event 74 | let event = Klendario.newEvent() 75 | event.title = title 76 | event.startDate = Date() + 60*60 77 | event.endDate = event.startDate.addingTimeInterval(60*60*2) 78 | 79 | event.save { error in 80 | if let error = error { 81 | print("error: \(error.localizedDescription)") 82 | } else { 83 | self.getEvents() 84 | print("event successfully created!") 85 | } 86 | } 87 | } 88 | 89 | 90 | // MARK: - Actions 91 | @IBAction func createEvent(_ sender: UIButton) { 92 | let alertController = UIAlertController(title: "New event", message: nil, preferredStyle: .alert) 93 | alertController.addTextField { (textField) in 94 | textField.placeholder = "Type the event title" 95 | } 96 | 97 | let okAction = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in 98 | if let textField = alertController.textFields?.first, let text = textField.text { 99 | self.createEvent(with: text != "" ? text : "New title") 100 | } 101 | }) 102 | 103 | let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) 104 | 105 | alertController.addAction(okAction) 106 | alertController.addAction(cancelAction) 107 | 108 | present(alertController, animated: true, completion: nil) 109 | } 110 | 111 | @IBAction func reloadEvents(_ sender: UIButton) { 112 | getEvents() 113 | } 114 | 115 | } 116 | 117 | 118 | extension ViewController : UITableViewDataSource { 119 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 120 | return events.count 121 | } 122 | 123 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 124 | let event = events[indexPath.row] 125 | 126 | let cell = tableView.dequeueReusableCell(withIdentifier: "EventCell", for: indexPath) 127 | cell.textLabel?.text = event.title 128 | cell.detailTextLabel?.text = "\(ViewController.formatter.string(from: event.startDate)) - \(ViewController.formatter.string(from: event.endDate))" 129 | return cell 130 | } 131 | } 132 | 133 | 134 | extension ViewController : UITableViewDelegate { 135 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 136 | tableView.deselectRow(at: indexPath, animated: true) 137 | } 138 | } 139 | 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ============== 3 | 4 | [![Pod Version](http://img.shields.io/cocoapods/v/Klendario.svg?style=flat)](https://github.com/ThXou/Klendario) 5 | [![Pod Platform](http://img.shields.io/cocoapods/p/Klendario.svg?style=flat)](https://github.com/ThXou/Klendario) 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | [![Pod License](http://img.shields.io/cocoapods/l/Klendario.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) 8 | 9 | Klendario is a Swift wrapper over the `EventKit` framework. It adds simplicity to the task of managing events in the iOS Calendar by providing handfull functions, extensions and the semi-automatic managment of the user authorization request to access the iOS calendar. 10 | 11 | Requirements 12 | ============== 13 | 14 | * iOS 9.0+ 15 | * Xcode 10.0+ 16 | * Swift 4.2+ 17 | 18 | Install 19 | ============== 20 | 21 | ### Cocoapods 22 | 23 | Add this line to your podfile: 24 | 25 | ```ruby 26 | pod 'Klendario' 27 | ``` 28 | 29 | ### Carthage 30 | 31 | Add this line to your `cartfile`: 32 | 33 | ```ruby 34 | github "ThXou/Klendario" ~> 1.0 35 | ``` 36 | 37 | And then follow the official documentation about [Adding frameworks to an application](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). 38 | 39 | Setup 40 | ============== 41 | 42 | Import `Klendario` in your source file: 43 | 44 | ```swift 45 | import Klendario 46 | ``` 47 | 48 | Then set the `NSCalendarsUsageDescription` usage description key in your app's `Info.plist` file to avoid the Xcode crash on access to sensitive data. 49 | 50 | Authorization 51 | ============== 52 | 53 | Almost every call will check the user authorization status and returns an error in case the user has not authorized the access to the calendar. If the authorization has not been determined yet, the user is prompted to authorize the application. Anyway you can request authorization manually by calling: 54 | 55 | ```swift 56 | Klendario.requestAuthorization { (granted, status, error) in 57 | if let error = error { 58 | print("error: \(error.localizedDescription)") 59 | } else { 60 | print("authorization granted!") 61 | } 62 | } 63 | ``` 64 | 65 | The closure will return an error if the user has denied the access or if the access is restricted due to, for example, parental controls. 66 | 67 | If you prefer, you can check if the user has granted access to the calendar using: 68 | 69 | ```swift 70 | Klendario.isAuthorized() 71 | ``` 72 | 73 | Events 74 | ============== 75 | 76 | ### Creating events 77 | 78 | Create an event is as easy as this: 79 | 80 | ```swift 81 | let event = Klendario.newEvent() 82 | event.title = "Awesome event" 83 | event.startDate = Date() 84 | event.endDate = Date().addingTimeInterval(60*60*2) // 2 hours 85 | event.save() 86 | ``` 87 | If you have the specific calendar where you want to add the event, you can pass it in the `newEvent()` function as a parameter. If you additionaly want to perform some actions on saving, you can use the optional completion closure: 88 | 89 | ```swift 90 | ... 91 | event.save { error in 92 | if let error = error { 93 | print("error: \(error.localizedDescription)") 94 | } else { 95 | print("event successfully created!") 96 | } 97 | } 98 | ``` 99 | 100 | Before saving events read the [Last but not least](#last) section. 101 | 102 | ### Getting events 103 | #### Get a single event 104 | 105 | You can get an event by knowing its event identifier: 106 | 107 | ```swift 108 | Klendario.getEvent(with: eventIdentifier) { (event, error) in 109 | guard let event = event else { return } 110 | print("got an event: \(event.title ?? "")") 111 | } 112 | ``` 113 | 114 | #### Get a group of events 115 | 116 | Or you can get a group of events between two dates and in specific calendars: 117 | 118 | ```swift 119 | Klendario.getEvents(from: Date(), 120 | to: Date() + 60*60*2, 121 | in: calendars) { (events, error) in 122 | guard let events = events else { return } 123 | print("got \(events.count) events") 124 | } 125 | ``` 126 | 127 | ### Deleting events 128 | 129 | You can easily delete an `EKEvent` object using the `delete` function: 130 | 131 | ```swift 132 | event.delete() 133 | ``` 134 | As for creating an event, you can perform actions on event deletion completion. You can omit any paremeter: 135 | 136 | ```swift 137 | event.delete(span: .futureEvents, commit: false) { error in 138 | if let error = error { 139 | print("error: \(error.localizedDescription)") 140 | } else { 141 | print("event successfully deleted!") 142 | } 143 | } 144 | ``` 145 | Before deleting events read the [Last but not least](#last) section. 146 | 147 | Calendars 148 | ============== 149 | 150 | ### Creating calendars 151 | 152 | Create a new calendar is as easy as create a new event: 153 | 154 | ```swift 155 | let calendar = Klendario.newCalendar() 156 | calendar.title = "Awesome calendar" 157 | calendar.save() 158 | ``` 159 | 160 | As for events, you can use a `completion` closure to handle possible errors or perform some action on task completion. This method is flexible so you can pass a different `eventStore` or `source` if you don't want to use the default one. 161 | 162 | Before saving calendars read the [Last but not least](#last) section. 163 | 164 | ### Getting calendars 165 | 166 | To get all the iOS calendars which includes events in the device, simply call: 167 | 168 | ```swift 169 | let calendars = Klendario.getCalendars() 170 | ``` 171 | ### Deleting calendars 172 | 173 | You can easily delete an `EKCalendar` object using the `delete` function: 174 | 175 | ```swift 176 | calendar.delete() 177 | ``` 178 | As for creating an event, you can perform actions on event deletion completion. You can omit any paremeter: 179 | 180 | ```swift 181 | calendar.delete(commit: true) { error in 182 | if let error = error { 183 | print("error: \(error.localizedDescription)") 184 | } else { 185 | print("calendar successfully deleted!") 186 | } 187 | } 188 | ``` 189 | Before deleting calendars read the [Last but not least](#last) section. 190 | 191 | Last but not least 192 | ============== 193 | 194 | It is very simple to save or delete an event or a calendar with `Klendario`, you just need to call `save()` or `delete()` on the object as shown in previous sections. **Be carefull** to not call `save()` or `delete()` on objects not retrieved with the `Klendario` API, because it shares the same `EKEventStore` object across all the API calls. 195 | 196 | `EventKit` does not support cross-store saving at least until iOS 12. -------------------------------------------------------------------------------- /Example/iOS Example/Resources/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Source/Klendario.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Klendario.swift 3 | // 4 | // Copyright © 2018 Luis Cardenas. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import EventKit 26 | 27 | /// A closure executed on calls which may return an error. 28 | public typealias KlendarioCompletion = (_ error: Error?) -> Void 29 | 30 | /// A closure executed when trying to get an event from calendar. 31 | public typealias KlendarioEventCompletion = (_ event: EKEvent?, _ error: Error?) -> Void 32 | 33 | /// A closure executed when trying to get a bunch of events from calendar. 34 | public typealias KlendarioEventsCompletion = (_ events: [EKEvent]?, _ error: Error?) -> Void 35 | 36 | /// A closure executed when requesting user authorization to the calendar. 37 | public typealias KlendarioAuthorizationCompletion = (_ granted: Bool, _ status: EKAuthorizationStatus, _ error: Error?) -> Void 38 | 39 | 40 | public class Klendario { 41 | 42 | /// A singleton object which mainly stored the default `eventStore`. 43 | fileprivate static let manager = Klendario() 44 | 45 | /// The default `eventStore` object to use in the get/add/remove tasks. 46 | fileprivate var eventStore = EKEventStore() 47 | 48 | 49 | // MARK: - Authorization 50 | /// Prompts the user to authorize event access to the Calendar if permission has not been yet determined. Otherwise 51 | /// it returns the specified error or access granted in case the user has authorized the access to the calendar. 52 | /// 53 | /// - parameter completion: The `completion` closure called on the request access to the calendar. 54 | public class func requestAuthorization(_ completion: KlendarioAuthorizationCompletion? = nil) { 55 | let status = EKEventStore.authorizationStatus(for: .event) 56 | switch status { 57 | case .authorized: 58 | completion?(true, status, nil) 59 | case .notDetermined: 60 | Klendario.manager.eventStore 61 | .requestAccess(to: .event) { (granted, error) in 62 | completion?(granted, status, error) 63 | } 64 | case .restricted: 65 | completion?(false, status, KDError.authorizationFailed(reason: .authorizationRestricted)) 66 | case .denied: 67 | completion?(false, status, KDError.authorizationFailed(reason: .authorizationDenied)) 68 | } 69 | } 70 | 71 | /// Returns a boolean indicating if user has granted access to the device's calendar. 72 | public class func isAuthorized() -> Bool { 73 | return EKEventStore.authorizationStatus(for: .event) == .authorized 74 | } 75 | 76 | 77 | // MARK: - Events 78 | // MARK: - Creating events 79 | /// Creates a new `EKEvent` object with the `eventStore`'s default calendar for new events. 80 | /// 81 | /// - parameter calendar: The calendar where to create the event. If `nil`, the `eventStore`'s default 82 | /// calendar for new events is used instead. 83 | public class func newEvent(in calendar: EKCalendar? = nil) -> EKEvent { 84 | let eventStore = Klendario.manager.eventStore 85 | 86 | let event = EKEvent(eventStore: eventStore) 87 | event.calendar = calendar ?? eventStore.defaultCalendarForNewEvents 88 | return event 89 | } 90 | 91 | 92 | // MARK: - Getting events 93 | /// Gets a single event matching the provided event `identifier`. 94 | /// 95 | /// - parameter identifier: The event `identifier`. 96 | /// - parameter completion: The `completion` closure called after the event search has been completed. 97 | public class func getEvent(with identifier: String, completion: @escaping KlendarioEventCompletion) { 98 | execute({ 99 | let eventStore = Klendario.manager.eventStore 100 | let event = eventStore.event(withIdentifier: identifier) 101 | DispatchQueue.main.async { completion(event, nil) } 102 | }) { error in 103 | DispatchQueue.main.async { completion(nil, error) } 104 | } 105 | } 106 | 107 | /// Returns the events included between the provided start and end dates and are present in the provided `calendars` array. 108 | /// 109 | /// - parameter date: The start date from where to start searching for events. 110 | /// - parameter to: The end date up to where to search for events. 111 | /// - parameter calendars: An optional array of calendars where to seach for events. 112 | /// - parameter completion: The `completion` closure called after the events search has been completed. 113 | public class func getEvents(from date: Date, to: Date, in calendars: [EKCalendar]? = nil, completion: @escaping KlendarioEventsCompletion) { 114 | execute({ 115 | let eventStore = Klendario.manager.eventStore 116 | let predicate = eventStore.predicateForEvents(withStart: date, end: to, calendars: calendars) 117 | let events = eventStore.events(matching: predicate) 118 | DispatchQueue.main.async { completion(events, nil) } 119 | }) { error in 120 | DispatchQueue.main.async { completion(nil, error) } 121 | } 122 | } 123 | 124 | 125 | // MARK: - Removing events 126 | /// Deletes the event with the given event `identifier`. 127 | /// 128 | /// - parameter identifier: The event identifier to delete. 129 | /// - parameter span: Determines if the deletion should apply to this event only or all future events. If you omit 130 | /// this parameter it is set by default to `.thisEvent`. 131 | /// - parameter completion: The `completion` closure to be called after the event deletion. 132 | public class func deleteEvent(with identifier: String, span: EKSpan = .thisEvent, completion: KlendarioCompletion? = nil) { 133 | execute({ 134 | getEvent(with: identifier, completion: { (event, error) in 135 | if let event = event { 136 | event.delete(span: span) { error in 137 | completion?(error) 138 | } 139 | } else { 140 | completion?(error) 141 | } 142 | }) 143 | }, completion: completion) 144 | } 145 | 146 | 147 | // MARK: - Event store handling 148 | /// Resets the store by discarding uncommited changes to the store 149 | public class func resetStore() { 150 | Klendario.manager.eventStore.reset() 151 | } 152 | 153 | /// Commit the unsaved changes made to the `eventStore`. 154 | /// 155 | /// - parameter completion: The `completion` closure to be called after the commit has been made. 156 | public class func commitChanges(_ completion: KlendarioCompletion? = nil) { 157 | executeAndThrow({ 158 | try Klendario.manager.eventStore.commit() 159 | DispatchQueue.main.async { completion?(nil) } 160 | }, completion: completion) 161 | } 162 | 163 | 164 | // MARK: - Calendars 165 | // MARK: - Creating calendars 166 | /// Creates a new `EKCalendar` object in the `eventStore` object if provided. Otherwise uses the default one. 167 | /// 168 | /// - parameter eventStore: The eventStore where to create the calendar. If `nil`, the default `eventStore` is used. 169 | /// - parameter source: The source where you want the calendar to be stored. If `nil`, `source`'s default calendar 170 | /// for new events is used. 171 | public class func newCalendar(in eventStore: EKEventStore? = nil, source: EKSource? = nil) -> EKCalendar { 172 | if let eventStore = eventStore { 173 | Klendario.manager.eventStore = eventStore 174 | } 175 | 176 | let calendar = EKCalendar(for: .event, eventStore: Klendario.manager.eventStore) 177 | calendar.source = source ?? Klendario.manager.eventStore.defaultCalendarForNewEvents?.source 178 | return calendar 179 | } 180 | 181 | 182 | // MARK: - Getting calendars 183 | /// Returns an array of calendars for the `.event` entity type. 184 | public class func getCalendars() -> [EKCalendar] { 185 | return Klendario.manager.eventStore.calendars(for: .event) 186 | } 187 | 188 | 189 | // MARK: - Private 190 | fileprivate class func execute(_ block: @escaping (() -> ()), completion: KlendarioCompletion? = nil) { 191 | requestAuthorization { (granted, _, error) in 192 | if granted { 193 | block() 194 | } else { 195 | completion?(error) 196 | } 197 | } 198 | } 199 | 200 | fileprivate class func executeAndThrow(_ block: @escaping (() throws -> ()), completion: KlendarioCompletion? = nil) { 201 | requestAuthorization { (granted, _, error) in 202 | if granted { 203 | do { 204 | try block() 205 | } catch let error { 206 | completion?(error) 207 | } 208 | } else { 209 | completion?(error) 210 | } 211 | } 212 | } 213 | 214 | } 215 | 216 | 217 | public extension EKEvent { 218 | /// Adds the event to the `eventStore`'s calendar. 219 | /// 220 | /// - parameter span: Determines if the modifications made to the event should apply to this event only 221 | /// or all future events. 222 | /// - parameter completion: The `completion` closure to be called on add event completion. 223 | public func save(span: EKSpan = .thisEvent, completion: KlendarioCompletion? = nil) { 224 | Klendario.executeAndThrow({ 225 | try Klendario.manager.eventStore.save(self, span: span) 226 | DispatchQueue.main.async { completion?(nil) } 227 | }, completion: completion) 228 | } 229 | 230 | /// Deletes the event from the `eventStore`'s calendar. 231 | /// 232 | /// - parameter span: Determines if the deletion should apply to this event only or all future events. 233 | /// - parameter commit: A boolean indicating if the event should be removed inmediatelly or after the next 234 | /// `eventStore`'s `commit` call. 235 | /// - parameter completion: The `completion` closure to be called after the event deletion. 236 | public func delete(span: EKSpan = .thisEvent, commit: Bool = true, completion: KlendarioCompletion? = nil) { 237 | Klendario.executeAndThrow({ 238 | try Klendario.manager.eventStore.remove(self, span: span, commit: commit) 239 | DispatchQueue.main.async { completion?(nil) } 240 | }, completion: completion) 241 | } 242 | } 243 | 244 | 245 | public extension EKCalendar { 246 | /// Adds the calendar to the `eventStore`. 247 | /// 248 | /// - parameter commit: A boolean indicating if the calendar should be removed inmediatelly or after the next 249 | /// `eventStore`'s `commit` call. 250 | /// - parameter completion: The `completion` closure to be called on add calendar completion. 251 | public func save(commit: Bool = true, completion: KlendarioCompletion? = nil) { 252 | Klendario.executeAndThrow({ 253 | try Klendario.manager.eventStore.saveCalendar(self, commit: commit) 254 | DispatchQueue.main.async { completion?(nil) } 255 | }, completion: completion) 256 | } 257 | 258 | /// Deletes the calendar from the `eventStore`. 259 | /// 260 | /// - parameter commit: A boolean indicating if the calendar should be removed inmediatelly or after the next 261 | /// `eventStore`'s `commit` call. 262 | /// - parameter completion: The `completion` closure to be called after the calendar deletion. 263 | public func delete(commit: Bool = true, completion: KlendarioCompletion? = nil) { 264 | Klendario.executeAndThrow({ 265 | try Klendario.manager.eventStore.removeCalendar(self, commit: commit) 266 | DispatchQueue.main.async { completion?(nil) } 267 | }, completion: completion) 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /Klendario.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AA4F5B6621C8E16C003B0641 /* Klendario.h in Headers */ = {isa = PBXBuildFile; fileRef = AA4F5B6421C8E16C003B0641 /* Klendario.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | AA65A11921C8E93B0019609A /* KDError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4F5B5A21C8E0F4003B0641 /* KDError.swift */; }; 12 | AA65A11A21C8E93B0019609A /* Klendario.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4F5B5921C8E0F4003B0641 /* Klendario.swift */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXFileReference section */ 16 | AA4F5B5921C8E0F4003B0641 /* Klendario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Klendario.swift; sourceTree = ""; }; 17 | AA4F5B5A21C8E0F4003B0641 /* KDError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KDError.swift; sourceTree = ""; }; 18 | AA4F5B6221C8E16C003B0641 /* Klendario.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Klendario.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | AA4F5B6421C8E16C003B0641 /* Klendario.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Klendario.h; sourceTree = ""; }; 20 | AA4F5B6521C8E16C003B0641 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 21 | AA4F5B6B21C8E2E5003B0641 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = ""; }; 22 | AA4F5B6C21C8E2E5003B0641 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 23 | AA4F5B6D21C8E2E6003B0641 /* Klendario.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Klendario.podspec; sourceTree = ""; }; 24 | /* End PBXFileReference section */ 25 | 26 | /* Begin PBXFrameworksBuildPhase section */ 27 | AA4F5B5F21C8E16C003B0641 /* Frameworks */ = { 28 | isa = PBXFrameworksBuildPhase; 29 | buildActionMask = 2147483647; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | AA4F5B3821C8E07B003B0641 = { 38 | isa = PBXGroup; 39 | children = ( 40 | AA4F5B5621C8E0C4003B0641 /* Deployment */, 41 | AA4F5B5721C8E0C9003B0641 /* Source */, 42 | AA4F5B4221C8E07B003B0641 /* Products */, 43 | ); 44 | sourceTree = ""; 45 | }; 46 | AA4F5B4221C8E07B003B0641 /* Products */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | AA4F5B6221C8E16C003B0641 /* Klendario.framework */, 50 | ); 51 | name = Products; 52 | sourceTree = ""; 53 | }; 54 | AA4F5B5621C8E0C4003B0641 /* Deployment */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | AA4F5B6C21C8E2E5003B0641 /* LICENSE */, 58 | AA4F5B6D21C8E2E6003B0641 /* Klendario.podspec */, 59 | AA4F5B6B21C8E2E5003B0641 /* VERSION */, 60 | ); 61 | name = Deployment; 62 | sourceTree = ""; 63 | }; 64 | AA4F5B5721C8E0C9003B0641 /* Source */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | AA4F5B5A21C8E0F4003B0641 /* KDError.swift */, 68 | AA4F5B5921C8E0F4003B0641 /* Klendario.swift */, 69 | AA4F5B6A21C8E216003B0641 /* Supporting files */, 70 | ); 71 | path = Source; 72 | sourceTree = ""; 73 | }; 74 | AA4F5B6A21C8E216003B0641 /* Supporting files */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | AA4F5B6421C8E16C003B0641 /* Klendario.h */, 78 | AA4F5B6521C8E16C003B0641 /* Info.plist */, 79 | ); 80 | name = "Supporting files"; 81 | sourceTree = ""; 82 | }; 83 | /* End PBXGroup section */ 84 | 85 | /* Begin PBXHeadersBuildPhase section */ 86 | AA4F5B5D21C8E16C003B0641 /* Headers */ = { 87 | isa = PBXHeadersBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | AA4F5B6621C8E16C003B0641 /* Klendario.h in Headers */, 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | /* End PBXHeadersBuildPhase section */ 95 | 96 | /* Begin PBXNativeTarget section */ 97 | AA4F5B6121C8E16C003B0641 /* Klendario iOS */ = { 98 | isa = PBXNativeTarget; 99 | buildConfigurationList = AA4F5B6721C8E16C003B0641 /* Build configuration list for PBXNativeTarget "Klendario iOS" */; 100 | buildPhases = ( 101 | AA4F5B5D21C8E16C003B0641 /* Headers */, 102 | AA4F5B5E21C8E16C003B0641 /* Sources */, 103 | AA4F5B5F21C8E16C003B0641 /* Frameworks */, 104 | AA4F5B6021C8E16C003B0641 /* Resources */, 105 | ); 106 | buildRules = ( 107 | ); 108 | dependencies = ( 109 | ); 110 | name = "Klendario iOS"; 111 | productName = "Klendario iOS"; 112 | productReference = AA4F5B6221C8E16C003B0641 /* Klendario.framework */; 113 | productType = "com.apple.product-type.framework"; 114 | }; 115 | /* End PBXNativeTarget section */ 116 | 117 | /* Begin PBXProject section */ 118 | AA4F5B3921C8E07B003B0641 /* Project object */ = { 119 | isa = PBXProject; 120 | attributes = { 121 | LastSwiftUpdateCheck = 1010; 122 | LastUpgradeCheck = 1010; 123 | ORGANIZATIONNAME = ThXou; 124 | TargetAttributes = { 125 | AA4F5B6121C8E16C003B0641 = { 126 | CreatedOnToolsVersion = 10.1; 127 | }; 128 | }; 129 | }; 130 | buildConfigurationList = AA4F5B3C21C8E07B003B0641 /* Build configuration list for PBXProject "Klendario" */; 131 | compatibilityVersion = "Xcode 9.3"; 132 | developmentRegion = en; 133 | hasScannedForEncodings = 0; 134 | knownRegions = ( 135 | en, 136 | Base, 137 | ); 138 | mainGroup = AA4F5B3821C8E07B003B0641; 139 | productRefGroup = AA4F5B4221C8E07B003B0641 /* Products */; 140 | projectDirPath = ""; 141 | projectRoot = ""; 142 | targets = ( 143 | AA4F5B6121C8E16C003B0641 /* Klendario iOS */, 144 | ); 145 | }; 146 | /* End PBXProject section */ 147 | 148 | /* Begin PBXResourcesBuildPhase section */ 149 | AA4F5B6021C8E16C003B0641 /* Resources */ = { 150 | isa = PBXResourcesBuildPhase; 151 | buildActionMask = 2147483647; 152 | files = ( 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | /* End PBXResourcesBuildPhase section */ 157 | 158 | /* Begin PBXSourcesBuildPhase section */ 159 | AA4F5B5E21C8E16C003B0641 /* Sources */ = { 160 | isa = PBXSourcesBuildPhase; 161 | buildActionMask = 2147483647; 162 | files = ( 163 | AA65A11921C8E93B0019609A /* KDError.swift in Sources */, 164 | AA65A11A21C8E93B0019609A /* Klendario.swift in Sources */, 165 | ); 166 | runOnlyForDeploymentPostprocessing = 0; 167 | }; 168 | /* End PBXSourcesBuildPhase section */ 169 | 170 | /* Begin XCBuildConfiguration section */ 171 | AA4F5B5121C8E07C003B0641 /* Debug */ = { 172 | isa = XCBuildConfiguration; 173 | buildSettings = { 174 | ALWAYS_SEARCH_USER_PATHS = NO; 175 | CLANG_ANALYZER_NONNULL = YES; 176 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 177 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 178 | CLANG_CXX_LIBRARY = "libc++"; 179 | CLANG_ENABLE_MODULES = YES; 180 | CLANG_ENABLE_OBJC_ARC = YES; 181 | CLANG_ENABLE_OBJC_WEAK = YES; 182 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 183 | CLANG_WARN_BOOL_CONVERSION = YES; 184 | CLANG_WARN_COMMA = YES; 185 | CLANG_WARN_CONSTANT_CONVERSION = YES; 186 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 187 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 188 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 189 | CLANG_WARN_EMPTY_BODY = YES; 190 | CLANG_WARN_ENUM_CONVERSION = YES; 191 | CLANG_WARN_INFINITE_RECURSION = YES; 192 | CLANG_WARN_INT_CONVERSION = YES; 193 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 194 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 195 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 196 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 197 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 198 | CLANG_WARN_STRICT_PROTOTYPES = YES; 199 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 200 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 201 | CLANG_WARN_UNREACHABLE_CODE = YES; 202 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 203 | CODE_SIGN_IDENTITY = "iPhone Developer"; 204 | COPY_PHASE_STRIP = NO; 205 | DEBUG_INFORMATION_FORMAT = dwarf; 206 | ENABLE_STRICT_OBJC_MSGSEND = YES; 207 | ENABLE_TESTABILITY = YES; 208 | GCC_C_LANGUAGE_STANDARD = gnu11; 209 | GCC_DYNAMIC_NO_PIC = NO; 210 | GCC_NO_COMMON_BLOCKS = YES; 211 | GCC_OPTIMIZATION_LEVEL = 0; 212 | GCC_PREPROCESSOR_DEFINITIONS = ( 213 | "DEBUG=1", 214 | "$(inherited)", 215 | ); 216 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 217 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 218 | GCC_WARN_UNDECLARED_SELECTOR = YES; 219 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 220 | GCC_WARN_UNUSED_FUNCTION = YES; 221 | GCC_WARN_UNUSED_VARIABLE = YES; 222 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 223 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 224 | MTL_FAST_MATH = YES; 225 | ONLY_ACTIVE_ARCH = YES; 226 | SDKROOT = iphoneos; 227 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 228 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 229 | }; 230 | name = Debug; 231 | }; 232 | AA4F5B5221C8E07C003B0641 /* Release */ = { 233 | isa = XCBuildConfiguration; 234 | buildSettings = { 235 | ALWAYS_SEARCH_USER_PATHS = NO; 236 | CLANG_ANALYZER_NONNULL = YES; 237 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 238 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 239 | CLANG_CXX_LIBRARY = "libc++"; 240 | CLANG_ENABLE_MODULES = YES; 241 | CLANG_ENABLE_OBJC_ARC = YES; 242 | CLANG_ENABLE_OBJC_WEAK = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 250 | CLANG_WARN_EMPTY_BODY = YES; 251 | CLANG_WARN_ENUM_CONVERSION = YES; 252 | CLANG_WARN_INFINITE_RECURSION = YES; 253 | CLANG_WARN_INT_CONVERSION = YES; 254 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 255 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 256 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 258 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 259 | CLANG_WARN_STRICT_PROTOTYPES = YES; 260 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 261 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | CODE_SIGN_IDENTITY = "iPhone Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 267 | ENABLE_NS_ASSERTIONS = NO; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu11; 270 | GCC_NO_COMMON_BLOCKS = YES; 271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 273 | GCC_WARN_UNDECLARED_SELECTOR = YES; 274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 275 | GCC_WARN_UNUSED_FUNCTION = YES; 276 | GCC_WARN_UNUSED_VARIABLE = YES; 277 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 278 | MTL_ENABLE_DEBUG_INFO = NO; 279 | MTL_FAST_MATH = YES; 280 | SDKROOT = iphoneos; 281 | SWIFT_COMPILATION_MODE = wholemodule; 282 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 283 | VALIDATE_PRODUCT = YES; 284 | }; 285 | name = Release; 286 | }; 287 | AA4F5B6821C8E16C003B0641 /* Debug */ = { 288 | isa = XCBuildConfiguration; 289 | buildSettings = { 290 | CODE_SIGN_IDENTITY = ""; 291 | CODE_SIGN_STYLE = Automatic; 292 | CURRENT_PROJECT_VERSION = 1; 293 | DEFINES_MODULE = YES; 294 | DEVELOPMENT_TEAM = BZ3VSUA92U; 295 | DYLIB_COMPATIBILITY_VERSION = 1; 296 | DYLIB_CURRENT_VERSION = 1; 297 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 298 | INFOPLIST_FILE = Source/Info.plist; 299 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 300 | LD_RUNPATH_SEARCH_PATHS = ( 301 | "$(inherited)", 302 | "@executable_path/Frameworks", 303 | "@loader_path/Frameworks", 304 | ); 305 | PRODUCT_BUNDLE_IDENTIFIER = "com.thxou.Klendario-iOS"; 306 | PRODUCT_NAME = Klendario; 307 | SKIP_INSTALL = YES; 308 | SWIFT_VERSION = 4.2; 309 | TARGETED_DEVICE_FAMILY = "1,2"; 310 | VERSIONING_SYSTEM = "apple-generic"; 311 | VERSION_INFO_PREFIX = ""; 312 | }; 313 | name = Debug; 314 | }; 315 | AA4F5B6921C8E16C003B0641 /* Release */ = { 316 | isa = XCBuildConfiguration; 317 | buildSettings = { 318 | CODE_SIGN_IDENTITY = ""; 319 | CODE_SIGN_STYLE = Automatic; 320 | CURRENT_PROJECT_VERSION = 1; 321 | DEFINES_MODULE = YES; 322 | DEVELOPMENT_TEAM = BZ3VSUA92U; 323 | DYLIB_COMPATIBILITY_VERSION = 1; 324 | DYLIB_CURRENT_VERSION = 1; 325 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 326 | INFOPLIST_FILE = Source/Info.plist; 327 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 328 | LD_RUNPATH_SEARCH_PATHS = ( 329 | "$(inherited)", 330 | "@executable_path/Frameworks", 331 | "@loader_path/Frameworks", 332 | ); 333 | PRODUCT_BUNDLE_IDENTIFIER = "com.thxou.Klendario-iOS"; 334 | PRODUCT_NAME = Klendario; 335 | SKIP_INSTALL = YES; 336 | SWIFT_VERSION = 4.2; 337 | TARGETED_DEVICE_FAMILY = "1,2"; 338 | VERSIONING_SYSTEM = "apple-generic"; 339 | VERSION_INFO_PREFIX = ""; 340 | }; 341 | name = Release; 342 | }; 343 | /* End XCBuildConfiguration section */ 344 | 345 | /* Begin XCConfigurationList section */ 346 | AA4F5B3C21C8E07B003B0641 /* Build configuration list for PBXProject "Klendario" */ = { 347 | isa = XCConfigurationList; 348 | buildConfigurations = ( 349 | AA4F5B5121C8E07C003B0641 /* Debug */, 350 | AA4F5B5221C8E07C003B0641 /* Release */, 351 | ); 352 | defaultConfigurationIsVisible = 0; 353 | defaultConfigurationName = Release; 354 | }; 355 | AA4F5B6721C8E16C003B0641 /* Build configuration list for PBXNativeTarget "Klendario iOS" */ = { 356 | isa = XCConfigurationList; 357 | buildConfigurations = ( 358 | AA4F5B6821C8E16C003B0641 /* Debug */, 359 | AA4F5B6921C8E16C003B0641 /* Release */, 360 | ); 361 | defaultConfigurationIsVisible = 0; 362 | defaultConfigurationName = Release; 363 | }; 364 | /* End XCConfigurationList section */ 365 | }; 366 | rootObject = AA4F5B3921C8E07B003B0641 /* Project object */; 367 | } 368 | -------------------------------------------------------------------------------- /Example/iOS Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AA4F5B2521C8DE88003B0641 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4F5B2421C8DE88003B0641 /* AppDelegate.swift */; }; 11 | AA4F5B2721C8DE88003B0641 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4F5B2621C8DE88003B0641 /* ViewController.swift */; }; 12 | AA4F5B2A21C8DE88003B0641 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA4F5B2821C8DE88003B0641 /* Main.storyboard */; }; 13 | AA4F5B2C21C8DE8A003B0641 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AA4F5B2B21C8DE8A003B0641 /* Assets.xcassets */; }; 14 | AA4F5B2F21C8DE8A003B0641 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA4F5B2D21C8DE8A003B0641 /* LaunchScreen.storyboard */; }; 15 | AA65A11721C8E69E0019609A /* Klendario.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA65A11621C8E69E0019609A /* Klendario.framework */; }; 16 | AA65A11821C8E69E0019609A /* Klendario.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = AA65A11621C8E69E0019609A /* Klendario.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | AA65A11521C8E56A0019609A /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | AA65A11821C8E69E0019609A /* Klendario.framework in Embed Frameworks */, 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | AA4F5B2121C8DE88003B0641 /* iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | AA4F5B2421C8DE88003B0641 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 36 | AA4F5B2621C8DE88003B0641 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 37 | AA4F5B2921C8DE88003B0641 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 38 | AA4F5B2B21C8DE8A003B0641 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 39 | AA4F5B2E21C8DE8A003B0641 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 40 | AA4F5B3021C8DE8A003B0641 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | AA65A11621C8E69E0019609A /* Klendario.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Klendario.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | /* End PBXFileReference section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | AA4F5B1E21C8DE88003B0641 /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | AA65A11721C8E69E0019609A /* Klendario.framework in Frameworks */, 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXFrameworksBuildPhase section */ 54 | 55 | /* Begin PBXGroup section */ 56 | AA4F5B1821C8DE88003B0641 = { 57 | isa = PBXGroup; 58 | children = ( 59 | AA65A11621C8E69E0019609A /* Klendario.framework */, 60 | AA4F5B2321C8DE88003B0641 /* iOS Example */, 61 | AA4F5B2221C8DE88003B0641 /* Products */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | AA4F5B2221C8DE88003B0641 /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | AA4F5B2121C8DE88003B0641 /* iOS Example.app */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | AA4F5B2321C8DE88003B0641 /* iOS Example */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | AA4F5B2421C8DE88003B0641 /* AppDelegate.swift */, 77 | AA4F5B2621C8DE88003B0641 /* ViewController.swift */, 78 | AA4F5B3721C8DEEB003B0641 /* Supporting files */, 79 | AA4F5B3621C8DEE6003B0641 /* Resources */, 80 | ); 81 | path = "iOS Example"; 82 | sourceTree = ""; 83 | }; 84 | AA4F5B3621C8DEE6003B0641 /* Resources */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | AA4F5B2821C8DE88003B0641 /* Main.storyboard */, 88 | AA4F5B2D21C8DE8A003B0641 /* LaunchScreen.storyboard */, 89 | AA4F5B2B21C8DE8A003B0641 /* Assets.xcassets */, 90 | ); 91 | path = Resources; 92 | sourceTree = ""; 93 | }; 94 | AA4F5B3721C8DEEB003B0641 /* Supporting files */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | AA4F5B3021C8DE8A003B0641 /* Info.plist */, 98 | ); 99 | path = "Supporting files"; 100 | sourceTree = ""; 101 | }; 102 | /* End PBXGroup section */ 103 | 104 | /* Begin PBXNativeTarget section */ 105 | AA4F5B2021C8DE88003B0641 /* iOS Example */ = { 106 | isa = PBXNativeTarget; 107 | buildConfigurationList = AA4F5B3321C8DE8A003B0641 /* Build configuration list for PBXNativeTarget "iOS Example" */; 108 | buildPhases = ( 109 | AA4F5B1D21C8DE88003B0641 /* Sources */, 110 | AA4F5B1E21C8DE88003B0641 /* Frameworks */, 111 | AA4F5B1F21C8DE88003B0641 /* Resources */, 112 | AA65A11521C8E56A0019609A /* Embed Frameworks */, 113 | ); 114 | buildRules = ( 115 | ); 116 | dependencies = ( 117 | ); 118 | name = "iOS Example"; 119 | productName = "iOS Example"; 120 | productReference = AA4F5B2121C8DE88003B0641 /* iOS Example.app */; 121 | productType = "com.apple.product-type.application"; 122 | }; 123 | /* End PBXNativeTarget section */ 124 | 125 | /* Begin PBXProject section */ 126 | AA4F5B1921C8DE88003B0641 /* Project object */ = { 127 | isa = PBXProject; 128 | attributes = { 129 | LastSwiftUpdateCheck = 1010; 130 | LastUpgradeCheck = 1010; 131 | ORGANIZATIONNAME = ThXou; 132 | TargetAttributes = { 133 | AA4F5B2021C8DE88003B0641 = { 134 | CreatedOnToolsVersion = 10.1; 135 | }; 136 | }; 137 | }; 138 | buildConfigurationList = AA4F5B1C21C8DE88003B0641 /* Build configuration list for PBXProject "iOS Example" */; 139 | compatibilityVersion = "Xcode 9.3"; 140 | developmentRegion = en; 141 | hasScannedForEncodings = 0; 142 | knownRegions = ( 143 | en, 144 | Base, 145 | ); 146 | mainGroup = AA4F5B1821C8DE88003B0641; 147 | productRefGroup = AA4F5B2221C8DE88003B0641 /* Products */; 148 | projectDirPath = ""; 149 | projectRoot = ""; 150 | targets = ( 151 | AA4F5B2021C8DE88003B0641 /* iOS Example */, 152 | ); 153 | }; 154 | /* End PBXProject section */ 155 | 156 | /* Begin PBXResourcesBuildPhase section */ 157 | AA4F5B1F21C8DE88003B0641 /* Resources */ = { 158 | isa = PBXResourcesBuildPhase; 159 | buildActionMask = 2147483647; 160 | files = ( 161 | AA4F5B2F21C8DE8A003B0641 /* LaunchScreen.storyboard in Resources */, 162 | AA4F5B2C21C8DE8A003B0641 /* Assets.xcassets in Resources */, 163 | AA4F5B2A21C8DE88003B0641 /* Main.storyboard in Resources */, 164 | ); 165 | runOnlyForDeploymentPostprocessing = 0; 166 | }; 167 | /* End PBXResourcesBuildPhase section */ 168 | 169 | /* Begin PBXSourcesBuildPhase section */ 170 | AA4F5B1D21C8DE88003B0641 /* Sources */ = { 171 | isa = PBXSourcesBuildPhase; 172 | buildActionMask = 2147483647; 173 | files = ( 174 | AA4F5B2721C8DE88003B0641 /* ViewController.swift in Sources */, 175 | AA4F5B2521C8DE88003B0641 /* AppDelegate.swift in Sources */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXSourcesBuildPhase section */ 180 | 181 | /* Begin PBXVariantGroup section */ 182 | AA4F5B2821C8DE88003B0641 /* Main.storyboard */ = { 183 | isa = PBXVariantGroup; 184 | children = ( 185 | AA4F5B2921C8DE88003B0641 /* Base */, 186 | ); 187 | name = Main.storyboard; 188 | sourceTree = ""; 189 | }; 190 | AA4F5B2D21C8DE8A003B0641 /* LaunchScreen.storyboard */ = { 191 | isa = PBXVariantGroup; 192 | children = ( 193 | AA4F5B2E21C8DE8A003B0641 /* Base */, 194 | ); 195 | name = LaunchScreen.storyboard; 196 | sourceTree = ""; 197 | }; 198 | /* End PBXVariantGroup section */ 199 | 200 | /* Begin XCBuildConfiguration section */ 201 | AA4F5B3121C8DE8A003B0641 /* Debug */ = { 202 | isa = XCBuildConfiguration; 203 | buildSettings = { 204 | ALWAYS_SEARCH_USER_PATHS = NO; 205 | CLANG_ANALYZER_NONNULL = YES; 206 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 207 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 208 | CLANG_CXX_LIBRARY = "libc++"; 209 | CLANG_ENABLE_MODULES = YES; 210 | CLANG_ENABLE_OBJC_ARC = YES; 211 | CLANG_ENABLE_OBJC_WEAK = YES; 212 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 213 | CLANG_WARN_BOOL_CONVERSION = YES; 214 | CLANG_WARN_COMMA = YES; 215 | CLANG_WARN_CONSTANT_CONVERSION = YES; 216 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 217 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 218 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 219 | CLANG_WARN_EMPTY_BODY = YES; 220 | CLANG_WARN_ENUM_CONVERSION = YES; 221 | CLANG_WARN_INFINITE_RECURSION = YES; 222 | CLANG_WARN_INT_CONVERSION = YES; 223 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 224 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 225 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 226 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 227 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 228 | CLANG_WARN_STRICT_PROTOTYPES = YES; 229 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 230 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 231 | CLANG_WARN_UNREACHABLE_CODE = YES; 232 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 233 | CODE_SIGN_IDENTITY = "iPhone Developer"; 234 | COPY_PHASE_STRIP = NO; 235 | DEBUG_INFORMATION_FORMAT = dwarf; 236 | ENABLE_STRICT_OBJC_MSGSEND = YES; 237 | ENABLE_TESTABILITY = YES; 238 | GCC_C_LANGUAGE_STANDARD = gnu11; 239 | GCC_DYNAMIC_NO_PIC = NO; 240 | GCC_NO_COMMON_BLOCKS = YES; 241 | GCC_OPTIMIZATION_LEVEL = 0; 242 | GCC_PREPROCESSOR_DEFINITIONS = ( 243 | "DEBUG=1", 244 | "$(inherited)", 245 | ); 246 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 247 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 248 | GCC_WARN_UNDECLARED_SELECTOR = YES; 249 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 250 | GCC_WARN_UNUSED_FUNCTION = YES; 251 | GCC_WARN_UNUSED_VARIABLE = YES; 252 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 253 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 254 | MTL_FAST_MATH = YES; 255 | ONLY_ACTIVE_ARCH = YES; 256 | SDKROOT = iphoneos; 257 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 258 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 259 | }; 260 | name = Debug; 261 | }; 262 | AA4F5B3221C8DE8A003B0641 /* Release */ = { 263 | isa = XCBuildConfiguration; 264 | buildSettings = { 265 | ALWAYS_SEARCH_USER_PATHS = NO; 266 | CLANG_ANALYZER_NONNULL = YES; 267 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 268 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 269 | CLANG_CXX_LIBRARY = "libc++"; 270 | CLANG_ENABLE_MODULES = YES; 271 | CLANG_ENABLE_OBJC_ARC = YES; 272 | CLANG_ENABLE_OBJC_WEAK = YES; 273 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 274 | CLANG_WARN_BOOL_CONVERSION = YES; 275 | CLANG_WARN_COMMA = YES; 276 | CLANG_WARN_CONSTANT_CONVERSION = YES; 277 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 279 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 280 | CLANG_WARN_EMPTY_BODY = YES; 281 | CLANG_WARN_ENUM_CONVERSION = YES; 282 | CLANG_WARN_INFINITE_RECURSION = YES; 283 | CLANG_WARN_INT_CONVERSION = YES; 284 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 285 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 286 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 287 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 288 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 289 | CLANG_WARN_STRICT_PROTOTYPES = YES; 290 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 291 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 292 | CLANG_WARN_UNREACHABLE_CODE = YES; 293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 294 | CODE_SIGN_IDENTITY = "iPhone Developer"; 295 | COPY_PHASE_STRIP = NO; 296 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 297 | ENABLE_NS_ASSERTIONS = NO; 298 | ENABLE_STRICT_OBJC_MSGSEND = YES; 299 | GCC_C_LANGUAGE_STANDARD = gnu11; 300 | GCC_NO_COMMON_BLOCKS = YES; 301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 303 | GCC_WARN_UNDECLARED_SELECTOR = YES; 304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 305 | GCC_WARN_UNUSED_FUNCTION = YES; 306 | GCC_WARN_UNUSED_VARIABLE = YES; 307 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 308 | MTL_ENABLE_DEBUG_INFO = NO; 309 | MTL_FAST_MATH = YES; 310 | SDKROOT = iphoneos; 311 | SWIFT_COMPILATION_MODE = wholemodule; 312 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 313 | VALIDATE_PRODUCT = YES; 314 | }; 315 | name = Release; 316 | }; 317 | AA4F5B3421C8DE8A003B0641 /* Debug */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 321 | CODE_SIGN_STYLE = Automatic; 322 | DEVELOPMENT_TEAM = BZ3VSUA92U; 323 | INFOPLIST_FILE = "$(SRCROOT)/iOS Example/Supporting files/Info.plist"; 324 | LD_RUNPATH_SEARCH_PATHS = ( 325 | "$(inherited)", 326 | "@executable_path/Frameworks", 327 | ); 328 | PRODUCT_BUNDLE_IDENTIFIER = "com.thxou.Klendario-iOS-Example"; 329 | PRODUCT_NAME = "$(TARGET_NAME)"; 330 | SWIFT_VERSION = 4.2; 331 | TARGETED_DEVICE_FAMILY = "1,2"; 332 | }; 333 | name = Debug; 334 | }; 335 | AA4F5B3521C8DE8A003B0641 /* Release */ = { 336 | isa = XCBuildConfiguration; 337 | buildSettings = { 338 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 339 | CODE_SIGN_STYLE = Automatic; 340 | DEVELOPMENT_TEAM = BZ3VSUA92U; 341 | INFOPLIST_FILE = "$(SRCROOT)/iOS Example/Supporting files/Info.plist"; 342 | LD_RUNPATH_SEARCH_PATHS = ( 343 | "$(inherited)", 344 | "@executable_path/Frameworks", 345 | ); 346 | PRODUCT_BUNDLE_IDENTIFIER = "com.thxou.Klendario-iOS-Example"; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | SWIFT_VERSION = 4.2; 349 | TARGETED_DEVICE_FAMILY = "1,2"; 350 | }; 351 | name = Release; 352 | }; 353 | /* End XCBuildConfiguration section */ 354 | 355 | /* Begin XCConfigurationList section */ 356 | AA4F5B1C21C8DE88003B0641 /* Build configuration list for PBXProject "iOS Example" */ = { 357 | isa = XCConfigurationList; 358 | buildConfigurations = ( 359 | AA4F5B3121C8DE8A003B0641 /* Debug */, 360 | AA4F5B3221C8DE8A003B0641 /* Release */, 361 | ); 362 | defaultConfigurationIsVisible = 0; 363 | defaultConfigurationName = Release; 364 | }; 365 | AA4F5B3321C8DE8A003B0641 /* Build configuration list for PBXNativeTarget "iOS Example" */ = { 366 | isa = XCConfigurationList; 367 | buildConfigurations = ( 368 | AA4F5B3421C8DE8A003B0641 /* Debug */, 369 | AA4F5B3521C8DE8A003B0641 /* Release */, 370 | ); 371 | defaultConfigurationIsVisible = 0; 372 | defaultConfigurationName = Release; 373 | }; 374 | /* End XCConfigurationList section */ 375 | }; 376 | rootObject = AA4F5B1921C8DE88003B0641 /* Project object */; 377 | } 378 | --------------------------------------------------------------------------------