├── Gemfile ├── imgs ├── Policy.png ├── ExampleModel.png └── PolicyExample.png ├── .travis.yml ├── Example ├── ExampleGif.gif ├── Example │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ViewController.swift │ ├── GroupTableViewCell.swift │ ├── Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── GroupsViewController.swift │ ├── AppDelegate.swift │ └── KoosaConfig.swift ├── Example.xcodeproj │ ├── xcuserdata │ │ └── mostafa.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── project.pbxproj ├── ExampleTests │ ├── Info.plist │ └── ExampleTests.swift └── ExampleUITests │ ├── Info.plist │ └── ExampleUITests.swift ├── Koosa ├── Kooosa.xcworkspace │ ├── xcuserdata │ │ └── mostafa.xcuserdatad │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Koosa.h ├── Info.plist └── Koosa.swift ├── Koosa.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── mostafa.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── xcshareddata │ └── xcschemes │ │ ├── KoosaTests.xcscheme │ │ └── Koosa.xcscheme └── project.pbxproj ├── fastlane ├── Appfile ├── test_output │ ├── report.junit │ └── report.html ├── README.md ├── Fastfile └── report.xml ├── Koosa.podspec ├── KoosaTests ├── Info.plist └── KoosaTests.swift ├── LICENSE └── README.md /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | gem "slather" 5 | -------------------------------------------------------------------------------- /imgs/Policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmabdelateef/Koosa/HEAD/imgs/Policy.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode9.3 3 | script: fastlane coverage 4 | -------------------------------------------------------------------------------- /Example/ExampleGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmabdelateef/Koosa/HEAD/Example/ExampleGif.gif -------------------------------------------------------------------------------- /imgs/ExampleModel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmabdelateef/Koosa/HEAD/imgs/ExampleModel.png -------------------------------------------------------------------------------- /imgs/PolicyExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmabdelateef/Koosa/HEAD/imgs/PolicyExample.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Koosa/Kooosa.xcworkspace/xcuserdata/mostafa.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Koosa/Kooosa.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Koosa.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | # app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app 2 | # apple_id("[[APPLE_ID]]") # Your Apple email address 3 | 4 | 5 | # For more information about the Appfile, see: 6 | # https://docs.fastlane.tools/advanced/#appfile 7 | -------------------------------------------------------------------------------- /Koosa/Kooosa.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fastlane/test_output/report.junit: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Koosa.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/xcuserdata/mostafa.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Example.xcscheme 8 | 9 | orderHint 10 | 2 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Koosa/Koosa.h: -------------------------------------------------------------------------------- 1 | // 2 | // Koosa.h 3 | // Koosa 4 | // 5 | // Created by Mostafa Abdellateef on 8/31/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Koosa. 12 | FOUNDATION_EXPORT double KoosaVersionNumber; 13 | 14 | //! Project version string for Koosa. 15 | FOUNDATION_EXPORT const unsigned char KoosaVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Example/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Koosa 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var usernameTextField: UITextField! 15 | 16 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 17 | if let groupsVC = segue.destination as? GroupsViewController { 18 | groupsVC.username = usernameTextField.text 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Koosa.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "Koosa" 4 | s.version = "1.0.1" 5 | s.summary = "Attributed Role-based Access Control For Swift" 6 | 7 | s.description = "A simple Attributed Role-based Access Control For Swift" 8 | 9 | s.homepage = "https://github.com/mmabdelateef/Koosa" 10 | 11 | s.license = "MIT" 12 | 13 | 14 | 15 | s.author = { "mabdellateef" => "mmabdelateef@gmail.com" } 16 | s.social_media_url = "https://twitter.com/mmabdellateef" 17 | 18 | s.platform = :ios, "8.0" 19 | 20 | s.source = { :git => "https://github.com/mmabdelateef/Koosa.git", :tag => "1.0.1" } 21 | 22 | s.source_files = "Koosa", "Koosa/**/*.{h,m,swift}" 23 | s.swift_version = "4.1" 24 | 25 | end -------------------------------------------------------------------------------- /KoosaTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/ExampleTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/ExampleUITests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Koosa/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 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Koosa.xcodeproj/xcuserdata/mostafa.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Koosa.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | KoosaTests.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 0693FAD02139926100939364 21 | 22 | primary 23 | 24 | 25 | 0693FAD92139926200939364 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/Example/GroupTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GroupTableViewCell.swift 3 | // Example 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GroupTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var groupNameLabel: UILabel! 14 | @IBOutlet weak var deleteBtn: UIButton! 15 | @IBOutlet weak var postBtn: UIButton! 16 | @IBOutlet weak var publicLabel: UILabel! 17 | @IBOutlet weak var browseBtn: UIButton! 18 | 19 | override func awakeFromNib() { 20 | super.awakeFromNib() 21 | 22 | postBtn.layer.cornerRadius = 3 23 | postBtn.clipsToBounds = true 24 | 25 | browseBtn.layer.cornerRadius = 3 26 | browseBtn.clipsToBounds = true 27 | 28 | deleteBtn.layer.cornerRadius = 3 29 | deleteBtn.clipsToBounds = true 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew cask install fastlane` 16 | 17 | # Available Actions 18 | ## iOS 19 | ### ios custom_lane 20 | ``` 21 | fastlane ios custom_lane 22 | ``` 23 | Description of what the lane does 24 | ### ios test 25 | ``` 26 | fastlane ios test 27 | ``` 28 | Runs all the tests 29 | ### ios coverage 30 | ``` 31 | fastlane ios coverage 32 | ``` 33 | Runs coverage 34 | 35 | ---- 36 | 37 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 38 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 39 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 40 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:ios) 17 | 18 | platform :ios do 19 | desc "Description of what the lane does" 20 | lane :custom_lane do 21 | # add actions here: https://docs.fastlane.tools/actions 22 | end 23 | 24 | desc "Runs all the tests" 25 | lane :test do 26 | scan( 27 | scheme: "Koosa", 28 | code_coverage: true 29 | ) 30 | end 31 | 32 | desc “Runs coverage” 33 | lane :coverage do 34 | test 35 | slather( 36 | travis: true, 37 | scheme: "Koosa", 38 | coveralls: true, 39 | proj: "Koosa.xcodeproj") 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mostafa Abdellateef 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 | -------------------------------------------------------------------------------- /Example/ExampleTests/ExampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleTests.swift 3 | // ExampleTests 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Example 11 | 12 | class ExampleTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/ExampleUITests/ExampleUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleUITests.swift 3 | // ExampleUITests 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ExampleUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/Example/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 | APPL 17 | CFBundleShortVersionString 18 | 1.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 | 45 | 46 | -------------------------------------------------------------------------------- /Koosa/Koosa.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Koosa.swift 3 | // Koosa 4 | // 5 | // Created by Mostafa Abdellateef on 8/31/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol Action { 12 | init() 13 | static var action: Action.Type { get } 14 | } 15 | 16 | public extension Action { 17 | static var action: Action.Type { return Self.self } 18 | } 19 | 20 | public protocol Role { 21 | init() 22 | static func shouldBeAbleTo (_ action: Action.Type) -> Policy 23 | func can (_ action: Action) -> Bool 24 | } 25 | 26 | public extension Role { 27 | 28 | static func shouldBeAbleTo(_ action: Action.Type) -> Policy { 29 | let rule = Policy(action: action.init(), role: self.init()) 30 | rule.condition = { role, action in 31 | guard role is Self else { 32 | return false 33 | } 34 | return true 35 | } 36 | rules.append(rule) 37 | return rule 38 | } 39 | 40 | func can (_ action: Action) -> Bool { 41 | return rules.reduce(false) { 42 | $1.apply(role: self, action: action) || $0 43 | } 44 | } 45 | } 46 | 47 | public class Policy { 48 | 49 | let action: Action 50 | let role: Role 51 | var condition: ((Role, Action) -> Bool)? 52 | 53 | init(action: Action, role: Role) { 54 | self.action = action 55 | self.role = role 56 | } 57 | 58 | func apply(role: Role, action: Action) -> Bool { 59 | return condition?(role, action) ?? false 60 | } 61 | 62 | public func when(condition: @escaping (Role, Action) -> Bool) { 63 | self.condition = condition 64 | } 65 | } 66 | 67 | internal var rules = [Policy]() 68 | -------------------------------------------------------------------------------- /Example/Example/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/Example/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 | } -------------------------------------------------------------------------------- /Example/Example/GroupsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GroupsViewController.swift 3 | // Example 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Koosa 11 | 12 | 13 | class GroupsViewController: UITableViewController { 14 | 15 | var user: Role? 16 | var username : String? 17 | 18 | let groups = [Group(groupNumber: 1, isPublicGroup: true), 19 | Group(groupNumber: 2, isPublicGroup: false), 20 | Group(groupNumber: 3, isPublicGroup: false), 21 | Group(groupNumber: 4, isPublicGroup: true)] 22 | 23 | let users = [GroupMemberUser(name: "Group1Member", age: 18, groupNumber: 1), 24 | GroupMemberUser(name: "Group2Member", age: 22, groupNumber: 2), 25 | GroupAdminUser(name: "Group1Admin", age: 18, groupNumber: 1), 26 | GroupAdminUser(name: "Group3Admin", age: 30, groupNumber: 3), 27 | SuperAdminUser(name: "SuperAdmin", age: 30)] 28 | 29 | var allowedGroups: [Group] { 30 | user = users.filter { $0.name == username }.first as? Role ?? Visitor() 31 | return groups.filter { user?.can(BrowseGroup(group: $0)) ?? false } 32 | } 33 | 34 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 35 | let cell = tableView.dequeueReusableCell(withIdentifier: "groupCell", for: indexPath) as! GroupTableViewCell 36 | let group = allowedGroups[indexPath.row] 37 | cell.deleteBtn.isHidden = !(user?.can(DeleteGroup(group: group)) ?? false) 38 | cell.postBtn.isHidden = !(user?.can(PostToGroup(group: group)) ?? false) 39 | cell.publicLabel.isHidden = !group.isPublicGroup 40 | cell.groupNameLabel.text = "Group \(group.groupNumber)" 41 | return cell 42 | } 43 | 44 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 45 | return allowedGroups.count 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Koosa.xcodeproj/xcshareddata/xcschemes/KoosaTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 16 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | 43 | 49 | 50 | 52 | 53 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Example/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | configureKoosaRules() 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // 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. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/Example/KoosaConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KoosaConfig.swift 3 | // Example 4 | // 5 | // Created by Mostafa Abdellateef on 9/2/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Koosa 11 | 12 | func configureKoosaRules() { 13 | 14 | GroupMemberUser.shouldBeAbleTo(BrowseGroup.action).when { 15 | guard let groupMember = $0 as? GroupMember, 16 | let browseAction = $1 as? BrowseGroup else { return false } 17 | return groupMember.groupNumber == browseAction.group.groupNumber 18 | } 19 | 20 | GroupMemberUser.shouldBeAbleTo(PostToGroup.action).when { 21 | guard let groupMember = $0 as? GroupMember, 22 | let postAction = $1 as? PostToGroup else { return false } 23 | return groupMember.groupNumber == postAction.group.groupNumber 24 | } 25 | 26 | // Admin inherits Member 27 | GroupAdminUser.shouldBeAbleTo(DeleteGroup.action).when { 28 | guard let groupAdmin = $0 as? GroupAdmin, 29 | let deleteAction = $1 as? DeleteGroup else { return false } 30 | return groupAdmin.groupNumber == deleteAction.group.groupNumber 31 | } 32 | 33 | Visitor.shouldBeAbleTo(BrowseGroup.action).when { 34 | guard let browseAction = $1 as? BrowseGroup else { return false } 35 | return browseAction.group.isPublicGroup 36 | } 37 | 38 | _ = SuperAdminUser.shouldBeAbleTo(BrowseGroup.action) 39 | _ = SuperAdminUser.shouldBeAbleTo(DeleteGroup.action) 40 | _ = SuperAdminUser.shouldBeAbleTo(PostToGroup.action) 41 | } 42 | 43 | protocol GroupMember: Role { 44 | var groupNumber: Int {set get} 45 | } 46 | protocol GroupAdmin: GroupMember { } 47 | protocol SuperAdmin: Role { } 48 | 49 | 50 | class User { 51 | var name: String? 52 | var age: Int? 53 | init(name: String, age: Int) { 54 | self.name = name 55 | self.age = age 56 | } 57 | 58 | init() { } 59 | } 60 | 61 | class VisitorUser: User { } 62 | class GroupMemberUser: User, GroupMember { 63 | var groupNumber: Int 64 | init(name: String, age: Int, groupNumber: Int) { 65 | self.groupNumber = groupNumber 66 | super.init(name: name, age: age) 67 | } 68 | 69 | override required init() { 70 | self.groupNumber = -1 71 | super.init() 72 | } 73 | 74 | } 75 | class GroupAdminUser: User, GroupAdmin { 76 | var groupNumber: Int 77 | init(name: String, age: Int, groupNumber: Int) { 78 | self.groupNumber = groupNumber 79 | super.init(name: name, age: age) 80 | } 81 | 82 | override required init() { 83 | self.groupNumber = -1 84 | super.init() 85 | } 86 | } 87 | 88 | class SuperAdminUser: User, SuperAdmin { 89 | override required init() { 90 | super.init() 91 | } 92 | 93 | override init(name: String, age: Int) { 94 | super.init(name: name, age: age) 95 | } 96 | } 97 | 98 | class Visitor: Role { 99 | required init() {} 100 | } 101 | 102 | struct Group { 103 | let groupNumber: Int 104 | let isPublicGroup: Bool 105 | } 106 | 107 | 108 | struct BrowseGroup: Action { 109 | init() { 110 | group = Group(groupNumber: -1, isPublicGroup: false) 111 | } 112 | let group: Group 113 | 114 | init(group: Group) { 115 | self.group = group 116 | } 117 | } 118 | 119 | struct PostToGroup: Action { 120 | init() { 121 | group = Group(groupNumber: -1, isPublicGroup: false) 122 | } 123 | let group: Group 124 | 125 | init(group: Group) { 126 | self.group = group 127 | } 128 | } 129 | 130 | struct DeleteGroup: Action { 131 | init() { 132 | group = Group(groupNumber: -1, isPublicGroup: false) 133 | } 134 | let group: Group 135 | 136 | init(group: Group) { 137 | self.group = group 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Koosa.xcodeproj/xcshareddata/xcschemes/Koosa.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /fastlane/report.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Koosa   [![Build Status](https://travis-ci.org/mmabdelateef/Koosa.svg?branch=master)](https://travis-ci.org/mmabdelateef/Koosa) [![Coverage Status](https://coveralls.io/repos/github/mmabdelateef/Koosa/badge.svg?branch=master)](https://coveralls.io/github/mmabdelateef/Koosa?branch=master) 2 | Declarative Swift framework for Attributed Role-based Access Control management 3 | #### Check out this blog post for full explanation and more details: [Access Control Management with Swift](https://medium.com/@mmabdelateef/access-control-management-with-swift-cc3c3d68cbc3) 4 | 5 | ## Example 6 | ![](imgs/PolicyExample.png) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 48 | 50 |
CodeIn Action
 14 |     
 15 |     // Anyone can browse group, if it is public
 16 |     Visitor.shouldBeAbleTo(BrowseGroup.action).when {
 17 |         guard let browseAction = $1 as? BrowseGroup else { return false }
 18 |         return browseAction.group.isPublicGroup
 19 |     }
 20 |     
 21 |     // Member can browse his groups + public groups
 22 |     GroupMemberUser.shouldBeAbleTo(BrowseGroup.action).when {
 23 |         guard let groupMember = $0 as? GroupMember,
 24 |             let browseAction = $1 as? BrowseGroup else { return false }
 25 |         return groupMember.groupNumber == browseAction.group.groupNumber
 26 |     }
 27 |     
 28 |     // Member can post his groups 
 29 |     GroupMemberUser.shouldBeAbleTo(PostToGroup.action).when {
 30 |         guard let groupMember = $0 as? GroupMember,
 31 |             let postAction = $1 as? PostToGroup else { return false }
 32 |         return groupMember.groupNumber == postAction.group.groupNumber
 33 |     }
 34 |     
 35 |     // Admin class extends Member + ability to delete
 36 |     GroupAdminUser.shouldBeAbleTo(DeleteGroup.action).when {
 37 |         guard let groupAdmin = $0 as? GroupAdmin,
 38 |             let deleteAction = $1 as? DeleteGroup else { return false }
 39 |         return groupAdmin.groupNumber == deleteAction.group.groupNumber
 40 |     }
 41 |     
 42 |     // SuperAdmin can do everything
 43 |     _ = SuperAdminUser.shouldBeAbleTo(BrowseGroup.action)
 44 |     _ = SuperAdminUser.shouldBeAbleTo(DeleteGroup.action)
 45 |     _ = SuperAdminUser.shouldBeAbleTo(PostToGroup.action)
 46 |     
 47 | 
49 |
51 | 52 | ## Usage: 53 | 54 | 1. Start by mapping each role in your requirements to a protocl that extends to prtocol `Role` or a protocl that extends it. Note that you can model role heirarchy using protocl inheritance. 55 | ```swift 56 | protocol GroupMember: Role { 57 | var groupNumber: Int {set get} 58 | } 59 | protocol GroupAdmin: GroupMember { } 60 | ``` 61 | 62 | 2. Model your actions into classes/strcut that conforms to protocl `Action`. 63 | ```swift 64 | struct BrowseGroup: Action { 65 | let group: Group 66 | 67 | init() { // required default initializer 68 | group = Group(groupNumber: -1, isPublicGroup: false) // default froup 69 | } 70 | 71 | init(group: Group) { 72 | self.group = group 73 | } 74 | } 75 | ``` 76 | 3. Use role protocls to create concrete role classes. 77 | ```swift 78 | class GroupAdminUser: User, GroupAdmin { 79 | var groupNumber: Int 80 | init(name: String, age: Int, groupNumber: Int) { 81 | self.groupNumber = groupNumber 82 | super.init(name: name, age: age) 83 | } 84 | 85 | override required init() { 86 | self.groupNumber = -1 87 | super.init() 88 | } 89 | } 90 | ``` 91 | 4. Add the policies. 92 | ```swift 93 | GroupMemberUser.shouldBeAbleTo(BrowseGroup.action).when { 94 | guard let groupMember = $0 as? GroupMember, 95 | let browseAction = $1 as? BrowseGroup else { return false } 96 | return groupMember.groupNumber == browseAction.group.groupNumber 97 | } 98 | GroupAdminUser.shouldBeAbleTo(DeleteGroup.action).when { 99 | guard let groupAdmin = $0 as? GroupAdminUser, 100 | let deleteAction = $1 as? DeleteGroup else { 101 | return false 102 | } 103 | return groupAdmin.groupNumber == deleteAction.group.groupNumber 104 | } 105 | _ = SuperAdminUser.shouldBeAbleTo(BrowseGroup.action) 106 | ``` 107 | 5. Now you can validate if any user can do any action. 108 | ```swift 109 | let member1 = GroupMemberUser(name: "member1", age: 18, groupNumber: 1) 110 | let admin2 = GroupAdminUser(name: "admin2", age: 22, groupNumber: 2) 111 | let group1 = Group(groupNumber: 1, isPublicGroup: false) 112 | let group2 = Group(groupNumber: 2, isPublicGroup: false) 113 | member1.can(BrowseGroup(group: group1) // true 114 | member1.can(BrowseGroup(group: group2) // false 115 | admin2.can(BrowseGroup(group: group1) // true: GroupAdmin inherits BrowseGroup permission from GroupMember 116 | admin2.can(DeleteGroup(group: group2) // true 117 | admin2.can(DeleteGroup(group: group1) // false 118 | ``` 119 | 120 | ## Installation 121 | 122 | Koosa can be installed using CocoaPods 123 | ```sh 124 | use_frameworks! 125 | pod 'Koosa' 126 | ``` 127 | 128 | License 129 | ---- 130 | 131 | MIT 132 | -------------------------------------------------------------------------------- /KoosaTests/KoosaTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KoosaTests.swift 3 | // KoosaTests 4 | // 5 | // Created by Mostafa Abdellateef on 8/31/18. 6 | // Copyright © 2018 Mostafa Abdellateef. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Koosa 11 | 12 | class KoosaTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | func testExample() { 23 | 24 | GroupAdminUser.shouldBeAbleTo(DeleteGroup.action).when { 25 | guard let groupAdmin = $0 as? GroupAdminUser, 26 | let deleteAction = $1 as? DeleteGroup else { 27 | return false 28 | } 29 | return groupAdmin.groupNumber == 30 | deleteAction.group.groupNumber 31 | } 32 | 33 | GroupMemberUser.shouldBeAbleTo(BrowseGroup.action).when { 34 | guard let groupMember = $0 as? GroupMember, 35 | let browseAction = $1 as? BrowseGroup else { return false } 36 | return groupMember.groupNumber == browseAction.group.groupNumber 37 | } 38 | 39 | AnonymousUser.shouldBeAbleTo(BrowseGroup.action).when { 40 | guard let browseAction = $1 as? BrowseGroup else { return false } 41 | return browseAction.group.isPublicGroup 42 | } 43 | 44 | _ = SuperAdminUser.shouldBeAbleTo(BrowseGroup.action) 45 | _ = SuperAdminUser.shouldBeAbleTo(PostToGroup.action) 46 | _ = SuperAdminUser.shouldBeAbleTo(DeleteGroup.action) 47 | 48 | let group1 = Group(groupNumber: 1, isPublicGroup: false) 49 | let group2 = Group(groupNumber: 2, isPublicGroup: true) 50 | 51 | let visitor = AnonymousUser() 52 | let member1 = GroupMemberUser(name: "member1", age: 18, groupNumber: 1) 53 | let member2 = GroupMemberUser(name: "member2", age: 22, groupNumber: 2) 54 | let admin1 = GroupAdminUser(name: "admin1", age: 18, groupNumber: 1) 55 | let admin2 = GroupAdminUser(name: "admin2", age: 22, groupNumber: 2) 56 | let superAdmin = SuperAdminUser(name: "SuperAdmin", age: 30) 57 | 58 | assert(member1.can(BrowseGroup(group: group1))) 59 | assert(!member2.can(BrowseGroup(group: group1))) 60 | assert(!visitor.can(BrowseGroup(group: group1))) 61 | assert(visitor.can(BrowseGroup(group: group2))) 62 | assert(!visitor.can(DeleteGroup(group: group1))) 63 | assert(admin1.can(DeleteGroup(group: group1))) 64 | assert(admin1.can(BrowseGroup(group: group1))) 65 | assert(!admin1.can(DeleteGroup(group: group2))) 66 | assert(!admin2.can(DeleteGroup(group: group1))) 67 | assert(admin2.can(DeleteGroup(group: group2))) 68 | assert(superAdmin.can(DeleteGroup(group: group2))) 69 | } 70 | } 71 | 72 | 73 | protocol GroupMember: Role { 74 | var groupNumber: Int {set get} 75 | } 76 | protocol GroupAdmin: GroupMember { } 77 | protocol SuperAdmin: Role { } 78 | 79 | 80 | class User { 81 | var name: String? 82 | var age: Int? 83 | init(name: String, age: Int) { 84 | self.name = name 85 | self.age = age 86 | } 87 | 88 | init() { 89 | 90 | } 91 | } 92 | 93 | //class VisitorUser: User { } 94 | class GroupMemberUser: User, GroupMember { 95 | var groupNumber: Int 96 | init(name: String, age: Int, groupNumber: Int) { 97 | self.groupNumber = groupNumber 98 | super.init(name: name, age: age) 99 | } 100 | 101 | override required init() { 102 | self.groupNumber = -1 103 | super.init() 104 | } 105 | 106 | } 107 | class GroupAdminUser: User, GroupAdmin { 108 | var groupNumber: Int 109 | init(name: String, age: Int, groupNumber: Int) { 110 | self.groupNumber = groupNumber 111 | super.init(name: name, age: age) 112 | } 113 | 114 | override required init() { 115 | self.groupNumber = -1 116 | super.init() 117 | } 118 | } 119 | 120 | class SuperAdminUser: User, SuperAdmin { 121 | override required init() { 122 | super.init() 123 | } 124 | 125 | override init(name: String, age: Int) { 126 | super.init(name: name, age: age) 127 | } 128 | } 129 | 130 | protocol Anonymous: Role { 131 | 132 | } 133 | 134 | class AnonymousUser: User, Anonymous { 135 | required override init() { 136 | super.init() 137 | } 138 | } 139 | 140 | struct Group { 141 | let groupNumber: Int 142 | let isPublicGroup: Bool 143 | } 144 | 145 | struct BrowseGroup: Action { 146 | init() { 147 | group = Group(groupNumber: -1, isPublicGroup: false) 148 | } 149 | let group: Group 150 | 151 | init(group: Group) { 152 | self.group = group 153 | } 154 | } 155 | 156 | struct PostToGroup: Action { 157 | init() { 158 | group = Group(groupNumber: -1, isPublicGroup: false) 159 | } 160 | let group: Group 161 | 162 | init(group: Group) { 163 | self.group = group 164 | } 165 | } 166 | 167 | struct DeleteGroup: Action { 168 | init() { 169 | group = Group(groupNumber: -1, isPublicGroup: false) 170 | } 171 | let group: Group 172 | 173 | init(group: Group) { 174 | self.group = group 175 | } 176 | } 177 | 178 | -------------------------------------------------------------------------------- /fastlane/test_output/report.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test Results | xcpretty 6 | 61 | 105 | 106 | 107 |
108 |
109 |

Test Results

110 |
111 |
112 |
113 |

1 tests

114 | 115 |
116 |
117 | AllFailingPassing 118 |
119 |
120 |
121 |
122 | 123 | 124 |
125 |
126 |

KoosaTests.KoosaTests

127 |
128 |
129 | 130 | 131 | 132 | 133 | 138 | 139 | 140 | 141 | 142 |
134 | 135 |

0.002s

136 | 137 |

testExample

143 |
144 |
145 | 146 |
147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /Example/Example/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 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 79 | 88 | 98 | 108 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /Koosa.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0693FADB2139926200939364 /* Koosa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0693FAD12139926100939364 /* Koosa.framework */; }; 11 | 0693FAE02139926200939364 /* KoosaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FADF2139926200939364 /* KoosaTests.swift */; }; 12 | 0693FAE22139926200939364 /* Koosa.h in Headers */ = {isa = PBXBuildFile; fileRef = 0693FAD42139926100939364 /* Koosa.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 0693FAEC2139927200939364 /* Koosa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FAEB2139927200939364 /* Koosa.swift */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXContainerItemProxy section */ 17 | 0693FADC2139926200939364 /* PBXContainerItemProxy */ = { 18 | isa = PBXContainerItemProxy; 19 | containerPortal = 0693FAC82139926100939364 /* Project object */; 20 | proxyType = 1; 21 | remoteGlobalIDString = 0693FAD02139926100939364; 22 | remoteInfo = Koosa; 23 | }; 24 | 0693FB9A213C64CD00939364 /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = 0693FB94213C64CB00939364 /* Example.xcodeproj */; 27 | proxyType = 2; 28 | remoteGlobalIDString = 0693FB63213C64CA00939364; 29 | remoteInfo = Example; 30 | }; 31 | 0693FB9C213C64CD00939364 /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = 0693FB94213C64CB00939364 /* Example.xcodeproj */; 34 | proxyType = 2; 35 | remoteGlobalIDString = 0693FB77213C64CB00939364; 36 | remoteInfo = ExampleTests; 37 | }; 38 | 0693FB9E213C64CD00939364 /* PBXContainerItemProxy */ = { 39 | isa = PBXContainerItemProxy; 40 | containerPortal = 0693FB94213C64CB00939364 /* Example.xcodeproj */; 41 | proxyType = 2; 42 | remoteGlobalIDString = 0693FB82213C64CB00939364; 43 | remoteInfo = ExampleUITests; 44 | }; 45 | /* End PBXContainerItemProxy section */ 46 | 47 | /* Begin PBXFileReference section */ 48 | 0693FAD12139926100939364 /* Koosa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Koosa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 0693FAD42139926100939364 /* Koosa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Koosa.h; sourceTree = ""; }; 50 | 0693FAD52139926100939364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 0693FADA2139926200939364 /* KoosaTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KoosaTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 0693FADF2139926200939364 /* KoosaTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KoosaTests.swift; sourceTree = ""; }; 53 | 0693FAE12139926200939364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 0693FAEB2139927200939364 /* Koosa.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Koosa.swift; sourceTree = ""; }; 55 | 0693FB94213C64CB00939364 /* Example.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Example.xcodeproj; path = Example/Example.xcodeproj; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 0693FACD2139926100939364 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | 0693FAD72139926200939364 /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | 0693FADB2139926200939364 /* Koosa.framework in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | /* End PBXFrameworksBuildPhase section */ 75 | 76 | /* Begin PBXGroup section */ 77 | 0693FAC72139926100939364 = { 78 | isa = PBXGroup; 79 | children = ( 80 | 0693FB94213C64CB00939364 /* Example.xcodeproj */, 81 | 0693FAD32139926100939364 /* Koosa */, 82 | 0693FADE2139926200939364 /* KoosaTests */, 83 | 0693FAD22139926100939364 /* Products */, 84 | ); 85 | sourceTree = ""; 86 | }; 87 | 0693FAD22139926100939364 /* Products */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 0693FAD12139926100939364 /* Koosa.framework */, 91 | 0693FADA2139926200939364 /* KoosaTests.xctest */, 92 | ); 93 | name = Products; 94 | sourceTree = ""; 95 | }; 96 | 0693FAD32139926100939364 /* Koosa */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 0693FAD42139926100939364 /* Koosa.h */, 100 | 0693FAD52139926100939364 /* Info.plist */, 101 | 0693FAEB2139927200939364 /* Koosa.swift */, 102 | ); 103 | path = Koosa; 104 | sourceTree = ""; 105 | }; 106 | 0693FADE2139926200939364 /* KoosaTests */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 0693FADF2139926200939364 /* KoosaTests.swift */, 110 | 0693FAE12139926200939364 /* Info.plist */, 111 | ); 112 | path = KoosaTests; 113 | sourceTree = ""; 114 | }; 115 | 0693FB95213C64CB00939364 /* Products */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 0693FB9B213C64CD00939364 /* Example.app */, 119 | 0693FB9D213C64CD00939364 /* ExampleTests.xctest */, 120 | 0693FB9F213C64CD00939364 /* ExampleUITests.xctest */, 121 | ); 122 | name = Products; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXHeadersBuildPhase section */ 128 | 0693FACE2139926100939364 /* Headers */ = { 129 | isa = PBXHeadersBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | 0693FAE22139926200939364 /* Koosa.h in Headers */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXHeadersBuildPhase section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | 0693FAD02139926100939364 /* Koosa */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = 0693FAE52139926200939364 /* Build configuration list for PBXNativeTarget "Koosa" */; 142 | buildPhases = ( 143 | 0693FACC2139926100939364 /* Sources */, 144 | 0693FACD2139926100939364 /* Frameworks */, 145 | 0693FACE2139926100939364 /* Headers */, 146 | 0693FACF2139926100939364 /* Resources */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = Koosa; 153 | productName = Koosa; 154 | productReference = 0693FAD12139926100939364 /* Koosa.framework */; 155 | productType = "com.apple.product-type.framework"; 156 | }; 157 | 0693FAD92139926200939364 /* KoosaTests */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 0693FAE82139926200939364 /* Build configuration list for PBXNativeTarget "KoosaTests" */; 160 | buildPhases = ( 161 | 0693FAD62139926200939364 /* Sources */, 162 | 0693FAD72139926200939364 /* Frameworks */, 163 | 0693FAD82139926200939364 /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | 0693FADD2139926200939364 /* PBXTargetDependency */, 169 | ); 170 | name = KoosaTests; 171 | productName = KoosaTests; 172 | productReference = 0693FADA2139926200939364 /* KoosaTests.xctest */; 173 | productType = "com.apple.product-type.bundle.unit-test"; 174 | }; 175 | /* End PBXNativeTarget section */ 176 | 177 | /* Begin PBXProject section */ 178 | 0693FAC82139926100939364 /* Project object */ = { 179 | isa = PBXProject; 180 | attributes = { 181 | LastSwiftUpdateCheck = 0930; 182 | LastUpgradeCheck = 0930; 183 | ORGANIZATIONNAME = "Mostafa Abdellateef"; 184 | TargetAttributes = { 185 | 0693FAD02139926100939364 = { 186 | CreatedOnToolsVersion = 9.3; 187 | LastSwiftMigration = 0930; 188 | }; 189 | 0693FAD92139926200939364 = { 190 | CreatedOnToolsVersion = 9.3; 191 | }; 192 | }; 193 | }; 194 | buildConfigurationList = 0693FACB2139926100939364 /* Build configuration list for PBXProject "Koosa" */; 195 | compatibilityVersion = "Xcode 9.3"; 196 | developmentRegion = en; 197 | hasScannedForEncodings = 0; 198 | knownRegions = ( 199 | en, 200 | ); 201 | mainGroup = 0693FAC72139926100939364; 202 | productRefGroup = 0693FAD22139926100939364 /* Products */; 203 | projectDirPath = ""; 204 | projectReferences = ( 205 | { 206 | ProductGroup = 0693FB95213C64CB00939364 /* Products */; 207 | ProjectRef = 0693FB94213C64CB00939364 /* Example.xcodeproj */; 208 | }, 209 | ); 210 | projectRoot = ""; 211 | targets = ( 212 | 0693FAD02139926100939364 /* Koosa */, 213 | 0693FAD92139926200939364 /* KoosaTests */, 214 | ); 215 | }; 216 | /* End PBXProject section */ 217 | 218 | /* Begin PBXReferenceProxy section */ 219 | 0693FB9B213C64CD00939364 /* Example.app */ = { 220 | isa = PBXReferenceProxy; 221 | fileType = wrapper.application; 222 | path = Example.app; 223 | remoteRef = 0693FB9A213C64CD00939364 /* PBXContainerItemProxy */; 224 | sourceTree = BUILT_PRODUCTS_DIR; 225 | }; 226 | 0693FB9D213C64CD00939364 /* ExampleTests.xctest */ = { 227 | isa = PBXReferenceProxy; 228 | fileType = wrapper.cfbundle; 229 | path = ExampleTests.xctest; 230 | remoteRef = 0693FB9C213C64CD00939364 /* PBXContainerItemProxy */; 231 | sourceTree = BUILT_PRODUCTS_DIR; 232 | }; 233 | 0693FB9F213C64CD00939364 /* ExampleUITests.xctest */ = { 234 | isa = PBXReferenceProxy; 235 | fileType = wrapper.cfbundle; 236 | path = ExampleUITests.xctest; 237 | remoteRef = 0693FB9E213C64CD00939364 /* PBXContainerItemProxy */; 238 | sourceTree = BUILT_PRODUCTS_DIR; 239 | }; 240 | /* End PBXReferenceProxy section */ 241 | 242 | /* Begin PBXResourcesBuildPhase section */ 243 | 0693FACF2139926100939364 /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | 0693FAD82139926200939364 /* Resources */ = { 251 | isa = PBXResourcesBuildPhase; 252 | buildActionMask = 2147483647; 253 | files = ( 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXResourcesBuildPhase section */ 258 | 259 | /* Begin PBXSourcesBuildPhase section */ 260 | 0693FACC2139926100939364 /* Sources */ = { 261 | isa = PBXSourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | 0693FAEC2139927200939364 /* Koosa.swift in Sources */, 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | }; 268 | 0693FAD62139926200939364 /* Sources */ = { 269 | isa = PBXSourcesBuildPhase; 270 | buildActionMask = 2147483647; 271 | files = ( 272 | 0693FAE02139926200939364 /* KoosaTests.swift in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXSourcesBuildPhase section */ 277 | 278 | /* Begin PBXTargetDependency section */ 279 | 0693FADD2139926200939364 /* PBXTargetDependency */ = { 280 | isa = PBXTargetDependency; 281 | target = 0693FAD02139926100939364 /* Koosa */; 282 | targetProxy = 0693FADC2139926200939364 /* PBXContainerItemProxy */; 283 | }; 284 | /* End PBXTargetDependency section */ 285 | 286 | /* Begin XCBuildConfiguration section */ 287 | 0693FAE32139926200939364 /* Debug */ = { 288 | isa = XCBuildConfiguration; 289 | buildSettings = { 290 | ALWAYS_SEARCH_USER_PATHS = NO; 291 | CLANG_ANALYZER_NONNULL = YES; 292 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 294 | CLANG_CXX_LIBRARY = "libc++"; 295 | CLANG_ENABLE_MODULES = YES; 296 | CLANG_ENABLE_OBJC_ARC = YES; 297 | CLANG_ENABLE_OBJC_WEAK = YES; 298 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 299 | CLANG_WARN_BOOL_CONVERSION = YES; 300 | CLANG_WARN_COMMA = YES; 301 | CLANG_WARN_CONSTANT_CONVERSION = YES; 302 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 304 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 305 | CLANG_WARN_EMPTY_BODY = YES; 306 | CLANG_WARN_ENUM_CONVERSION = YES; 307 | CLANG_WARN_INFINITE_RECURSION = YES; 308 | CLANG_WARN_INT_CONVERSION = YES; 309 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 310 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 311 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 312 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 313 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 314 | CLANG_WARN_STRICT_PROTOTYPES = YES; 315 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 316 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 317 | CLANG_WARN_UNREACHABLE_CODE = YES; 318 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 319 | CODE_SIGN_IDENTITY = "iPhone Developer"; 320 | COPY_PHASE_STRIP = NO; 321 | CURRENT_PROJECT_VERSION = 1; 322 | DEBUG_INFORMATION_FORMAT = dwarf; 323 | ENABLE_STRICT_OBJC_MSGSEND = YES; 324 | ENABLE_TESTABILITY = YES; 325 | GCC_C_LANGUAGE_STANDARD = gnu11; 326 | GCC_DYNAMIC_NO_PIC = NO; 327 | GCC_NO_COMMON_BLOCKS = YES; 328 | GCC_OPTIMIZATION_LEVEL = 0; 329 | GCC_PREPROCESSOR_DEFINITIONS = ( 330 | "DEBUG=1", 331 | "$(inherited)", 332 | ); 333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 335 | GCC_WARN_UNDECLARED_SELECTOR = YES; 336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 337 | GCC_WARN_UNUSED_FUNCTION = YES; 338 | GCC_WARN_UNUSED_VARIABLE = YES; 339 | IPHONEOS_DEPLOYMENT_TARGET = 11.3; 340 | MTL_ENABLE_DEBUG_INFO = YES; 341 | ONLY_ACTIVE_ARCH = YES; 342 | SDKROOT = iphoneos; 343 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 344 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 345 | VERSIONING_SYSTEM = "apple-generic"; 346 | VERSION_INFO_PREFIX = ""; 347 | }; 348 | name = Debug; 349 | }; 350 | 0693FAE42139926200939364 /* Release */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ALWAYS_SEARCH_USER_PATHS = NO; 354 | CLANG_ANALYZER_NONNULL = YES; 355 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 357 | CLANG_CXX_LIBRARY = "libc++"; 358 | CLANG_ENABLE_MODULES = YES; 359 | CLANG_ENABLE_OBJC_ARC = YES; 360 | CLANG_ENABLE_OBJC_WEAK = YES; 361 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 362 | CLANG_WARN_BOOL_CONVERSION = YES; 363 | CLANG_WARN_COMMA = YES; 364 | CLANG_WARN_CONSTANT_CONVERSION = YES; 365 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 366 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 367 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 368 | CLANG_WARN_EMPTY_BODY = YES; 369 | CLANG_WARN_ENUM_CONVERSION = YES; 370 | CLANG_WARN_INFINITE_RECURSION = YES; 371 | CLANG_WARN_INT_CONVERSION = YES; 372 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 373 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 374 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 375 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 376 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 377 | CLANG_WARN_STRICT_PROTOTYPES = YES; 378 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 379 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 380 | CLANG_WARN_UNREACHABLE_CODE = YES; 381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 382 | CODE_SIGN_IDENTITY = "iPhone Developer"; 383 | COPY_PHASE_STRIP = NO; 384 | CURRENT_PROJECT_VERSION = 1; 385 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 386 | ENABLE_NS_ASSERTIONS = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu11; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 11.3; 397 | MTL_ENABLE_DEBUG_INFO = NO; 398 | SDKROOT = iphoneos; 399 | SWIFT_COMPILATION_MODE = wholemodule; 400 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 401 | VALIDATE_PRODUCT = YES; 402 | VERSIONING_SYSTEM = "apple-generic"; 403 | VERSION_INFO_PREFIX = ""; 404 | }; 405 | name = Release; 406 | }; 407 | 0693FAE62139926200939364 /* Debug */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | CLANG_ENABLE_MODULES = YES; 411 | CODE_SIGN_IDENTITY = ""; 412 | CODE_SIGN_STYLE = Automatic; 413 | DEFINES_MODULE = YES; 414 | DYLIB_COMPATIBILITY_VERSION = 1; 415 | DYLIB_CURRENT_VERSION = 1; 416 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 417 | INFOPLIST_FILE = Koosa/Info.plist; 418 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 419 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 420 | LD_RUNPATH_SEARCH_PATHS = ( 421 | "$(inherited)", 422 | "@executable_path/Frameworks", 423 | "@loader_path/Frameworks", 424 | ); 425 | PRODUCT_BUNDLE_IDENTIFIER = com.Koosa; 426 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 427 | SKIP_INSTALL = YES; 428 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 429 | SWIFT_VERSION = 4.0; 430 | TARGETED_DEVICE_FAMILY = "1,2"; 431 | }; 432 | name = Debug; 433 | }; 434 | 0693FAE72139926200939364 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | CLANG_ENABLE_MODULES = YES; 438 | CODE_SIGN_IDENTITY = ""; 439 | CODE_SIGN_STYLE = Automatic; 440 | DEFINES_MODULE = YES; 441 | DYLIB_COMPATIBILITY_VERSION = 1; 442 | DYLIB_CURRENT_VERSION = 1; 443 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 444 | INFOPLIST_FILE = Koosa/Info.plist; 445 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 446 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 447 | LD_RUNPATH_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "@executable_path/Frameworks", 450 | "@loader_path/Frameworks", 451 | ); 452 | PRODUCT_BUNDLE_IDENTIFIER = com.Koosa; 453 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 454 | SKIP_INSTALL = YES; 455 | SWIFT_VERSION = 4.0; 456 | TARGETED_DEVICE_FAMILY = "1,2"; 457 | }; 458 | name = Release; 459 | }; 460 | 0693FAE92139926200939364 /* Debug */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 464 | CODE_SIGN_STYLE = Automatic; 465 | INFOPLIST_FILE = KoosaTests/Info.plist; 466 | LD_RUNPATH_SEARCH_PATHS = ( 467 | "$(inherited)", 468 | "@executable_path/Frameworks", 469 | "@loader_path/Frameworks", 470 | ); 471 | PRODUCT_BUNDLE_IDENTIFIER = com.KoosaTests; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | SWIFT_VERSION = 4.0; 474 | TARGETED_DEVICE_FAMILY = "1,2"; 475 | }; 476 | name = Debug; 477 | }; 478 | 0693FAEA2139926200939364 /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 482 | CODE_SIGN_STYLE = Automatic; 483 | INFOPLIST_FILE = KoosaTests/Info.plist; 484 | LD_RUNPATH_SEARCH_PATHS = ( 485 | "$(inherited)", 486 | "@executable_path/Frameworks", 487 | "@loader_path/Frameworks", 488 | ); 489 | PRODUCT_BUNDLE_IDENTIFIER = com.KoosaTests; 490 | PRODUCT_NAME = "$(TARGET_NAME)"; 491 | SWIFT_VERSION = 4.0; 492 | TARGETED_DEVICE_FAMILY = "1,2"; 493 | }; 494 | name = Release; 495 | }; 496 | /* End XCBuildConfiguration section */ 497 | 498 | /* Begin XCConfigurationList section */ 499 | 0693FACB2139926100939364 /* Build configuration list for PBXProject "Koosa" */ = { 500 | isa = XCConfigurationList; 501 | buildConfigurations = ( 502 | 0693FAE32139926200939364 /* Debug */, 503 | 0693FAE42139926200939364 /* Release */, 504 | ); 505 | defaultConfigurationIsVisible = 0; 506 | defaultConfigurationName = Release; 507 | }; 508 | 0693FAE52139926200939364 /* Build configuration list for PBXNativeTarget "Koosa" */ = { 509 | isa = XCConfigurationList; 510 | buildConfigurations = ( 511 | 0693FAE62139926200939364 /* Debug */, 512 | 0693FAE72139926200939364 /* Release */, 513 | ); 514 | defaultConfigurationIsVisible = 0; 515 | defaultConfigurationName = Release; 516 | }; 517 | 0693FAE82139926200939364 /* Build configuration list for PBXNativeTarget "KoosaTests" */ = { 518 | isa = XCConfigurationList; 519 | buildConfigurations = ( 520 | 0693FAE92139926200939364 /* Debug */, 521 | 0693FAEA2139926200939364 /* Release */, 522 | ); 523 | defaultConfigurationIsVisible = 0; 524 | defaultConfigurationName = Release; 525 | }; 526 | /* End XCConfigurationList section */ 527 | }; 528 | rootObject = 0693FAC82139926100939364 /* Project object */; 529 | } 530 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0693FB67213C64CA00939364 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FB66213C64CA00939364 /* AppDelegate.swift */; }; 11 | 0693FB69213C64CA00939364 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FB68213C64CA00939364 /* ViewController.swift */; }; 12 | 0693FB6C213C64CA00939364 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0693FB6A213C64CA00939364 /* Main.storyboard */; }; 13 | 0693FB6E213C64CB00939364 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0693FB6D213C64CB00939364 /* Assets.xcassets */; }; 14 | 0693FB71213C64CB00939364 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0693FB6F213C64CB00939364 /* LaunchScreen.storyboard */; }; 15 | 0693FB7C213C64CB00939364 /* ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FB7B213C64CB00939364 /* ExampleTests.swift */; }; 16 | 0693FB87213C64CB00939364 /* ExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FB86213C64CB00939364 /* ExampleUITests.swift */; }; 17 | 0693FBA1213C667000939364 /* KoosaConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FBA0213C667000939364 /* KoosaConfig.swift */; }; 18 | 0693FBA3213C7ECB00939364 /* GroupsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FBA2213C7ECB00939364 /* GroupsViewController.swift */; }; 19 | 0693FBA5213C888500939364 /* GroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0693FBA4213C888500939364 /* GroupTableViewCell.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 0693FB78213C64CB00939364 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 0693FB5B213C64CA00939364 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 0693FB62213C64CA00939364; 28 | remoteInfo = Example; 29 | }; 30 | 0693FB83213C64CB00939364 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 0693FB5B213C64CA00939364 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 0693FB62213C64CA00939364; 35 | remoteInfo = Example; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 0693FB63213C64CA00939364 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 0693FB66213C64CA00939364 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 42 | 0693FB68213C64CA00939364 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 43 | 0693FB6B213C64CA00939364 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 44 | 0693FB6D213C64CB00939364 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 45 | 0693FB70213C64CB00939364 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 46 | 0693FB72213C64CB00939364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | 0693FB77213C64CB00939364 /* ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 0693FB7B213C64CB00939364 /* ExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleTests.swift; sourceTree = ""; }; 49 | 0693FB7D213C64CB00939364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 0693FB82213C64CB00939364 /* ExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 0693FB86213C64CB00939364 /* ExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleUITests.swift; sourceTree = ""; }; 52 | 0693FB88213C64CB00939364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | 0693FBA0213C667000939364 /* KoosaConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KoosaConfig.swift; sourceTree = ""; }; 54 | 0693FBA2213C7ECB00939364 /* GroupsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupsViewController.swift; sourceTree = ""; }; 55 | 0693FBA4213C888500939364 /* GroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupTableViewCell.swift; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 0693FB60213C64CA00939364 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | 0693FB74213C64CB00939364 /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | 0693FB7F213C64CB00939364 /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | /* End PBXFrameworksBuildPhase section */ 81 | 82 | /* Begin PBXGroup section */ 83 | 0693FB5A213C64CA00939364 = { 84 | isa = PBXGroup; 85 | children = ( 86 | 0693FB65213C64CA00939364 /* Example */, 87 | 0693FB7A213C64CB00939364 /* ExampleTests */, 88 | 0693FB85213C64CB00939364 /* ExampleUITests */, 89 | 0693FB64213C64CA00939364 /* Products */, 90 | ); 91 | sourceTree = ""; 92 | }; 93 | 0693FB64213C64CA00939364 /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 0693FB63213C64CA00939364 /* Example.app */, 97 | 0693FB77213C64CB00939364 /* ExampleTests.xctest */, 98 | 0693FB82213C64CB00939364 /* ExampleUITests.xctest */, 99 | ); 100 | name = Products; 101 | sourceTree = ""; 102 | }; 103 | 0693FB65213C64CA00939364 /* Example */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 0693FB66213C64CA00939364 /* AppDelegate.swift */, 107 | 0693FB68213C64CA00939364 /* ViewController.swift */, 108 | 0693FB6A213C64CA00939364 /* Main.storyboard */, 109 | 0693FB6D213C64CB00939364 /* Assets.xcassets */, 110 | 0693FB6F213C64CB00939364 /* LaunchScreen.storyboard */, 111 | 0693FB72213C64CB00939364 /* Info.plist */, 112 | 0693FBA0213C667000939364 /* KoosaConfig.swift */, 113 | 0693FBA2213C7ECB00939364 /* GroupsViewController.swift */, 114 | 0693FBA4213C888500939364 /* GroupTableViewCell.swift */, 115 | ); 116 | path = Example; 117 | sourceTree = ""; 118 | }; 119 | 0693FB7A213C64CB00939364 /* ExampleTests */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 0693FB7B213C64CB00939364 /* ExampleTests.swift */, 123 | 0693FB7D213C64CB00939364 /* Info.plist */, 124 | ); 125 | path = ExampleTests; 126 | sourceTree = ""; 127 | }; 128 | 0693FB85213C64CB00939364 /* ExampleUITests */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 0693FB86213C64CB00939364 /* ExampleUITests.swift */, 132 | 0693FB88213C64CB00939364 /* Info.plist */, 133 | ); 134 | path = ExampleUITests; 135 | sourceTree = ""; 136 | }; 137 | /* End PBXGroup section */ 138 | 139 | /* Begin PBXNativeTarget section */ 140 | 0693FB62213C64CA00939364 /* Example */ = { 141 | isa = PBXNativeTarget; 142 | buildConfigurationList = 0693FB8B213C64CB00939364 /* Build configuration list for PBXNativeTarget "Example" */; 143 | buildPhases = ( 144 | 0693FB5F213C64CA00939364 /* Sources */, 145 | 0693FB60213C64CA00939364 /* Frameworks */, 146 | 0693FB61213C64CA00939364 /* Resources */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = Example; 153 | productName = Example; 154 | productReference = 0693FB63213C64CA00939364 /* Example.app */; 155 | productType = "com.apple.product-type.application"; 156 | }; 157 | 0693FB76213C64CB00939364 /* ExampleTests */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 0693FB8E213C64CB00939364 /* Build configuration list for PBXNativeTarget "ExampleTests" */; 160 | buildPhases = ( 161 | 0693FB73213C64CB00939364 /* Sources */, 162 | 0693FB74213C64CB00939364 /* Frameworks */, 163 | 0693FB75213C64CB00939364 /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | 0693FB79213C64CB00939364 /* PBXTargetDependency */, 169 | ); 170 | name = ExampleTests; 171 | productName = ExampleTests; 172 | productReference = 0693FB77213C64CB00939364 /* ExampleTests.xctest */; 173 | productType = "com.apple.product-type.bundle.unit-test"; 174 | }; 175 | 0693FB81213C64CB00939364 /* ExampleUITests */ = { 176 | isa = PBXNativeTarget; 177 | buildConfigurationList = 0693FB91213C64CB00939364 /* Build configuration list for PBXNativeTarget "ExampleUITests" */; 178 | buildPhases = ( 179 | 0693FB7E213C64CB00939364 /* Sources */, 180 | 0693FB7F213C64CB00939364 /* Frameworks */, 181 | 0693FB80213C64CB00939364 /* Resources */, 182 | ); 183 | buildRules = ( 184 | ); 185 | dependencies = ( 186 | 0693FB84213C64CB00939364 /* PBXTargetDependency */, 187 | ); 188 | name = ExampleUITests; 189 | productName = ExampleUITests; 190 | productReference = 0693FB82213C64CB00939364 /* ExampleUITests.xctest */; 191 | productType = "com.apple.product-type.bundle.ui-testing"; 192 | }; 193 | /* End PBXNativeTarget section */ 194 | 195 | /* Begin PBXProject section */ 196 | 0693FB5B213C64CA00939364 /* Project object */ = { 197 | isa = PBXProject; 198 | attributes = { 199 | LastSwiftUpdateCheck = 0930; 200 | LastUpgradeCheck = 0930; 201 | ORGANIZATIONNAME = "Mostafa Abdellateef"; 202 | TargetAttributes = { 203 | 0693FB62213C64CA00939364 = { 204 | CreatedOnToolsVersion = 9.3; 205 | }; 206 | 0693FB76213C64CB00939364 = { 207 | CreatedOnToolsVersion = 9.3; 208 | TestTargetID = 0693FB62213C64CA00939364; 209 | }; 210 | 0693FB81213C64CB00939364 = { 211 | CreatedOnToolsVersion = 9.3; 212 | TestTargetID = 0693FB62213C64CA00939364; 213 | }; 214 | }; 215 | }; 216 | buildConfigurationList = 0693FB5E213C64CA00939364 /* Build configuration list for PBXProject "Example" */; 217 | compatibilityVersion = "Xcode 9.3"; 218 | developmentRegion = en; 219 | hasScannedForEncodings = 0; 220 | knownRegions = ( 221 | en, 222 | Base, 223 | ); 224 | mainGroup = 0693FB5A213C64CA00939364; 225 | productRefGroup = 0693FB64213C64CA00939364 /* Products */; 226 | projectDirPath = ""; 227 | projectRoot = ""; 228 | targets = ( 229 | 0693FB62213C64CA00939364 /* Example */, 230 | 0693FB76213C64CB00939364 /* ExampleTests */, 231 | 0693FB81213C64CB00939364 /* ExampleUITests */, 232 | ); 233 | }; 234 | /* End PBXProject section */ 235 | 236 | /* Begin PBXResourcesBuildPhase section */ 237 | 0693FB61213C64CA00939364 /* Resources */ = { 238 | isa = PBXResourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | 0693FB71213C64CB00939364 /* LaunchScreen.storyboard in Resources */, 242 | 0693FB6E213C64CB00939364 /* Assets.xcassets in Resources */, 243 | 0693FB6C213C64CA00939364 /* Main.storyboard in Resources */, 244 | ); 245 | runOnlyForDeploymentPostprocessing = 0; 246 | }; 247 | 0693FB75213C64CB00939364 /* Resources */ = { 248 | isa = PBXResourcesBuildPhase; 249 | buildActionMask = 2147483647; 250 | files = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | 0693FB80213C64CB00939364 /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | /* End PBXResourcesBuildPhase section */ 262 | 263 | /* Begin PBXSourcesBuildPhase section */ 264 | 0693FB5F213C64CA00939364 /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 0693FBA3213C7ECB00939364 /* GroupsViewController.swift in Sources */, 269 | 0693FBA1213C667000939364 /* KoosaConfig.swift in Sources */, 270 | 0693FB69213C64CA00939364 /* ViewController.swift in Sources */, 271 | 0693FB67213C64CA00939364 /* AppDelegate.swift in Sources */, 272 | 0693FBA5213C888500939364 /* GroupTableViewCell.swift in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | 0693FB73213C64CB00939364 /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 0693FB7C213C64CB00939364 /* ExampleTests.swift in Sources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | 0693FB7E213C64CB00939364 /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | 0693FB87213C64CB00939364 /* ExampleUITests.swift in Sources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXSourcesBuildPhase section */ 293 | 294 | /* Begin PBXTargetDependency section */ 295 | 0693FB79213C64CB00939364 /* PBXTargetDependency */ = { 296 | isa = PBXTargetDependency; 297 | target = 0693FB62213C64CA00939364 /* Example */; 298 | targetProxy = 0693FB78213C64CB00939364 /* PBXContainerItemProxy */; 299 | }; 300 | 0693FB84213C64CB00939364 /* PBXTargetDependency */ = { 301 | isa = PBXTargetDependency; 302 | target = 0693FB62213C64CA00939364 /* Example */; 303 | targetProxy = 0693FB83213C64CB00939364 /* PBXContainerItemProxy */; 304 | }; 305 | /* End PBXTargetDependency section */ 306 | 307 | /* Begin PBXVariantGroup section */ 308 | 0693FB6A213C64CA00939364 /* Main.storyboard */ = { 309 | isa = PBXVariantGroup; 310 | children = ( 311 | 0693FB6B213C64CA00939364 /* Base */, 312 | ); 313 | name = Main.storyboard; 314 | sourceTree = ""; 315 | }; 316 | 0693FB6F213C64CB00939364 /* LaunchScreen.storyboard */ = { 317 | isa = PBXVariantGroup; 318 | children = ( 319 | 0693FB70213C64CB00939364 /* Base */, 320 | ); 321 | name = LaunchScreen.storyboard; 322 | sourceTree = ""; 323 | }; 324 | /* End PBXVariantGroup section */ 325 | 326 | /* Begin XCBuildConfiguration section */ 327 | 0693FB89213C64CB00939364 /* Debug */ = { 328 | isa = XCBuildConfiguration; 329 | buildSettings = { 330 | ALWAYS_SEARCH_USER_PATHS = NO; 331 | CLANG_ANALYZER_NONNULL = YES; 332 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 334 | CLANG_CXX_LIBRARY = "libc++"; 335 | CLANG_ENABLE_MODULES = YES; 336 | CLANG_ENABLE_OBJC_ARC = YES; 337 | CLANG_ENABLE_OBJC_WEAK = YES; 338 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 339 | CLANG_WARN_BOOL_CONVERSION = YES; 340 | CLANG_WARN_COMMA = YES; 341 | CLANG_WARN_CONSTANT_CONVERSION = YES; 342 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 343 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 344 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 345 | CLANG_WARN_EMPTY_BODY = YES; 346 | CLANG_WARN_ENUM_CONVERSION = YES; 347 | CLANG_WARN_INFINITE_RECURSION = YES; 348 | CLANG_WARN_INT_CONVERSION = YES; 349 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 350 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 351 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 352 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 353 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 354 | CLANG_WARN_STRICT_PROTOTYPES = YES; 355 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 356 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 357 | CLANG_WARN_UNREACHABLE_CODE = YES; 358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 359 | CODE_SIGN_IDENTITY = "iPhone Developer"; 360 | COPY_PHASE_STRIP = NO; 361 | DEBUG_INFORMATION_FORMAT = dwarf; 362 | ENABLE_STRICT_OBJC_MSGSEND = YES; 363 | ENABLE_TESTABILITY = YES; 364 | GCC_C_LANGUAGE_STANDARD = gnu11; 365 | GCC_DYNAMIC_NO_PIC = NO; 366 | GCC_NO_COMMON_BLOCKS = YES; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PREPROCESSOR_DEFINITIONS = ( 369 | "DEBUG=1", 370 | "$(inherited)", 371 | ); 372 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 373 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 374 | GCC_WARN_UNDECLARED_SELECTOR = YES; 375 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 376 | GCC_WARN_UNUSED_FUNCTION = YES; 377 | GCC_WARN_UNUSED_VARIABLE = YES; 378 | IPHONEOS_DEPLOYMENT_TARGET = 11.3; 379 | MTL_ENABLE_DEBUG_INFO = YES; 380 | ONLY_ACTIVE_ARCH = YES; 381 | SDKROOT = iphoneos; 382 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 383 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 384 | }; 385 | name = Debug; 386 | }; 387 | 0693FB8A213C64CB00939364 /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_ENABLE_OBJC_WEAK = YES; 398 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 399 | CLANG_WARN_BOOL_CONVERSION = YES; 400 | CLANG_WARN_COMMA = YES; 401 | CLANG_WARN_CONSTANT_CONVERSION = YES; 402 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 403 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 404 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 405 | CLANG_WARN_EMPTY_BODY = YES; 406 | CLANG_WARN_ENUM_CONVERSION = YES; 407 | CLANG_WARN_INFINITE_RECURSION = YES; 408 | CLANG_WARN_INT_CONVERSION = YES; 409 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 411 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 412 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 413 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 414 | CLANG_WARN_STRICT_PROTOTYPES = YES; 415 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 416 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 417 | CLANG_WARN_UNREACHABLE_CODE = YES; 418 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 419 | CODE_SIGN_IDENTITY = "iPhone Developer"; 420 | COPY_PHASE_STRIP = NO; 421 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 422 | ENABLE_NS_ASSERTIONS = NO; 423 | ENABLE_STRICT_OBJC_MSGSEND = YES; 424 | GCC_C_LANGUAGE_STANDARD = gnu11; 425 | GCC_NO_COMMON_BLOCKS = YES; 426 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 427 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 428 | GCC_WARN_UNDECLARED_SELECTOR = YES; 429 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 430 | GCC_WARN_UNUSED_FUNCTION = YES; 431 | GCC_WARN_UNUSED_VARIABLE = YES; 432 | IPHONEOS_DEPLOYMENT_TARGET = 11.3; 433 | MTL_ENABLE_DEBUG_INFO = NO; 434 | SDKROOT = iphoneos; 435 | SWIFT_COMPILATION_MODE = wholemodule; 436 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 437 | VALIDATE_PRODUCT = YES; 438 | }; 439 | name = Release; 440 | }; 441 | 0693FB8C213C64CB00939364 /* Debug */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 445 | CODE_SIGN_STYLE = Automatic; 446 | INFOPLIST_FILE = Example/Info.plist; 447 | LD_RUNPATH_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "@executable_path/Frameworks", 450 | ); 451 | PRODUCT_BUNDLE_IDENTIFIER = com.koosa.Example; 452 | PRODUCT_NAME = "$(TARGET_NAME)"; 453 | SWIFT_VERSION = 4.0; 454 | TARGETED_DEVICE_FAMILY = "1,2"; 455 | }; 456 | name = Debug; 457 | }; 458 | 0693FB8D213C64CB00939364 /* Release */ = { 459 | isa = XCBuildConfiguration; 460 | buildSettings = { 461 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 462 | CODE_SIGN_STYLE = Automatic; 463 | INFOPLIST_FILE = Example/Info.plist; 464 | LD_RUNPATH_SEARCH_PATHS = ( 465 | "$(inherited)", 466 | "@executable_path/Frameworks", 467 | ); 468 | PRODUCT_BUNDLE_IDENTIFIER = com.koosa.Example; 469 | PRODUCT_NAME = "$(TARGET_NAME)"; 470 | SWIFT_VERSION = 4.0; 471 | TARGETED_DEVICE_FAMILY = "1,2"; 472 | }; 473 | name = Release; 474 | }; 475 | 0693FB8F213C64CB00939364 /* Debug */ = { 476 | isa = XCBuildConfiguration; 477 | buildSettings = { 478 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 479 | BUNDLE_LOADER = "$(TEST_HOST)"; 480 | CODE_SIGN_STYLE = Automatic; 481 | INFOPLIST_FILE = ExampleTests/Info.plist; 482 | LD_RUNPATH_SEARCH_PATHS = ( 483 | "$(inherited)", 484 | "@executable_path/Frameworks", 485 | "@loader_path/Frameworks", 486 | ); 487 | PRODUCT_BUNDLE_IDENTIFIER = com.koosa.ExampleTests; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | SWIFT_VERSION = 4.0; 490 | TARGETED_DEVICE_FAMILY = "1,2"; 491 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; 492 | }; 493 | name = Debug; 494 | }; 495 | 0693FB90213C64CB00939364 /* Release */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 499 | BUNDLE_LOADER = "$(TEST_HOST)"; 500 | CODE_SIGN_STYLE = Automatic; 501 | INFOPLIST_FILE = ExampleTests/Info.plist; 502 | LD_RUNPATH_SEARCH_PATHS = ( 503 | "$(inherited)", 504 | "@executable_path/Frameworks", 505 | "@loader_path/Frameworks", 506 | ); 507 | PRODUCT_BUNDLE_IDENTIFIER = com.koosa.ExampleTests; 508 | PRODUCT_NAME = "$(TARGET_NAME)"; 509 | SWIFT_VERSION = 4.0; 510 | TARGETED_DEVICE_FAMILY = "1,2"; 511 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; 512 | }; 513 | name = Release; 514 | }; 515 | 0693FB92213C64CB00939364 /* Debug */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 519 | CODE_SIGN_STYLE = Automatic; 520 | INFOPLIST_FILE = ExampleUITests/Info.plist; 521 | LD_RUNPATH_SEARCH_PATHS = ( 522 | "$(inherited)", 523 | "@executable_path/Frameworks", 524 | "@loader_path/Frameworks", 525 | ); 526 | PRODUCT_BUNDLE_IDENTIFIER = com.koosa.ExampleUITests; 527 | PRODUCT_NAME = "$(TARGET_NAME)"; 528 | SWIFT_VERSION = 4.0; 529 | TARGETED_DEVICE_FAMILY = "1,2"; 530 | TEST_TARGET_NAME = Example; 531 | }; 532 | name = Debug; 533 | }; 534 | 0693FB93213C64CB00939364 /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 538 | CODE_SIGN_STYLE = Automatic; 539 | INFOPLIST_FILE = ExampleUITests/Info.plist; 540 | LD_RUNPATH_SEARCH_PATHS = ( 541 | "$(inherited)", 542 | "@executable_path/Frameworks", 543 | "@loader_path/Frameworks", 544 | ); 545 | PRODUCT_BUNDLE_IDENTIFIER = com.koosa.ExampleUITests; 546 | PRODUCT_NAME = "$(TARGET_NAME)"; 547 | SWIFT_VERSION = 4.0; 548 | TARGETED_DEVICE_FAMILY = "1,2"; 549 | TEST_TARGET_NAME = Example; 550 | }; 551 | name = Release; 552 | }; 553 | /* End XCBuildConfiguration section */ 554 | 555 | /* Begin XCConfigurationList section */ 556 | 0693FB5E213C64CA00939364 /* Build configuration list for PBXProject "Example" */ = { 557 | isa = XCConfigurationList; 558 | buildConfigurations = ( 559 | 0693FB89213C64CB00939364 /* Debug */, 560 | 0693FB8A213C64CB00939364 /* Release */, 561 | ); 562 | defaultConfigurationIsVisible = 0; 563 | defaultConfigurationName = Release; 564 | }; 565 | 0693FB8B213C64CB00939364 /* Build configuration list for PBXNativeTarget "Example" */ = { 566 | isa = XCConfigurationList; 567 | buildConfigurations = ( 568 | 0693FB8C213C64CB00939364 /* Debug */, 569 | 0693FB8D213C64CB00939364 /* Release */, 570 | ); 571 | defaultConfigurationIsVisible = 0; 572 | defaultConfigurationName = Release; 573 | }; 574 | 0693FB8E213C64CB00939364 /* Build configuration list for PBXNativeTarget "ExampleTests" */ = { 575 | isa = XCConfigurationList; 576 | buildConfigurations = ( 577 | 0693FB8F213C64CB00939364 /* Debug */, 578 | 0693FB90213C64CB00939364 /* Release */, 579 | ); 580 | defaultConfigurationIsVisible = 0; 581 | defaultConfigurationName = Release; 582 | }; 583 | 0693FB91213C64CB00939364 /* Build configuration list for PBXNativeTarget "ExampleUITests" */ = { 584 | isa = XCConfigurationList; 585 | buildConfigurations = ( 586 | 0693FB92213C64CB00939364 /* Debug */, 587 | 0693FB93213C64CB00939364 /* Release */, 588 | ); 589 | defaultConfigurationIsVisible = 0; 590 | defaultConfigurationName = Release; 591 | }; 592 | /* End XCConfigurationList section */ 593 | }; 594 | rootObject = 0693FB5B213C64CA00939364 /* Project object */; 595 | } 596 | --------------------------------------------------------------------------------