├── Source ├── Classes │ ├── .gitkeep │ ├── EmptyDecodable.swift │ ├── UIView+Subviews.swift │ ├── CountryPickerViewController+DisplayState.swift │ ├── Configurable.swift │ ├── ColumbusMain.swift │ ├── CountryList.swift │ ├── Country.swift │ ├── CountryCell.swift │ ├── CountryView.swift │ └── CountryPickerViewController.swift ├── Resources │ ├── .gitkeep │ ├── Info.plist │ └── Countries.json ├── Columbus.h └── Info.plist ├── github ├── CONTRIBUTING.md ├── assets │ ├── history.png │ ├── indexbar.png │ ├── searchbar.png │ ├── theming.png │ └── localization.png ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── AUTHORS ├── icon.png ├── .spi.yml ├── Example ├── Source │ ├── tvOS │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ └── App Icon & Top Shelf Image.brandassets │ │ │ │ ├── App Icon.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Middle.imagestacklayer │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ │ ├── App Icon - App Store.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Middle.imagestacklayer │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ │ ├── Top Shelf Image.imageset │ │ │ │ └── Contents.json │ │ │ │ ├── Top Shelf Image Wide.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ └── Info.plist │ ├── UIColor+SemanticColors.swift │ ├── iOS │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ └── Info.plist │ ├── CountryPickerStoryboard.storyboard │ ├── LaunchScreen.storyboard │ └── AppDelegate.swift └── ColumbusExample.xcodeproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ └── xcschemes │ │ ├── Columbus_iOS_Example.xcscheme │ │ └── Columbus_tvOS_Example.xcscheme │ └── project.pbxproj ├── Columbus.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ ├── Columbus-iOS.xcscheme │ │ └── Columbus-tvOS.xcscheme └── project.pbxproj ├── Tests ├── ColumbusTests.swift └── Info.plist ├── Columbus.xcworkspace ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── Gemfile ├── .github ├── workflows │ ├── auto-assign-to-project.yml │ ├── test.yml │ └── ci.yml └── dependabot.yml ├── Columbus.podspec ├── LICENSE ├── .gitignore ├── CHANGELOG.md ├── README.md └── Gemfile.lock /Source/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Source/Resources/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Stefan Herold -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blackjacx/Columbus/HEAD/icon.png -------------------------------------------------------------------------------- /.spi.yml: -------------------------------------------------------------------------------- 1 | version: 1.7.6 2 | builder: 3 | configs: 4 | - documentation_targets: [Columbus] -------------------------------------------------------------------------------- /github/assets/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blackjacx/Columbus/HEAD/github/assets/history.png -------------------------------------------------------------------------------- /github/assets/indexbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blackjacx/Columbus/HEAD/github/assets/indexbar.png -------------------------------------------------------------------------------- /github/assets/searchbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blackjacx/Columbus/HEAD/github/assets/searchbar.png -------------------------------------------------------------------------------- /github/assets/theming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blackjacx/Columbus/HEAD/github/assets/theming.png -------------------------------------------------------------------------------- /github/assets/localization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blackjacx/Columbus/HEAD/github/assets/localization.png -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Columbus.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Changed 2 | - Resolve #123 - issue title 3 | 4 | ## Fixed 5 | - Resolve #123 - issue title 6 | 7 | ## Deleted 8 | - Resolve #123 - issue title 9 | 10 | ## How To Test 11 | - [ ] 12 | - [ ] 13 | - [ ] 14 | -------------------------------------------------------------------------------- /Example/ColumbusExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/ColumbusTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColumbusTests.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 24.12.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | final class ColumbusTests: XCTestCase {} 12 | -------------------------------------------------------------------------------- /Source/Classes/EmptyDecodable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmptyDecodable.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 20.02.21. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EmptyDecodable: Codable { } 12 | -------------------------------------------------------------------------------- /github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Expected behaviour 2 | 3 | 4 | 5 | ## Actual behaviour 6 | 7 | 8 | 9 | ## Steps to reproduce 10 | 11 | 1. 12 | 2. 13 | 3. 14 | 15 | ## Specifications 16 | 17 | - App version: 18 | - Platform: iOS 19 | - Device: iPhone 20 | - Environment: Production 21 | -------------------------------------------------------------------------------- /Columbus.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "version" : 1, 9 | "author" : "xcode" 10 | } 11 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "version" : 1, 9 | "author" : "xcode" 10 | } 11 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "version" : 1, 9 | "author" : "xcode" 10 | } 11 | } -------------------------------------------------------------------------------- /Columbus.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Columbus.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/ColumbusExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'xcov' 10 | gem 'danger' 11 | gem 'danger-changelog' 12 | gem 'danger-commit_lint' 13 | gem 'danger-swiftlint' 14 | gem 'danger-xcov' 15 | 16 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 17 | eval_gemfile(plugins_path) if File.exist?(plugins_path) -------------------------------------------------------------------------------- /Source/Classes/UIView+Subviews.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Subviews.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 13.08.19. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | 13 | func recursiveSubviews() -> [UIView] { 14 | 15 | if subviews.isEmpty { 16 | return subviews 17 | } 18 | return subviews + subviews.flatMap { $0.recursiveSubviews() } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "tv-marketing", 13 | "scale" : "1x" 14 | }, 15 | { 16 | "idiom" : "tv-marketing", 17 | "scale" : "2x" 18 | } 19 | ], 20 | "info" : { 21 | "version" : 1, 22 | "author" : "xcode" 23 | } 24 | } -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "tv-marketing", 13 | "scale" : "1x" 14 | }, 15 | { 16 | "idiom" : "tv-marketing", 17 | "scale" : "2x" 18 | } 19 | ], 20 | "info" : { 21 | "version" : 1, 22 | "author" : "xcode" 23 | } 24 | } -------------------------------------------------------------------------------- /.github/workflows/auto-assign-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Auto Assign to Project 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | pull_request: 7 | types: [opened] 8 | 9 | jobs: 10 | add-to-project: 11 | runs-on: ubuntu-latest 12 | name: Assign to "Backlog" Project 13 | steps: 14 | - name: Assign NEW issues and NEW pull requests to global project "Backlog" (1) 15 | uses: actions/add-to-project@main 16 | with: 17 | project-url: https://github.com/users/Blackjacx/projects/1 18 | github-token: ${{ secrets.ACCESS_TOKEN }} -------------------------------------------------------------------------------- /Source/Columbus.h: -------------------------------------------------------------------------------- 1 | // 2 | // Columbus.h 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 21.12.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Columbus. 12 | FOUNDATION_EXPORT double ColumbusVersionNumber; 13 | 14 | //! Project version string for Columbus. 15 | FOUNDATION_EXPORT const unsigned char ColumbusVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Source/Classes/CountryPickerViewController+DisplayState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CountryPickerViewController+DisplayState.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 05.02.21. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension CountryPickerViewController { 12 | 13 | /// This enum controls how the picker will look like. Features like the searchbar will always be visible. 14 | enum DisplayState { 15 | /// Simple, showing only the countries 16 | case simple 17 | /// Showing the iso country code too. Suitable when selecting the county code for a phone number. 18 | case countryCodeSelection 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: [ develop ] 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | os: ["macos-12"] 13 | swift: ["5.6.1"] 14 | runs-on: ${{ matrix.os }} 15 | 16 | steps: 17 | - uses: swift-actions/setup-swift@v2 18 | with: 19 | swift-version: ${{ matrix.swift }} 20 | - uses: actions/checkout@v5 21 | - name: Log Swift Version 22 | run: swift --version 23 | - name: Log Xcode Versions 24 | run: ls -la /Applications/ 25 | - name: Build for macOS 26 | run: swift build -v 27 | - name: Run Tests for macOS 28 | run: swift test -v -------------------------------------------------------------------------------- /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.10.0 19 | CFBundleVersion 20 | 37 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/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.10.0 19 | CFBundleVersion 20 | 37 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/Classes/Configurable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Configurable.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 21.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol Configurable { 12 | var displayState: CountryPickerViewController.DisplayState { get } 13 | var textAttributes: [NSAttributedString.Key: Any] { get } 14 | var searchTextAttributes: [NSAttributedString.Key: Any]? { get } 15 | var selectionColor: UIColor { get } 16 | var lineColor: UIColor { get } 17 | var lineWidth: CGFloat { get } 18 | var rasterSize: CGFloat { get } 19 | var backgroundColor: UIColor { get } 20 | var separatorInsets: NSDirectionalEdgeInsets? { get } 21 | var controlColor: UIColor { get } 22 | var searchBarAttributedPlaceholder: NSAttributedString? { get } 23 | } 24 | -------------------------------------------------------------------------------- /Example/Source/tvOS/Images.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - App Store.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | version: 2 6 | updates: 7 | - package-ecosystem: "github-actions" 8 | directory: "/.github/workflows" 9 | schedule: 10 | interval: "weekly" 11 | assignees: 12 | - "Blackjacx" 13 | open-pull-requests-limit: 20 # Limit the number of open PRs 14 | - package-ecosystem: "swift" 15 | directory: "/" # Location of package manifests 16 | schedule: 17 | interval: "weekly" 18 | assignees: 19 | - "Blackjacx" 20 | open-pull-requests-limit: 20 # Limit the number of open PRs 21 | -------------------------------------------------------------------------------- /Source/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleIdentifier 8 | $(PRODUCT_BUNDLE_IDENTIFIER) 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | $(PRODUCT_NAME) 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.10.0 17 | CFBundleVersion 18 | 37 19 | NSHumanReadableCopyright 20 | Copyright © 2023 Stefan Herold. All rights reserved. 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Source/UIColor+SemanticColors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+SemanticColors.swift 3 | // Columbus-iOS 4 | // 5 | // Created by Stefan Herold on 31.01.20. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIColor { 12 | static let text: UIColor = .label 13 | static let line: UIColor = .separator 14 | static let placeholder: UIColor = .placeholderText 15 | 16 | static let background: UIColor = UIColor(dynamicProvider: { (traits) in 17 | switch traits.userInterfaceStyle { 18 | case (.dark): return UIColor(white: 0.1, alpha: 1) 19 | default: return .white 20 | } 21 | }) 22 | 23 | static let selection: UIColor = UIColor(dynamicProvider: { (traits) in 24 | switch traits.userInterfaceStyle { 25 | case (.dark): return .darkGray 26 | default: return UIColor(white: 0.9, alpha: 1.0) 27 | } 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /Source/Classes/ColumbusMain.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColumbusMain.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 22.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // swiftlint:disable:next convenience_type 12 | public final class ColumbusMain { 13 | 14 | public static let bundle: Bundle = { 15 | let frameworkBundle = Bundle(for: ColumbusMain.self) 16 | let bundleName = "Resources.bundle" 17 | guard let bundleURL = frameworkBundle.resourceURL?.appendingPathComponent(bundleName) else { 18 | preconditionFailure("Bundle url nil!") 19 | } 20 | guard let bundle = Bundle(url: bundleURL) else { 21 | preconditionFailure("Bundle nil!") 22 | } 23 | return bundle 24 | }() 25 | 26 | static func layoutConstraintId(_ suffix: String) -> String { 27 | "\(ColumbusMain.bundle.bundleIdentifier!).\(suffix)" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Example/Source/tvOS/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 | 0.6.2 19 | CFBundleVersion 20 | 8 21 | LSRequiresIPhoneOS 22 | 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UIUserInterfaceStyle 28 | Automatic 29 | 30 | 31 | -------------------------------------------------------------------------------- /Columbus.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Columbus' 3 | s.version = '1.9.0' 4 | s.license = { :type => 'MIT', :file => 'LICENSE' } 5 | s.summary = 'A country picker for iOS, tvOS and watchOS.' 6 | s.description = <<-DESC 7 | A country picker for iOS, tvOS and watchOS with features you will only find distributed in many different country-picker implementations. 8 | DESC 9 | s.homepage = 'https://github.com/blackjacx/Columbus' 10 | s.social_media_url = 'https://twitter.com/Blackjacxxx' 11 | s.author = { 'Stefan Herold' => 'stefan.herold@gmail.com' } 12 | s.source = { :git => 'https://github.com/blackjacx/Columbus.git', :tag => s.version.to_s } 13 | s.source_files = 'Source/Classes/**/*' 14 | s.swift_versions = ['5.4'] 15 | 16 | s.ios.deployment_target = '13.0' 17 | s.tvos.deployment_target = '13.0' 18 | 19 | s.resource_bundles = { 20 | 'Resources' => ['Source/Resources/*.{json,xcassets}'] 21 | } 22 | 23 | s.frameworks = 'UIKit' 24 | end 25 | 26 | -------------------------------------------------------------------------------- /Example/Source/iOS/Images.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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Stefan Herold 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Example/Source/iOS/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 | 0.6.2 19 | CFBundleVersion 20 | 8 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationPortraitUpsideDown 33 | UIInterfaceOrientationLandscapeLeft 34 | UIInterfaceOrientationLandscapeRight 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | env: 4 | FRAMEWORK: "Columbus" 5 | XCOV_SCHEME: "Columbus-iOS" 6 | FRAMEWORK_WORKSPACE: "Columbus.xcworkspace" 7 | FASTLANE_XCODE_LIST_TIMEOUT: 999 8 | FASTLANE_WORK_DIR: . 9 | MINT_PATH: ${{ github.workspace }}/mint 10 | 11 | jobs: 12 | bootstrap-and-test: 13 | name: Test 14 | runs-on: macos-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v5 18 | - name: Download Configuration Files 19 | run: bash <(curl -s https://raw.githubusercontent.com/Blackjacx/Scripts/master/frameworks/bootstrap.sh) -d 20 | - name: Cache RubyGems 21 | uses: actions/cache@v4 22 | with: 23 | path: vendor/bundle 24 | key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} 25 | restore-keys: ${{ runner.os }}-gem- 26 | - name: Cache Mint packages 27 | uses: actions/cache@v4 28 | with: 29 | path: ${{ env.MINT_PATH }} 30 | key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }} 31 | restore-keys: ${{ runner.os }}-mint- 32 | - name: Install dependencies 33 | run: bash <(curl -s https://raw.githubusercontent.com/Blackjacx/Scripts/master/frameworks/bootstrap.sh) 34 | - name: Run tests 35 | run: bundle exec fastlane test framework:${{ env.FRAMEWORK }} run_danger:${{ github.event_name }} 36 | env: 37 | DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /Source/Classes/CountryList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CountryList.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 22.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct CountryList { 12 | 13 | public typealias ArrayType = [Country] 14 | 15 | /// List of countries 16 | private let values: ArrayType 17 | 18 | init(values: ArrayType = []) { 19 | self.values = values 20 | } 21 | } 22 | 23 | extension CountryList: Collection { 24 | 25 | public typealias Index = ArrayType.Index 26 | public typealias Element = ArrayType.Element 27 | 28 | // The upper and lower bounds of the collection, used in iterations 29 | public var startIndex: Index { values.startIndex } 30 | public var endIndex: Index { values.endIndex } 31 | 32 | // Required subscript, based on a dictionary index 33 | public subscript(index: Index) -> Element { values[index] } 34 | 35 | // Method that returns the next index when iterating 36 | public func index(after i: Index) -> Index { values.index(after: i) } 37 | } 38 | 39 | extension CountryList: Decodable { 40 | 41 | public init(from decoder: Decoder) throws { 42 | var container = try decoder.unkeyedContainer() 43 | var countries: [Country] = [] 44 | 45 | while !container.isAtEnd { 46 | do { 47 | let country = try container.decode(Country.self) 48 | countries.append(country) 49 | } catch { 50 | _ = try? container.decode(EmptyDecodable.self) // proceed to next element 51 | } 52 | } 53 | self.values = countries 54 | .sorted { $1.name > $0.name } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Example/Source/CountryPickerStoryboard.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 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Source/Classes/Country.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Country.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 21.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum CountryDecodingError: Error { 12 | case nameNotFound 13 | case flagIconNotFound 14 | } 15 | 16 | public struct Country { 17 | 18 | private static let locale = Locale(identifier: Locale.preferredLanguages.first!) 19 | 20 | /// Name of the country 21 | public let name: String 22 | /// ISO country code, e.g. DE, etc. 23 | public let isoCountryCode: String 24 | /// International dialing code, e.g. 49, 1, ... 25 | public let dialingCodeWithPlusPrefix: String 26 | /// `dialingCode` without + sign 27 | public let dialingCode: String 28 | /// The flag icon as unicode string 29 | public let flagString: String 30 | } 31 | 32 | extension Country: Decodable { 33 | 34 | enum CodingKeys: String, CodingKey { 35 | case isoCountryCode = "code" 36 | case dialingCodeWithPlusPrefix = "dial_code" 37 | } 38 | 39 | public init(from decoder: Decoder) throws { 40 | let container = try decoder.container(keyedBy: CodingKeys.self) 41 | let isoCountryCode = try container.decode(String.self, forKey: .isoCountryCode) 42 | 43 | self.isoCountryCode = isoCountryCode 44 | dialingCodeWithPlusPrefix = try container.decode(String.self, forKey: .dialingCodeWithPlusPrefix) 45 | dialingCode = dialingCodeWithPlusPrefix.trimmingCharacters(in: CharacterSet.decimalDigits.inverted) 46 | 47 | guard let countryName = Self.locale.localizedString(forRegionCode: isoCountryCode) else { 48 | throw CountryDecodingError.nameNotFound 49 | } 50 | name = countryName 51 | 52 | guard let flagString = Self.flagUnicode(isoCountryCode: isoCountryCode, name: countryName) else { 53 | throw CountryDecodingError.flagIconNotFound 54 | } 55 | self.flagString = flagString 56 | } 57 | 58 | static func flagUnicode(isoCountryCode: String, name: String) -> String? { 59 | let base = UnicodeScalar("🇦").value - UnicodeScalar("A").value 60 | var s = "" 61 | for v in isoCountryCode.uppercased().unicodeScalars { 62 | s.unicodeScalars.append(UnicodeScalar(base + v.value)!) 63 | } 64 | return String(s) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | # macos 6 | **/.DS_Store 7 | **/.env 8 | **/.envrc 9 | 10 | ## CI 11 | codesigndoc_exports 12 | 13 | # Carthage framework bundle - created during release process 14 | *.framework.zip 15 | *.xcframework.zip 16 | # Fastlane config script is downloaded 17 | fastlane/Fastfile 18 | # Fastlane plugin config is downloaded 19 | fastlane/Pluginfile 20 | # Mint dependencies file which is downloaded 21 | Mintfile 22 | # Swiftlint config file which is downloaded 23 | .swiftlint.yml 24 | # Danger config file which is downloaded 25 | Dangerfile 26 | # Bundler configuration which is bootstrapped 27 | .bundle 28 | # Bundler vendor information which is bootstrapped 29 | vendor 30 | # Documentation script - loaded via https://raw.githubusercontent.com/Blackjacx/Scripts/master/frameworks/bootstrap.sh 31 | scripts/make-docc-documentation.sh 32 | 33 | ## Build generated 34 | build/ 35 | DerivedData/ 36 | 37 | ## Various settings 38 | *.pbxuser 39 | !default.pbxuser 40 | *.mode1v3 41 | !default.mode1v3 42 | *.mode2v3 43 | !default.mode2v3 44 | *.perspectivev3 45 | !default.perspectivev3 46 | xcuserdata/ 47 | 48 | ## Other 49 | *.moved-aside 50 | *.xccheckout 51 | *.xcscmblueprint 52 | 53 | ## Obj-C/Swift specific 54 | *.hmap 55 | *.ipa 56 | *.dSYM.zip 57 | *.dSYM 58 | 59 | ## Playgrounds 60 | timeline.xctimeline 61 | playground.xcworkspace 62 | 63 | # CocoaPods 64 | # 65 | # We recommend against adding the Pods directory to your .gitignore. However 66 | # you should judge for yourself, the pros and cons are mentioned at: 67 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 68 | # 69 | Pods/ 70 | 71 | # Carthage 72 | # 73 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 74 | # Carthage/Checkouts 75 | Carthage/Build 76 | 77 | # Swift Package Manager 78 | # 79 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 80 | # Packages/ 81 | # Package.pins 82 | .build/ 83 | .swiftpm 84 | 85 | # fastlane 86 | # 87 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 88 | # screenshots whenever they are needed. 89 | # For more information about the recommended setup visit: 90 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 91 | 92 | fastlane/report.xml 93 | fastlane/Preview.html 94 | fastlane/screenshots 95 | fastlane/test_output 96 | fastlane/.env 97 | fastlane/README.md -------------------------------------------------------------------------------- /Example/Source/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/Source/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Columbus_iOS_Example 4 | // 5 | // Created by Stefan Herold on 23.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Columbus 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | window = UIWindow(frame: UIScreen.main.bounds) 21 | 22 | let config = CountryPickerConfig() 23 | let defaultCountryCode = CountryPickerViewController.defaultCountry().isoCountryCode 24 | var countryPicker = CountryPickerViewController(config: config, initialCountryCode: defaultCountryCode) { (country) in 25 | print("Programmatic: \(country)") 26 | } 27 | 28 | #if os(iOS) 29 | let storyboard = UIStoryboard(name: "CountryPickerStoryboard", bundle: nil) 30 | countryPicker = storyboard.instantiateViewController(identifier: "picker") { (coder) -> CountryPickerViewController? in 31 | CountryPickerViewController(coder: coder, config: config, initialCountryCode: defaultCountryCode) { (country) in 32 | print("Storyboard: \(country)") 33 | } 34 | } 35 | #endif 36 | 37 | let navigationController = UINavigationController(rootViewController: countryPicker) 38 | #if os(iOS) 39 | navigationController.navigationBar.prefersLargeTitles = true 40 | countryPicker.useLargeTitles(true) 41 | #endif 42 | countryPicker.title = "Country Picker" 43 | 44 | window?.rootViewController = navigationController 45 | window?.makeKeyAndVisible() 46 | return true 47 | } 48 | } 49 | 50 | struct CountryPickerConfig: Configurable { 51 | 52 | var displayState = CountryPickerViewController.DisplayState.countryCodeSelection 53 | /// In this example this has to be a computed property so the font object 54 | /// is calculated later on demand. Since this object is created right at app 55 | /// start something related to dynamic type seems not to be ready yet. 56 | var textAttributes: [NSAttributedString.Key: Any] { 57 | [ 58 | .foregroundColor: UIColor.text, 59 | .font: UIFont.preferredFont(forTextStyle: .body) 60 | ] 61 | } 62 | var searchTextAttributes: [NSAttributedString.Key: Any]? { textAttributes } 63 | var backgroundColor: UIColor = .background 64 | var selectionColor: UIColor = .selection 65 | var controlColor: UIColor = UIColor(red: 1.0 / 255.0, green: 192.0 / 255.0, blue: 1, alpha: 1) 66 | var lineColor: UIColor = .line 67 | var lineWidth: CGFloat = 1.0 / UIScreen.main.scale 68 | var rasterSize: CGFloat = 10.0 69 | var separatorInsets: NSDirectionalEdgeInsets? { nil } 70 | let searchBarAttributedPlaceholder: NSAttributedString? = { 71 | NSAttributedString(string: "Search", 72 | attributes: [ 73 | .foregroundColor: UIColor.placeholder, 74 | .font: UIFont.preferredFont(forTextStyle: .body)]) 75 | }() 76 | } 77 | -------------------------------------------------------------------------------- /Columbus.xcodeproj/xcshareddata/xcschemes/Columbus-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 63 | 69 | 70 | 71 | 72 | 78 | 79 | 85 | 86 | 87 | 88 | 90 | 91 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /Columbus.xcodeproj/xcshareddata/xcschemes/Columbus-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 63 | 69 | 70 | 71 | 72 | 78 | 79 | 85 | 86 | 87 | 88 | 90 | 91 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /Example/ColumbusExample.xcodeproj/xcshareddata/xcschemes/Columbus_iOS_Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 64 | 70 | 71 | 72 | 73 | 79 | 81 | 87 | 88 | 89 | 90 | 92 | 93 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Example/ColumbusExample.xcodeproj/xcshareddata/xcschemes/Columbus_tvOS_Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 64 | 70 | 71 | 72 | 73 | 79 | 81 | 87 | 88 | 89 | 90 | 92 | 93 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Source/Classes/CountryCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CountryCell.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 21.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class CountryCell: UITableViewCell { 12 | 13 | static var cellId: String { "\(CountryCell.self)" } 14 | 15 | private let countryView = CountryView() 16 | private let separator = UIView() 17 | private var config: Configurable! 18 | 19 | private var separatorHeight: NSLayoutConstraint? 20 | private var separatorLeading: NSLayoutConstraint? 21 | private var separatorTrailing: NSLayoutConstraint? 22 | 23 | private func sharedInit() { 24 | selectedBackgroundView = UIView() 25 | selectedBackgroundView?.layer.masksToBounds = true 26 | 27 | backgroundView = UIView() 28 | backgroundView?.layer.masksToBounds = true 29 | 30 | setupCountryView() 31 | setupSeparator() 32 | setupAutoLayout() 33 | } 34 | 35 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 36 | super.init(style: style, reuseIdentifier: reuseIdentifier) 37 | sharedInit() 38 | } 39 | 40 | required init?(coder aDecoder: NSCoder) { 41 | super.init(coder: aDecoder) 42 | sharedInit() 43 | } 44 | 45 | override func layoutSubviews() { 46 | super.layoutSubviews() 47 | let radius = frame.height / 4 48 | selectedBackgroundView?.layer.cornerRadius = radius 49 | backgroundView?.layer.cornerRadius = radius 50 | } 51 | 52 | override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { 53 | backgroundView?.backgroundColor = isFocused ? config.selectionColor : config.backgroundColor 54 | } 55 | 56 | func setupCountryView() { 57 | countryView.translatesAutoresizingMaskIntoConstraints = false 58 | countryView.setContentHuggingPriority(.required, for: .vertical) 59 | contentView.addSubview(countryView) 60 | } 61 | 62 | private func setupSeparator() { 63 | separator.translatesAutoresizingMaskIntoConstraints = false 64 | contentView.addSubview(separator) 65 | } 66 | 67 | func setupAutoLayout() { 68 | separatorHeight = separator.heightAnchor.constraint(equalToConstant: 0) 69 | separatorHeight?.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).separatorHeight") 70 | 71 | let separatorBottom = separator.bottomAnchor.constraint(equalTo: bottomAnchor) 72 | separatorBottom.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).separatorBottom") 73 | 74 | let leading = countryView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor) 75 | leading.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).leading") 76 | 77 | let trailing = countryView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor) 78 | trailing.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).trailing") 79 | 80 | let top = countryView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor) 81 | top.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).top") 82 | 83 | let bottom = countryView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor) 84 | bottom.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).bottom") 85 | 86 | NSLayoutConstraint.activate([ 87 | leading, 88 | trailing, 89 | top, 90 | bottom, 91 | separatorHeight!, 92 | separatorBottom 93 | ]) 94 | } 95 | 96 | func configure(with country: Country, config: Configurable) { 97 | self.config = config 98 | countryView.configure(with: country, config: config) 99 | 100 | // 101 | // Separator setup 102 | // 103 | 104 | separator.backgroundColor = config.lineColor 105 | separatorHeight?.constant = config.lineWidth 106 | 107 | // First deactivate constraints 108 | NSLayoutConstraint.deactivate([separatorLeading, separatorTrailing].compactMap { $0 }) 109 | 110 | // Now override constraints 111 | if let separatorInsets = config.separatorInsets { 112 | separatorLeading = separator.leadingAnchor.constraint(equalTo: leadingAnchor, constant: separatorInsets.leading) 113 | separatorTrailing = separator.trailingAnchor.constraint(equalTo: trailingAnchor, constant: separatorInsets.trailing) 114 | } else { 115 | separatorLeading = separator.leadingAnchor.constraint(equalTo: countryView.leadingTextAnchor) 116 | separatorTrailing = separator.trailingAnchor.constraint(equalTo: countryView.trailingTextAnchor) 117 | } 118 | // Finally activate the correct constraints 119 | NSLayoutConstraint.activate([separatorLeading!, separatorTrailing!]) 120 | 121 | #if os(iOS) 122 | separator.isHidden = false 123 | #else 124 | separator.isHidden = true 125 | #endif 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Source/Classes/CountryView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CountryView.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 21.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class CountryView: UIView { 12 | 13 | private (set) lazy var leadingTextAnchor: NSLayoutXAxisAnchor = countryNameLabel.leadingAnchor 14 | private (set) lazy var trailingTextAnchor: NSLayoutXAxisAnchor = countryCodeLabel.trailingAnchor 15 | 16 | private let hStack = UIStackView() 17 | private let flagIconView = UILabel() 18 | private let countryNameLabel = UILabel() 19 | private let countryCodeLabel = UILabel() 20 | 21 | var country: Country! 22 | var config: Configurable! 23 | 24 | private func sharedInit() { 25 | setupHStack() 26 | setupFlagIconView() 27 | setupCountryNameLabel() 28 | setupCountryCodeLabel() 29 | setupAutoLayout() 30 | } 31 | 32 | override init(frame: CGRect) { 33 | super.init(frame: frame) 34 | sharedInit() 35 | } 36 | 37 | required init?(coder aDecoder: NSCoder) { 38 | super.init(coder: aDecoder) 39 | sharedInit() 40 | } 41 | 42 | func setupHStack() { 43 | [flagIconView, countryNameLabel, countryCodeLabel].forEach { 44 | hStack.addArrangedSubview($0) 45 | } 46 | hStack.translatesAutoresizingMaskIntoConstraints = false 47 | addSubview(hStack) 48 | } 49 | 50 | func setupFlagIconView() { 51 | flagIconView.numberOfLines = 1 52 | flagIconView.setContentHuggingPriority(.required, for: .horizontal) 53 | flagIconView.setContentHuggingPriority(.required, for: .vertical) 54 | flagIconView.setContentCompressionResistancePriority(.required, for: .horizontal) 55 | } 56 | 57 | func setupCountryNameLabel() { 58 | } 59 | 60 | private func setupCountryCodeLabel() { 61 | countryCodeLabel.setContentCompressionResistancePriority(.required, for: .horizontal) 62 | countryCodeLabel.setContentHuggingPriority(.required, for: .horizontal) 63 | } 64 | 65 | func setupAutoLayout() { 66 | let constraints: [NSLayoutConstraint] = [ 67 | hStack.leadingAnchor.constraint(equalTo: leadingAnchor), 68 | hStack.trailingAnchor.constraint(equalTo: trailingAnchor), 69 | hStack.topAnchor.constraint(equalTo: topAnchor), 70 | hStack.bottomAnchor.constraint(equalTo: bottomAnchor) 71 | ] 72 | NSLayoutConstraint.activate(constraints) 73 | } 74 | 75 | func configure(with country: Country, config: Configurable) { 76 | 77 | hStack.spacing = config.rasterSize 78 | 79 | countryNameLabel.attributedText = NSAttributedString(string: country.name, 80 | attributes: config.textAttributes) 81 | 82 | let countryCodeAttributes = updatedAttributes(attributes: config.textAttributes, 83 | alignment: .right) 84 | countryCodeLabel.attributedText = NSAttributedString(string: country.dialingCodeWithPlusPrefix, 85 | attributes: countryCodeAttributes) 86 | 87 | let flagIconAttributes = updatedAttributes(attributes: config.textAttributes, 88 | // Ensure a system font is used for the emojis so they are not 89 | // truncated or rendered in a weird way 90 | font: UIFont.preferredFont(forTextStyle: .body), 91 | // Center icon horizontally (tvOS) 92 | alignment: .center, 93 | // Improve visibility of flags with white background 94 | shadow: NSShadow()) 95 | 96 | flagIconView.attributedText = NSAttributedString(string: country.flagString, 97 | attributes: flagIconAttributes) 98 | 99 | // Configure Display State 100 | switch config.displayState { 101 | case .simple: countryCodeLabel.isHidden = true 102 | case .countryCodeSelection: countryCodeLabel.isHidden = false 103 | } 104 | } 105 | 106 | private func updatedAttributes(attributes: [NSAttributedString.Key: Any], 107 | font: UIFont? = nil, 108 | alignment: NSTextAlignment? = nil, 109 | shadow: NSShadow? = nil) -> [NSAttributedString.Key: Any] { 110 | var attributes = attributes 111 | 112 | if let font = font { 113 | attributes[.font] = font 114 | } 115 | 116 | if let alignment = alignment { 117 | let paragraphStyle = NSMutableParagraphStyle() 118 | paragraphStyle.setParagraphStyle(NSParagraphStyle.default) 119 | paragraphStyle.alignment = alignment 120 | attributes[.paragraphStyle] = paragraphStyle 121 | } 122 | 123 | if let shadow = shadow { 124 | shadow.shadowOffset = CGSize(width: 1, height: 1) 125 | shadow.shadowColor = UIColor(white: 0, alpha: 0.25) 126 | attributes[.shadow] = shadow 127 | } 128 | 129 | return attributes 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [Unreleased] 4 | 5 | ## [1.10.0] - 2024-07-12Z 6 | * [#51](https://github.com/Blackjacx/Columbus/pull/51): Make font attributes optional - [@Blackjacx](https://github.com/Blackjacx). 7 | 8 | ## [1.9.0] - 2023-05-09Z 9 | * [#49](https://github.com/Blackjacx/Columbus/pull/49): Add fallback for CTCarrier deprecation - [@mic-ioki](https://github.com/mic-ioki). 10 | * Use default country for the initial country code - [@Blackjacx](https://github.com/Blackjacx). 11 | * Update Copyright - [@Blackjacx](https://github.com/Blackjacx). 12 | 13 | ## [1.8.0] - 2023-05-02Z 14 | * Remove auto assign to project workflow - [@Blackjacx](https://github.com/Blackjacx). 15 | * Make CoreTelephony Approach Debuggable - [@Blackjacx](https://github.com/Blackjacx). 16 | 17 | ## [1.7.6] - 2022-07-07Z 18 | 19 | * [#43](https://github.com/Blackjacx/Columbus/pull/43): Enable Large Titles - [@Blackjacx](https://github.com/Blackjacx). 20 | 21 | ## [1.7.5] - 2022-02-01Z 22 | * Remove SwiftLint Build Phase (b5c98ca055a1e577dd910b9f6fc2aac9e6a2ce5c) - [@Blackjacx](https://github.com/Blackjacx). 23 | 24 | ## [1.7.4] - 2021-11-29Z 25 | * [#42](https://github.com/Blackjacx/Columbus/pull/42): Add horizontal hugging prio to code label - [@Blackjacx](https://github.com/Blackjacx). 26 | 27 | ## [1.7.3] - 2021-11-24 28 | * [#40](https://github.com/Blackjacx/Columbus/pull/40): Use system font for flags - [@Blackjacx](https://github.com/Blackjacx). 29 | 30 | ## [1.7.2] - 2021-11-24 31 | * [#39](https://github.com/Blackjacx/Columbus/pull/39): Fix Icon Truncation - [@Blackjacx](https://github.com/Blackjacx). 32 | 33 | ## [1.7.1] - 2021-11-24 34 | * [#38](https://github.com/Blackjacx/Columbus/pull/38): Fix Separator Alignment - [@Blackjacx](https://github.com/Blackjacx). 35 | 36 | ## [1.7.0] - 2021-11-23 37 | * [#37](https://github.com/Blackjacx/Columbus/pull/37): Replace images by emojis - [@Blackjacx](https://github.com/Blackjacx). 38 | 39 | ## [1.6.0] - 2021-05-20 40 | * [#34](https://github.com/Blackjacx/Columbus/pull/34): XCFramework Compatibility - [@Blackjacx](https://github.com/Blackjacx). 41 | * Simplify section index creation - [@Blackjacx](https://github.com/Blackjacx). 42 | * Throw error instead of ignore missing flag icon - [@Blackjacx](https://github.com/Blackjacx). 43 | 44 | ## [1.4.2] - 2021-02-06 45 | * Implement DisplayState - [@Blackjacx](https://github.com/Blackjacx). 46 | * Inject config directly in ViewController - [@Blackjacx](https://github.com/Blackjacx). 47 | 48 | ## [1.4.1] - 2020-07-02 49 | * [#24](https://github.com/Blackjacx/Columbus/pull/24): Remove defaultCountry() isoCountryCode param default value - [@Blackjacx](https://github.com/Blackjacx). 50 | 51 | ## [1.4.0] - 2020-07-02 52 | * [#23](https://github.com/Blackjacx/Columbus/pull/23): Use region code instead Locale in defaultCountry - [@Blackjacx](https://github.com/Blackjacx). 53 | 54 | ## [1.2.0] - 2020-04-16 55 | * [#22](https://github.com/Blackjacx/Columbus/pull/22): Enable module stability - [@Blackjacx](https://github.com/Blackjacx). 56 | 57 | ## [1.1.1] - 2020-02-01 58 | * [#20](https://github.com/Blackjacx/Columbus/pull/20): Fix App Localization - [@Blackjacx](https://github.com/Blackjacx). 59 | 60 | ## [1.1.0] - 2020-02-01 61 | * [#19](https://github.com/Blackjacx/Columbus/pull/19): Implement Dynamic Type - [@Blackjacx](https://github.com/Blackjacx). 62 | 63 | ## [1.0.1] - 2019-08-13 64 | * [#18](https://github.com/Blackjacx/Columbus/pull/18): Fix Recursive Textfield Determination - [@Blackjacx](https://github.com/Blackjacx). 65 | * Fix vulnerability with Fastlane / mini_magick - [@Blackjacx](https://github.com/blackjacx). 66 | 67 | ## [1.0.0] - 2019-05-14 68 | * [#16](https://github.com/Blackjacx/Columbus/pull/16): Fix Keyboard-Related Events - [@Blackjacx](https://github.com/Blackjacx). 69 | * [#15](https://github.com/Blackjacx/Columbus/pull/15): Migrate to Swift 5 - [@Blackjacx](https://github.com/Blackjacx). 70 | 71 | ## [0.7.4] - 2019-01-04 72 | * [#13](https://github.com/Blackjacx/Columbus/pull/13): Prevent Embedding Swift Libraries - [@blackjacx](https://github.com/blackjacx). 73 | 74 | ## [0.7.3] - 2019-01-04 75 | * [#12](https://github.com/Blackjacx/Columbus/pull/12): Remove CFBundleExecutable From Plist - [@blackjacx](https://github.com/blackjacx). 76 | 77 | ## [0.7.2] - 2018-12-28 78 | * [#11](https://github.com/Blackjacx/Columbus/pull/11): Fix Resource Bundle Name - [@blackjacx](https://github.com/blackjacx). 79 | 80 | ## [0.7.1] - 2018-12-28 81 | * [#10](https://github.com/Blackjacx/Columbus/pull/10): Prevent Using CoreTelephony API on Simulator - [@blackjacx](https://github.com/blackjacx). 82 | 83 | ## [0.7.0] - 2018-12-24 84 | * [#9](https://github.com/Blackjacx/Columbus/pull/9): Enable Carthage Support - [@blackjacx](https://github.com/blackjacx). 85 | 86 | ## [0.6.2] - 2018-11-30 87 | * [#8](https://github.com/Blackjacx/Columbus/pull/8): Fix Constraint Warnings - [@blackjacx](https://github.com/blackjacx). 88 | 89 | ## [0.6.1] - 2018-11-14 90 | * [#7](https://github.com/Blackjacx/Columbus/pull/7): Customizable Separator Insets - [@blackjacx](https://github.com/blackjacx). 91 | 92 | ## [0.6.0] - 2018-11-14 93 | * [#6](https://github.com/Blackjacx/Columbus/pull/6): Make Countries • DefaultCountry Easier Reachable - [@blackjacx](https://github.com/blackjacx). 94 | 95 | ## [0.5.0] - 2018-11-09 96 | * Add AUTHORS file - [@blackjacx](https://github.com/blackjacx). 97 | 98 | ## [0.4.0] - 2018-11-06 99 | * [#5](https://github.com/Blackjacx/Columbus/pull/5): Add Vector Flag Assets - [@regexident](https://github.com/regexident). 100 | * [#4](https://github.com/Blackjacx/Columbus/pull/4): Added some "please"s to the "Contribution" part of the README - [@regexident](https://github.com/regexident). 101 | 102 | ## [0.3.0] - 2018-10-03 103 | * [#3](https://github.com/Blackjacx/Columbus/pull/3): Adding Feature List and Screenshots - [@blackjacx](https://github.com/blackjacx). 104 | 105 | ## [0.2.0] - 2018-10-02 106 | * [#1](https://github.com/Blackjacx/Columbus/pull/1): Initial Commit - [@blackjacx](https://github.com/blackjacx). 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [![Twitter Follow](https://img.shields.io/badge/follow-%40blackjacx-1DA1F2?logo=twitter&style=for-the-badge)](https://twitter.com/intent/follow?original_referer=https%3A%2F%2Fgithub.com%2Fblackjacx&screen_name=Blackjacxxx) 4 | [![Version](https://img.shields.io/github/release/blackjacx/Columbus.svg)](https://github.com/Blackjacx/Columbus/releases) 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![Platforms](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FBlackjacx%2FColumbus%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/Blackjacx/Columbus) 7 | [![Swift Versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FBlackjacx%2FColumbus%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/Blackjacx/Columbus) 8 | [![iOS 13+](https://img.shields.io/badge/iOS-13.0%2B-blue.svg)](https://developer.apple.com/download/) 9 | [![Xcode 13+](https://img.shields.io/badge/Xcode-13%2B-blue.svg)](https://developer.apple.com/download/) 10 | [![Codebeat](https://codebeat.co/badges/7ad2da62-af22-4a76-a4da-2eb2002bde18)](https://codebeat.co/projects/github-com-blackjacx-columbus-develop) 11 | [![License](https://img.shields.io/github/license/blackjacx/columbus.svg)](https://github.com/blackjacx/columbus/blob/main/LICENSE) 12 | [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg?logo=paypal&style=for-the-badge)](https://www.paypal.me/STHEROLD) 13 | 14 | # Columbus 15 | 16 | A country picker 🌎 for iOS, tvOS ad watchOS with features you will only find distributed in many different country-picker implementations. 17 | 18 | ## Features 19 | 20 | - Filter countries using an as-you-type search bar - type the **name** or it's **country code** 21 | - Quickly find a country by using the **index bar** on the right 22 | - Localized by using standard components and Apple's `Locale` class 23 | - Theme support to easily fit to your design 24 | - Storyboard support 25 | - Select a country from the history of selected countries - `still in progress` 26 | 27 | ## Code Documentation 28 | 29 | Find the statically generated code documentation [here](https://blackjacx.github.io/Columbus/documentation/columbus/) (powered by [DocC](https://developer.apple.com/documentation/docc)) 30 | 31 | ## Installation 32 | 33 | ### Carthage (recommended) 34 | 35 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate Columbus into your Xcode project using Carthage, specify it in your Cartfile: 36 | 37 | ```ruby 38 | github "Blackjacx/Columbus" 39 | ``` 40 | 41 | The use the following command to build the XCFramework: 42 | 43 | ```shell 44 | carthage bootstrap --use-ssh --use-xcframeworks --cache-builds 45 | ``` 46 | 47 | Using Carthage has some advantages in contrast to Cocopods for this framework. Since it needs to compile the asset catalog for over 200 flag assets it is much faster to build the framework once using Carthage and drop it into your app. If you use Cocoapods the asset catalog is compiled together with Columbus each time you do a clean build and probably also when Xcode thinks Columbus needs to be compiled again. 48 | 49 | ### CocoaPods 50 | 51 | To install via [CocoaPods](https://cocoapods.org/pods/Columbus), simply add the following line to your Podfile and run `pod install` to install the newest version: 52 | 53 | ```ruby 54 | pod "Columbus" 55 | ``` 56 | 57 | ## Examples 58 | 59 | ### Usage 60 | 61 | In the following example you'll find all the possible configuration/theming options of Columbus: 62 | 63 | ```swift 64 | struct CountryPickerConfig: Configurable { 65 | 66 | var displayState = CountryPickerViewController.DisplayState.countryCodeSelection 67 | /// In this example this has to be a computed property so the font object 68 | /// is calculated later on demand. Since this object is created right at app 69 | /// start something related to dynamic type seems not to be ready yet. 70 | var textAttributes: [NSAttributedString.Key: Any] { 71 | [ 72 | .foregroundColor: UIColor.text, 73 | .font: UIFont.preferredFont(forTextStyle: .body) 74 | ] 75 | } 76 | var backgroundColor: UIColor = .background 77 | var selectionColor: UIColor = .selection 78 | var controlColor: UIColor = UIColor(red: 1.0 / 255.0, green: 192.0 / 255.0, blue: 1, alpha: 1) 79 | var lineColor: UIColor = .line 80 | var lineWidth: CGFloat = 1.0 / UIScreen.main.scale 81 | var rasterSize: CGFloat = 10.0 82 | var separatorInsets: UIEdgeInsets { 83 | UIEdgeInsets(top: 0, left: rasterSize * 4.7, bottom: 0, right: rasterSize * 2.5) 84 | } 85 | let searchBarAttributedPlaceholder: NSAttributedString = { 86 | NSAttributedString(string: "Search", 87 | attributes: [ 88 | .foregroundColor: UIColor.placeholder, 89 | .font: UIFont.preferredFont(forTextStyle: .body)]) 90 | }() 91 | } 92 | let countryPicker = CountryPickerViewController(config: CountryPickerConfig(), 93 | initialCountryCode: "US") { (country) in 94 | print(country) 95 | } 96 | present(countryPicker, animated: true) 97 | 98 | ``` 99 | 100 | ### Storyboards 101 | 102 | Good news for our storyboard users. I implemented full storyboard support. You'll need a fallback for earlier versions. To instantiate the picker from a storyboard you can use the following example: 103 | 104 | ```swift 105 | let defaultCountry = CountryPickerViewController.defaultCountry(from: "US") 106 | let picker: CountryPickerViewController = storyboard.instantiateViewController(identifier: "Picker") { (coder) -> CountryPickerViewController? in 107 | return CountryPickerViewController(coder: coder, initialCountryCode: defaultCountry.isoCountryCode) { (country) in 108 | print(country) 109 | } 110 | } 111 | ``` 112 | 113 | The above example gives you a non-optional instance of `CountryPickerViewController`. This new syntax also enables us to provide parameters for a storyboard-initialized view (controller). This prevents the addition of optional properties like in previous versions of iOS which is a huge progress. 114 | 115 | ### iOS 116 | 117 | The repository includes an example project. It shows the main use case of the project - the country picker. To run it, just type `pod try Columbus` in your console and it will be downloaded and opened for you. The following set of screenshots highlights the key features unique to Columbus: 118 | 119 | Filtering|Index bar|History|Localization|Theming 120 | --- | --- | --- | --- | --- 121 | ![Searchbar](./github/assets/searchbar.png)|![Indexbar](./github/assets/indexbar.png)|![History](./github/assets/history.png)|![Localization](./github/assets/localization.png)|![Theming](./github/assets/theming.png) 122 | 123 | 124 | ### tvOS 125 | ... still in progress ... 126 | 127 | ### watchOS 128 | ... still in progress ... 129 | 130 | ## Contribution 131 | 132 | - If you found a **bug**, please open an **issue**. 133 | - If you have a **feature request**, please open an **issue**. 134 | - If you want to **contribute**, please submit a **pull request**. 135 | 136 | ## Author 137 | 138 | [Stefan Herold](mailto:stefan.herold@gmail.com) • 🐦 [@Blackjacxxx](https://twitter.com/Blackjacxxx) 139 | 140 | ## Contributors 141 | 142 | Thanks to all of you who are part of this: 143 | 144 | 145 | 146 | 147 | 148 | ## Links 149 | 150 | - [Modifying UISearchBar Cancel button font text color and style](https://stackoverflow.com/questions/11572372/modifying-uisearchbar-cancel-button-font-text-color-and-style) 151 | - [Localize the cancel button of a UISearchBar](https://stackoverflow.com/questions/12031942/uisearchbar-cancel-button-change-language-of-word-cancel-in-uisearchdisplaycon) 152 | 153 | ## License 154 | 155 | Columbus is available under the MIT license. See the [LICENSE](LICENSE) file for more info. 156 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | activesupport (7.1.3.4) 9 | base64 10 | bigdecimal 11 | concurrent-ruby (~> 1.0, >= 1.0.2) 12 | connection_pool (>= 2.2.5) 13 | drb 14 | i18n (>= 1.6, < 2) 15 | minitest (>= 5.1) 16 | mutex_m 17 | tzinfo (~> 2.0) 18 | addressable (2.8.7) 19 | public_suffix (>= 2.0.2, < 7.0) 20 | algoliasearch (1.27.5) 21 | httpclient (~> 2.8, >= 2.8.3) 22 | json (>= 1.5.1) 23 | artifactory (3.0.17) 24 | atomos (0.1.3) 25 | aws-eventstream (1.3.0) 26 | aws-partitions (1.955.0) 27 | aws-sdk-core (3.201.1) 28 | aws-eventstream (~> 1, >= 1.3.0) 29 | aws-partitions (~> 1, >= 1.651.0) 30 | aws-sigv4 (~> 1.8) 31 | jmespath (~> 1, >= 1.6.1) 32 | aws-sdk-kms (1.88.0) 33 | aws-sdk-core (~> 3, >= 3.201.0) 34 | aws-sigv4 (~> 1.5) 35 | aws-sdk-s3 (1.156.0) 36 | aws-sdk-core (~> 3, >= 3.201.0) 37 | aws-sdk-kms (~> 1) 38 | aws-sigv4 (~> 1.5) 39 | aws-sigv4 (1.8.0) 40 | aws-eventstream (~> 1, >= 1.0.2) 41 | babosa (1.0.4) 42 | base64 (0.2.0) 43 | bigdecimal (3.1.8) 44 | claide (1.1.0) 45 | claide-plugins (0.9.2) 46 | cork 47 | nap 48 | open4 (~> 1.3) 49 | cocoapods (1.15.2) 50 | addressable (~> 2.8) 51 | claide (>= 1.0.2, < 2.0) 52 | cocoapods-core (= 1.15.2) 53 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 54 | cocoapods-downloader (>= 2.1, < 3.0) 55 | cocoapods-plugins (>= 1.0.0, < 2.0) 56 | cocoapods-search (>= 1.0.0, < 2.0) 57 | cocoapods-trunk (>= 1.6.0, < 2.0) 58 | cocoapods-try (>= 1.1.0, < 2.0) 59 | colored2 (~> 3.1) 60 | escape (~> 0.0.4) 61 | fourflusher (>= 2.3.0, < 3.0) 62 | gh_inspector (~> 1.0) 63 | molinillo (~> 0.8.0) 64 | nap (~> 1.0) 65 | ruby-macho (>= 2.3.0, < 3.0) 66 | xcodeproj (>= 1.23.0, < 2.0) 67 | cocoapods-core (1.15.2) 68 | activesupport (>= 5.0, < 8) 69 | addressable (~> 2.8) 70 | algoliasearch (~> 1.0) 71 | concurrent-ruby (~> 1.1) 72 | fuzzy_match (~> 2.0.4) 73 | nap (~> 1.0) 74 | netrc (~> 0.11) 75 | public_suffix (~> 4.0) 76 | typhoeus (~> 1.0) 77 | cocoapods-deintegrate (1.0.5) 78 | cocoapods-downloader (2.1) 79 | cocoapods-plugins (1.0.0) 80 | nap 81 | cocoapods-search (1.0.1) 82 | cocoapods-trunk (1.6.0) 83 | nap (>= 0.8, < 2.0) 84 | netrc (~> 0.11) 85 | cocoapods-try (1.2.0) 86 | colored (1.2) 87 | colored2 (3.1.2) 88 | commander (4.6.0) 89 | highline (~> 2.0.0) 90 | concurrent-ruby (1.3.3) 91 | connection_pool (2.4.1) 92 | cork (0.3.0) 93 | colored2 (~> 3.1) 94 | danger (9.4.3) 95 | claide (~> 1.0) 96 | claide-plugins (>= 0.9.2) 97 | colored2 (~> 3.1) 98 | cork (~> 0.1) 99 | faraday (>= 0.9.0, < 3.0) 100 | faraday-http-cache (~> 2.0) 101 | git (~> 1.13) 102 | kramdown (~> 2.3) 103 | kramdown-parser-gfm (~> 1.0) 104 | no_proxy_fix 105 | octokit (>= 4.0) 106 | terminal-table (>= 1, < 4) 107 | danger-changelog (0.7.1) 108 | danger-plugin-api (~> 1.0) 109 | danger-commit_lint (0.0.7) 110 | danger-plugin-api (~> 1.0) 111 | danger-plugin-api (1.0.0) 112 | danger (> 2.0) 113 | danger-swiftlint (0.36.1) 114 | danger 115 | rake (> 10) 116 | thor (~> 1.0.0) 117 | danger-xcov (0.5.0) 118 | danger (>= 2.1) 119 | xcov (>= 1.7.3) 120 | declarative (0.0.20) 121 | digest-crc (0.6.5) 122 | rake (>= 12.0.0, < 14.0.0) 123 | domain_name (0.6.20240107) 124 | dotenv (2.8.1) 125 | drb (2.2.1) 126 | emoji_regex (3.2.3) 127 | escape (0.0.4) 128 | ethon (0.16.0) 129 | ffi (>= 1.15.0) 130 | excon (0.111.0) 131 | faraday (1.10.3) 132 | faraday-em_http (~> 1.0) 133 | faraday-em_synchrony (~> 1.0) 134 | faraday-excon (~> 1.1) 135 | faraday-httpclient (~> 1.0) 136 | faraday-multipart (~> 1.0) 137 | faraday-net_http (~> 1.0) 138 | faraday-net_http_persistent (~> 1.0) 139 | faraday-patron (~> 1.0) 140 | faraday-rack (~> 1.0) 141 | faraday-retry (~> 1.0) 142 | ruby2_keywords (>= 0.0.4) 143 | faraday-cookie_jar (0.0.7) 144 | faraday (>= 0.8.0) 145 | http-cookie (~> 1.0.0) 146 | faraday-em_http (1.0.0) 147 | faraday-em_synchrony (1.0.0) 148 | faraday-excon (1.1.0) 149 | faraday-http-cache (2.5.1) 150 | faraday (>= 0.8) 151 | faraday-httpclient (1.0.1) 152 | faraday-multipart (1.0.4) 153 | multipart-post (~> 2) 154 | faraday-net_http (1.0.1) 155 | faraday-net_http_persistent (1.2.0) 156 | faraday-patron (1.0.0) 157 | faraday-rack (1.0.0) 158 | faraday-retry (1.0.3) 159 | faraday_middleware (1.2.0) 160 | faraday (~> 1.0) 161 | fastimage (2.3.1) 162 | fastlane (2.221.1) 163 | CFPropertyList (>= 2.3, < 4.0.0) 164 | addressable (>= 2.8, < 3.0.0) 165 | artifactory (~> 3.0) 166 | aws-sdk-s3 (~> 1.0) 167 | babosa (>= 1.0.3, < 2.0.0) 168 | bundler (>= 1.12.0, < 3.0.0) 169 | colored (~> 1.2) 170 | commander (~> 4.6) 171 | dotenv (>= 2.1.1, < 3.0.0) 172 | emoji_regex (>= 0.1, < 4.0) 173 | excon (>= 0.71.0, < 1.0.0) 174 | faraday (~> 1.0) 175 | faraday-cookie_jar (~> 0.0.6) 176 | faraday_middleware (~> 1.0) 177 | fastimage (>= 2.1.0, < 3.0.0) 178 | gh_inspector (>= 1.1.2, < 2.0.0) 179 | google-apis-androidpublisher_v3 (~> 0.3) 180 | google-apis-playcustomapp_v1 (~> 0.1) 181 | google-cloud-env (>= 1.6.0, < 2.0.0) 182 | google-cloud-storage (~> 1.31) 183 | highline (~> 2.0) 184 | http-cookie (~> 1.0.5) 185 | json (< 3.0.0) 186 | jwt (>= 2.1.0, < 3) 187 | mini_magick (>= 4.9.4, < 5.0.0) 188 | multipart-post (>= 2.0.0, < 3.0.0) 189 | naturally (~> 2.2) 190 | optparse (>= 0.1.1, < 1.0.0) 191 | plist (>= 3.1.0, < 4.0.0) 192 | rubyzip (>= 2.0.0, < 3.0.0) 193 | security (= 0.1.5) 194 | simctl (~> 1.6.3) 195 | terminal-notifier (>= 2.0.0, < 3.0.0) 196 | terminal-table (~> 3) 197 | tty-screen (>= 0.6.3, < 1.0.0) 198 | tty-spinner (>= 0.8.0, < 1.0.0) 199 | word_wrap (~> 1.0.0) 200 | xcodeproj (>= 1.13.0, < 2.0.0) 201 | xcpretty (~> 0.3.0) 202 | xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) 203 | fastlane-plugin-changelog (0.16.0) 204 | ffi (1.17.0) 205 | fourflusher (2.3.1) 206 | fuzzy_match (2.0.4) 207 | gh_inspector (1.1.3) 208 | git (1.19.1) 209 | addressable (~> 2.8) 210 | rchardet (~> 1.8) 211 | google-apis-androidpublisher_v3 (0.54.0) 212 | google-apis-core (>= 0.11.0, < 2.a) 213 | google-apis-core (0.11.3) 214 | addressable (~> 2.5, >= 2.5.1) 215 | googleauth (>= 0.16.2, < 2.a) 216 | httpclient (>= 2.8.1, < 3.a) 217 | mini_mime (~> 1.0) 218 | representable (~> 3.0) 219 | retriable (>= 2.0, < 4.a) 220 | rexml 221 | google-apis-iamcredentials_v1 (0.17.0) 222 | google-apis-core (>= 0.11.0, < 2.a) 223 | google-apis-playcustomapp_v1 (0.13.0) 224 | google-apis-core (>= 0.11.0, < 2.a) 225 | google-apis-storage_v1 (0.31.0) 226 | google-apis-core (>= 0.11.0, < 2.a) 227 | google-cloud-core (1.7.0) 228 | google-cloud-env (>= 1.0, < 3.a) 229 | google-cloud-errors (~> 1.0) 230 | google-cloud-env (1.6.0) 231 | faraday (>= 0.17.3, < 3.0) 232 | google-cloud-errors (1.4.0) 233 | google-cloud-storage (1.47.0) 234 | addressable (~> 2.8) 235 | digest-crc (~> 0.4) 236 | google-apis-iamcredentials_v1 (~> 0.1) 237 | google-apis-storage_v1 (~> 0.31.0) 238 | google-cloud-core (~> 1.6) 239 | googleauth (>= 0.16.2, < 2.a) 240 | mini_mime (~> 1.0) 241 | googleauth (1.8.1) 242 | faraday (>= 0.17.3, < 3.a) 243 | jwt (>= 1.4, < 3.0) 244 | multi_json (~> 1.11) 245 | os (>= 0.9, < 2.0) 246 | signet (>= 0.16, < 2.a) 247 | highline (2.0.3) 248 | http-cookie (1.0.6) 249 | domain_name (~> 0.5) 250 | httpclient (2.8.3) 251 | i18n (1.14.5) 252 | concurrent-ruby (~> 1.0) 253 | jmespath (1.6.2) 254 | json (2.7.2) 255 | jwt (2.8.2) 256 | base64 257 | kramdown (2.4.0) 258 | rexml 259 | kramdown-parser-gfm (1.1.0) 260 | kramdown (~> 2.0) 261 | mini_magick (4.13.2) 262 | mini_mime (1.1.5) 263 | minitest (5.24.1) 264 | molinillo (0.8.0) 265 | multi_json (1.15.0) 266 | multipart-post (2.4.1) 267 | mutex_m (0.2.0) 268 | nanaimo (0.3.0) 269 | nap (1.1.0) 270 | naturally (2.2.1) 271 | netrc (0.11.0) 272 | nkf (0.2.0) 273 | no_proxy_fix (0.1.2) 274 | octokit (9.1.0) 275 | faraday (>= 1, < 3) 276 | sawyer (~> 0.9) 277 | open4 (1.3.4) 278 | optparse (0.5.0) 279 | os (1.1.4) 280 | plist (3.7.1) 281 | public_suffix (4.0.7) 282 | rake (13.2.1) 283 | rchardet (1.8.0) 284 | representable (3.2.0) 285 | declarative (< 0.1.0) 286 | trailblazer-option (>= 0.1.1, < 0.2.0) 287 | uber (< 0.2.0) 288 | retriable (3.1.2) 289 | rexml (3.2.9) 290 | strscan 291 | rouge (2.0.7) 292 | ruby-macho (2.5.1) 293 | ruby2_keywords (0.0.5) 294 | rubyzip (2.3.2) 295 | sawyer (0.9.2) 296 | addressable (>= 2.3.5) 297 | faraday (>= 0.17.3, < 3) 298 | security (0.1.5) 299 | signet (0.19.0) 300 | addressable (~> 2.8) 301 | faraday (>= 0.17.5, < 3.a) 302 | jwt (>= 1.5, < 3.0) 303 | multi_json (~> 1.10) 304 | simctl (1.6.10) 305 | CFPropertyList 306 | naturally 307 | slack-notifier (2.4.0) 308 | strscan (3.1.0) 309 | terminal-notifier (2.0.0) 310 | terminal-table (3.0.2) 311 | unicode-display_width (>= 1.1.1, < 3) 312 | thor (1.0.1) 313 | trailblazer-option (0.1.2) 314 | tty-cursor (0.7.1) 315 | tty-screen (0.8.2) 316 | tty-spinner (0.9.3) 317 | tty-cursor (~> 0.7) 318 | typhoeus (1.4.1) 319 | ethon (>= 0.9.0) 320 | tzinfo (2.0.6) 321 | concurrent-ruby (~> 1.0) 322 | uber (0.1.0) 323 | unicode-display_width (2.5.0) 324 | word_wrap (1.0.0) 325 | xcodeproj (1.24.0) 326 | CFPropertyList (>= 2.3.3, < 4.0) 327 | atomos (~> 0.1.3) 328 | claide (>= 1.0.2, < 2.0) 329 | colored2 (~> 3.1) 330 | nanaimo (~> 0.3.0) 331 | rexml (~> 3.2.4) 332 | xcov (1.8.1) 333 | fastlane (>= 2.141.0, < 3.0.0) 334 | multipart-post 335 | slack-notifier 336 | terminal-table 337 | xcodeproj 338 | xcresult (~> 0.2.0) 339 | xcpretty (0.3.0) 340 | rouge (~> 2.0.7) 341 | xcpretty-travis-formatter (1.0.1) 342 | xcpretty (~> 0.2, >= 0.0.7) 343 | xcresult (0.2.1) 344 | 345 | PLATFORMS 346 | ruby 347 | 348 | DEPENDENCIES 349 | cocoapods 350 | danger 351 | danger-changelog 352 | danger-commit_lint 353 | danger-swiftlint 354 | danger-xcov 355 | fastlane 356 | fastlane-plugin-changelog 357 | xcov 358 | 359 | BUNDLED WITH 360 | 2.5.14 361 | -------------------------------------------------------------------------------- /Source/Classes/CountryPickerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CountryPickerViewController.swift 3 | // Columbus 4 | // 5 | // Created by Stefan Herold on 22.06.18. 6 | // Copyright © 2023 Stefan Herold. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | #if os(iOS) && !targetEnvironment(simulator) 12 | import CoreTelephony 13 | #endif 14 | 15 | /// The CountryPickerViewController class uses a UITableView to display 16 | /// country names, flags and dialing codes. It is used to pick a country. 17 | public final class CountryPickerViewController: UIViewController { 18 | 19 | public typealias DidSelectCountry = (_ country: Country) -> Void 20 | 21 | /// The list of data displayed in the data source 22 | public static let countries = createCountries() 23 | 24 | /// The configuration for the country picker 25 | let config: Configurable 26 | /// The list of data displayed when the user enters a search term 27 | var filteredItems = CountryList() 28 | /// Returns all items or filtered items if filtering is currently active 29 | var items: CountryList { isFiltering ? filteredItems : Self.countries } 30 | /// The data source for the section indexing 31 | var itemsForSectionTitle = [String: [Country]]() 32 | /// The section index title cache 33 | var sectionTitles = [String]() 34 | /// Called by the CountryPicker after the user selects a country. 35 | let didSelectClosure: DidSelectCountry 36 | /// The currently picked iso country code 37 | let selectedCountryCode: String 38 | /// The controller managing the search bar placed in the navigation item 39 | let searchController = UISearchController(searchResultsController: nil) 40 | /// The tableview that displays the countries 41 | let table = UITableView(frame: .zero, style: .plain) 42 | /// Constrains the bottom margin of the tableview to screen or keyboard 43 | var tableViewBottomConstraint: NSLayoutConstraint! 44 | /// The index path of the currently focussed item 45 | var focussedIndexPath: IndexPath = IndexPath(row: 0, section: 0) { 46 | didSet { 47 | DispatchQueue.main.async { [weak self] in 48 | self?.setNeedsFocusUpdate() 49 | self?.updateFocusIfNeeded() 50 | } 51 | } 52 | } 53 | 54 | override public weak var preferredFocusedView: UIView? { 55 | 56 | print("\(focussedIndexPath.section), \(focussedIndexPath.row)") 57 | let cell = table.cellForRow(at: focussedIndexPath) 58 | return cell 59 | } 60 | 61 | /// The observer that informs about KeyboardDidShow notifications 62 | private var keyboardDidShowObserver: NSObjectProtocol? 63 | /// The observer that informs about KeyboardWillHide notifications 64 | private var keyboardWillHideObserver: NSObjectProtocol? 65 | 66 | // MARK: - Initialization 67 | 68 | public init(config: Configurable, 69 | initialCountryCode: String, 70 | didSelectClosure: @escaping DidSelectCountry) { 71 | self.config = config 72 | self.selectedCountryCode = initialCountryCode 73 | self.didSelectClosure = didSelectClosure 74 | super.init(nibName: nil, bundle: nil) 75 | } 76 | 77 | public init?(coder aDecoder: NSCoder, 78 | config: Configurable, 79 | initialCountryCode: String, 80 | didSelectClosure: @escaping DidSelectCountry) { 81 | self.config = config 82 | self.selectedCountryCode = initialCountryCode 83 | self.didSelectClosure = didSelectClosure 84 | super.init(coder: aDecoder) 85 | } 86 | 87 | @available(*, unavailable, message: "init(coder:) has not been implemented") 88 | required init?(coder aDecoder: NSCoder) { 89 | preconditionFailure("init(coder:) has not been implemented") 90 | } 91 | 92 | deinit { 93 | deinitObserver() 94 | } 95 | 96 | private func deinitObserver() { 97 | 98 | #if os(iOS) 99 | if let observer = keyboardDidShowObserver { 100 | NotificationCenter.default.removeObserver(observer) 101 | } 102 | 103 | if let observer = keyboardWillHideObserver { 104 | NotificationCenter.default.removeObserver(observer) 105 | } 106 | #endif 107 | } 108 | 109 | // MARK: - Setup UI 110 | 111 | override public func viewDidLoad() { 112 | 113 | super.viewDidLoad() 114 | 115 | view.backgroundColor = config.backgroundColor 116 | 117 | setupTable() 118 | #if os(iOS) 119 | setupSearchBar() 120 | #endif 121 | setupAutoLayout() 122 | 123 | reloadData() 124 | displaySelectedCountry() 125 | setupObserver() 126 | } 127 | 128 | public override func viewWillAppear(_ animated: Bool) { 129 | super.viewWillAppear(animated) 130 | 131 | // Font change here is needed since UISearchController seems a bit 132 | // broken. Setting that in viewDidLoad doesn't have any effect... 133 | // 134 | // Don't move that to viewDidAppear to not produce a visible change. 135 | #if os(iOS) 136 | if let placeholder = config.searchBarAttributedPlaceholder { 137 | searchController.searchBar.searchTextField.attributedPlaceholder = placeholder 138 | } 139 | 140 | if let textAttributes = config.searchTextAttributes { 141 | searchController.searchBar.searchTextField.typingAttributes = textAttributes 142 | searchController.searchBar.searchTextField.defaultTextAttributes = textAttributes 143 | } 144 | #endif 145 | } 146 | 147 | public override func viewDidAppear(_ animated: Bool) { 148 | super.viewDidAppear(animated) 149 | 150 | #if os(iOS) 151 | // https://stackoverflow.com/a/59996504/971329 152 | searchController.isActive = true 153 | #endif 154 | } 155 | 156 | private func setupObserver() { 157 | 158 | let center = NotificationCenter.default 159 | 160 | #if os(iOS) 161 | keyboardDidShowObserver = center.addObserver(forName: UIResponder.keyboardDidShowNotification, 162 | object: nil, 163 | queue: nil) { [weak self] (note) in 164 | 165 | guard let userInfo = note.userInfo, 166 | userInfo[UIResponder.keyboardIsLocalUserInfoKey] as? Bool == true, 167 | let frame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { 168 | return 169 | } 170 | self?.tableViewBottomConstraint.constant = -frame.height 171 | } 172 | 173 | keyboardWillHideObserver = center.addObserver(forName: UIResponder.keyboardWillHideNotification, 174 | object: nil, 175 | queue: nil) { [weak self] (note) in 176 | 177 | guard let userInfo = note.userInfo, userInfo[UIResponder.keyboardIsLocalUserInfoKey] as? Bool == true else { 178 | return 179 | } 180 | self?.tableViewBottomConstraint.constant = 0 181 | } 182 | #endif 183 | } 184 | 185 | private func setupTable() { 186 | table.translatesAutoresizingMaskIntoConstraints = false 187 | table.register(CountryCell.self, forCellReuseIdentifier: CountryCell.cellId) 188 | table.backgroundColor = config.backgroundColor 189 | table.dataSource = self 190 | table.delegate = self 191 | table.tintColor = config.controlColor 192 | table.tableFooterView = UIView() 193 | view.addSubview(table) 194 | } 195 | 196 | private func setupSearchBar() { 197 | #if os(iOS) 198 | searchController.delegate = self 199 | searchController.searchResultsUpdater = self 200 | searchController.automaticallyShowsCancelButton = false 201 | 202 | searchController.searchBar.tintColor = config.controlColor 203 | 204 | 205 | searchController.searchBar.searchTextField.textDragInteraction?.isEnabled = false 206 | searchController.searchBar.searchTextField.returnKeyType = .done 207 | searchController.searchBar.searchTextField.tintColor = config.controlColor 208 | searchController.searchBar.searchTextField.textColor = config.controlColor 209 | searchController.searchBar.searchTextField.delegate = self 210 | 211 | navigationItem.hidesSearchBarWhenScrolling = false 212 | navigationItem.searchController = searchController 213 | #endif 214 | } 215 | 216 | private func setupAutoLayout() { 217 | 218 | var constraints: [NSLayoutConstraint] = [] 219 | 220 | tableViewBottomConstraint = table.bottomAnchor.constraint(equalTo: view.bottomAnchor) 221 | tableViewBottomConstraint.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).tableView.bottom") 222 | constraints.append(tableViewBottomConstraint) 223 | 224 | let tableLeading = table.leadingAnchor.constraint(equalTo: view.leadingAnchor) 225 | tableLeading.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).tableView.leading") 226 | constraints.append(tableLeading) 227 | 228 | let tableTrailing = table.trailingAnchor.constraint(equalTo: view.trailingAnchor) 229 | tableTrailing.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).tableView.trailing") 230 | constraints.append(tableTrailing) 231 | 232 | let tableTop = table.topAnchor.constraint(equalTo: view.topAnchor) 233 | tableTop.identifier = ColumbusMain.layoutConstraintId("\(type(of: self)).tableView.top") 234 | constraints.append(tableTop) 235 | 236 | NSLayoutConstraint.activate(constraints) 237 | } 238 | 239 | // MARK: - Large Titles 240 | public func useLargeTitles(_ isOn: Bool) { 241 | #if os(iOS) 242 | searchController.hidesNavigationBarDuringPresentation = isOn ? true : false 243 | navigationItem.largeTitleDisplayMode = isOn ? .always : .never 244 | #endif 245 | } 246 | 247 | // MARK: - Country Handling 248 | 249 | /// Gives you the default country for your device using the following (ordered) approaches: 250 | /// 1. Trying to determine your country using the country you passed in via its two-letter ISO country code. This 251 | /// has precedence since from now it is only used for really forcing the country picker to return a specific 252 | /// country. 253 | /// 2. Trying to determine your country from your SIM card 254 | /// 3. Using `US` as fallback if the other approaches didn't work. 255 | public static func defaultCountry(from isoCountryCode: String? = nil) -> Country { 256 | 257 | // Fallback to United States 258 | 259 | let defaultCountry = countries.first { 260 | $0.isoCountryCode.compare("US", options: .caseInsensitive) == .orderedSame 261 | }! 262 | 263 | // Using the `isoCountryCode` parameter to force the picker to return a specific country. 264 | 265 | if 266 | let isoCountryCode = isoCountryCode, 267 | let country = (countries.first { $0.isoCountryCode.compare(isoCountryCode, options: .caseInsensitive) == .orderedSame }) { 268 | return country 269 | } 270 | 271 | // Core Telephony Approach 272 | 273 | #if os(iOS) && !targetEnvironment(simulator) 274 | 275 | // CTCarrier is deprecated from 16.4 and Locale region is used as fallback. 276 | // see: https://developer.apple.com/documentation/ios-ipados-release-notes/ios-ipados-16_4-release-notes#Deprecations 277 | 278 | var deviceIsoCountryCode: String? 279 | if #available(iOS 16.4, *) { 280 | deviceIsoCountryCode = Locale.current.language.region?.identifier 281 | } else { 282 | guard let cellularProviders = CTTelephonyNetworkInfo().serviceSubscriberCellularProviders else { 283 | return defaultCountry 284 | } 285 | let carriers = cellularProviders.map(\.value) 286 | deviceIsoCountryCode = carriers.compactMap(\.isoCountryCode).first?.uppercased() 287 | } 288 | 289 | guard let deviceIsoCountryCode, 290 | let country = (countries.first { $0.isoCountryCode.compare(deviceIsoCountryCode, options: .caseInsensitive) == .orderedSame }) else { 291 | return defaultCountry 292 | } 293 | return country 294 | #endif 295 | 296 | // Fallback to United States 297 | 298 | return defaultCountry 299 | } 300 | 301 | private static func createCountries() -> CountryList { 302 | 303 | guard 304 | let countriesFilePath = ColumbusMain.bundle.path(forResource: "Countries", ofType: "json"), 305 | let countriesData = FileManager.default.contents(atPath: countriesFilePath), 306 | let countries = try? JSONDecoder().decode(CountryList.self, from: countriesData) else { 307 | return CountryList() 308 | } 309 | return countries 310 | } 311 | 312 | // MARK: - Filtering 313 | 314 | /// Returns `true` if search controller is active and query is non-empty 315 | var isFiltering: Bool { 316 | searchController.isActive && searchController.searchBar.text?.isEmpty == false 317 | } 318 | 319 | func filterContentForSearchText(_ searchText: String?) { 320 | defer { 321 | reloadData() 322 | } 323 | guard let query = searchText?.lowercased(), !query.isEmpty else { 324 | filteredItems = Self.countries 325 | return 326 | } 327 | let filteredByName = Self.countries.filter { 328 | $0.name.lowercased().contains(query) 329 | } 330 | let filteredByDialingCode = Self.countries.filter { 331 | "+\($0.dialingCode)".contains(query) 332 | } 333 | 334 | if !filteredByName.isEmpty { 335 | filteredItems = CountryList(values: filteredByName) 336 | } else { 337 | filteredItems = CountryList(values: filteredByDialingCode) 338 | } 339 | } 340 | 341 | // MARK: Section Indices 342 | 343 | func updateSectionIndex() { 344 | 345 | itemsForSectionTitle = Dictionary(grouping: items) { String($0.name.prefix(1)) } 346 | sectionTitles = [String](itemsForSectionTitle.keys) 347 | sectionTitles = sectionTitles.sorted(by: <) 348 | } 349 | 350 | // MARK: - Date Reloading 351 | 352 | func reloadData() { 353 | 354 | updateSectionIndex() 355 | table.reloadData() 356 | } 357 | 358 | // MARK: Pre-select initial country 359 | 360 | func displaySelectedCountry() { 361 | 362 | DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) { [weak self] in 363 | guard let key = (self?.itemsForSectionTitle.first { $0.value.contains { $0.isoCountryCode == self?.selectedCountryCode } }?.key), 364 | let section = (self?.sectionTitles.firstIndex { $0 == key }), 365 | let row = (self?.itemsForSectionTitle[key]?.firstIndex { $0.isoCountryCode == self?.selectedCountryCode }) else { 366 | return 367 | } 368 | 369 | let indexPath = IndexPath(row: row, section: section) 370 | 371 | DispatchQueue.main.async { [weak self] in 372 | #if os(iOS) 373 | self?.table.selectRow(at: indexPath, animated: true, scrollPosition: .middle) 374 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in 375 | self?.table.deselectRow(at: indexPath, animated: true) 376 | } 377 | #elseif os(tvOS) 378 | self?.table.scrollToRow(at: indexPath, at: .middle, animated: true) 379 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in 380 | self?.focussedIndexPath = indexPath 381 | } 382 | #endif 383 | } 384 | } 385 | } 386 | } 387 | 388 | extension CountryPickerViewController: UITableViewDataSource { 389 | 390 | public func numberOfSections(in tableView: UITableView) -> Int { 391 | sectionTitles.count 392 | } 393 | 394 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 395 | let key = sectionTitles[section] 396 | return itemsForSectionTitle[key]?.count ?? 0 397 | } 398 | 399 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 400 | let cell = tableView.dequeueReusableCell(withIdentifier: CountryCell.cellId, for: indexPath) 401 | let raster = config.rasterSize 402 | let margins = NSDirectionalEdgeInsets(top: raster, leading: raster, bottom: raster, trailing: raster) 403 | 404 | if let cell = cell as? CountryCell { 405 | let key = sectionTitles[indexPath.section] 406 | let sectionItems = itemsForSectionTitle[key] 407 | let item = sectionItems?[indexPath.row] 408 | item.map { cell.configure(with: $0, config: config) } 409 | } 410 | 411 | cell.selectedBackgroundView?.backgroundColor = config.selectionColor 412 | cell.backgroundView?.backgroundColor = config.backgroundColor 413 | cell.backgroundColor = config.backgroundColor 414 | cell.contentView.directionalLayoutMargins = margins 415 | cell.contentView.preservesSuperviewLayoutMargins = false 416 | 417 | return cell 418 | } 419 | } 420 | 421 | extension CountryPickerViewController: UITableViewDelegate { 422 | 423 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 424 | tableView.deselectRow(at: indexPath, animated: true) 425 | let key = sectionTitles[indexPath.section] 426 | let sectionItems = itemsForSectionTitle[key] 427 | let item = sectionItems?[indexPath.row] 428 | item.map { didSelectClosure($0) } 429 | } 430 | 431 | public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 432 | sectionTitles[section] 433 | } 434 | 435 | public func sectionIndexTitles(for tableView: UITableView) -> [String]? { 436 | sectionTitles 437 | } 438 | 439 | public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 440 | 441 | // Adjusting the separator insets: http://stackoverflow.com/a/39005773/971329 442 | 443 | #if os(iOS) 444 | // setting separator inset 445 | cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude) 446 | #endif 447 | } 448 | } 449 | 450 | extension CountryPickerViewController: UISearchResultsUpdating { 451 | public func updateSearchResults(for searchController: UISearchController) { 452 | filterContentForSearchText(searchController.searchBar.text) 453 | } 454 | } 455 | 456 | // https://stackoverflow.com/a/59996504/971329 457 | extension CountryPickerViewController: UISearchControllerDelegate { 458 | public func presentSearchController(_ searchController: UISearchController) { 459 | DispatchQueue.main.async { [weak self] in 460 | self?.searchController.searchBar.becomeFirstResponder() 461 | } 462 | } 463 | } 464 | 465 | // https://stackoverflow.com/a/59996504/971329 466 | extension CountryPickerViewController: UITextFieldDelegate { 467 | public func textFieldShouldReturn(_ textField: UITextField) -> Bool { 468 | searchController.isActive = false 469 | return true 470 | } 471 | } 472 | -------------------------------------------------------------------------------- /Source/Resources/Countries.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Afghanistan", 4 | "dial_code": "+93", 5 | "code": "AF" 6 | }, 7 | { 8 | "name": "Aland Islands", 9 | "dial_code": "+358", 10 | "code": "AX" 11 | }, 12 | { 13 | "name": "Albania", 14 | "dial_code": "+355", 15 | "code": "AL" 16 | }, 17 | { 18 | "name": "Algeria", 19 | "dial_code": "+213", 20 | "code": "DZ" 21 | }, 22 | { 23 | "name": "AmericanSamoa", 24 | "dial_code": "+1684", 25 | "code": "AS" 26 | }, 27 | { 28 | "name": "Andorra", 29 | "dial_code": "+376", 30 | "code": "AD" 31 | }, 32 | { 33 | "name": "Angola", 34 | "dial_code": "+244", 35 | "code": "AO" 36 | }, 37 | { 38 | "name": "Anguilla", 39 | "dial_code": "+1264", 40 | "code": "AI" 41 | }, 42 | { 43 | "name": "Antarctica", 44 | "dial_code": "+672", 45 | "code": "AQ" 46 | }, 47 | { 48 | "name": "Antigua and Barbuda", 49 | "dial_code": "+1268", 50 | "code": "AG" 51 | }, 52 | { 53 | "name": "Argentina", 54 | "dial_code": "+54", 55 | "code": "AR" 56 | }, 57 | { 58 | "name": "Armenia", 59 | "dial_code": "+374", 60 | "code": "AM" 61 | }, 62 | { 63 | "name": "Aruba", 64 | "dial_code": "+297", 65 | "code": "AW" 66 | }, 67 | { 68 | "name": "Australia", 69 | "dial_code": "+61", 70 | "code": "AU" 71 | }, 72 | { 73 | "name": "Austria", 74 | "dial_code": "+43", 75 | "code": "AT" 76 | }, 77 | { 78 | "name": "Azerbaijan", 79 | "dial_code": "+994", 80 | "code": "AZ" 81 | }, 82 | { 83 | "name": "Bahamas", 84 | "dial_code": "+1242", 85 | "code": "BS" 86 | }, 87 | { 88 | "name": "Bahrain", 89 | "dial_code": "+973", 90 | "code": "BH" 91 | }, 92 | { 93 | "name": "Bangladesh", 94 | "dial_code": "+880", 95 | "code": "BD" 96 | }, 97 | { 98 | "name": "Barbados", 99 | "dial_code": "+1246", 100 | "code": "BB" 101 | }, 102 | { 103 | "name": "Belarus", 104 | "dial_code": "+375", 105 | "code": "BY" 106 | }, 107 | { 108 | "name": "Belgium", 109 | "dial_code": "+32", 110 | "code": "BE" 111 | }, 112 | { 113 | "name": "Belize", 114 | "dial_code": "+501", 115 | "code": "BZ" 116 | }, 117 | { 118 | "name": "Benin", 119 | "dial_code": "+229", 120 | "code": "BJ" 121 | }, 122 | { 123 | "name": "Bermuda", 124 | "dial_code": "+1441", 125 | "code": "BM" 126 | }, 127 | { 128 | "name": "Bhutan", 129 | "dial_code": "+975", 130 | "code": "BT" 131 | }, 132 | { 133 | "name": "Bolivia, Plurinational State of", 134 | "dial_code": "+591", 135 | "code": "BO" 136 | }, 137 | { 138 | "name": "Bosnia and Herzegovina", 139 | "dial_code": "+387", 140 | "code": "BA" 141 | }, 142 | { 143 | "name": "Botswana", 144 | "dial_code": "+267", 145 | "code": "BW" 146 | }, 147 | { 148 | "name": "Brazil", 149 | "dial_code": "+55", 150 | "code": "BR" 151 | }, 152 | { 153 | "name": "British Indian Ocean Territory", 154 | "dial_code": "+246", 155 | "code": "IO" 156 | }, 157 | { 158 | "name": "Brunei Darussalam", 159 | "dial_code": "+673", 160 | "code": "BN" 161 | }, 162 | { 163 | "name": "Bulgaria", 164 | "dial_code": "+359", 165 | "code": "BG" 166 | }, 167 | { 168 | "name": "Burkina Faso", 169 | "dial_code": "+226", 170 | "code": "BF" 171 | }, 172 | { 173 | "name": "Burundi", 174 | "dial_code": "+257", 175 | "code": "BI" 176 | }, 177 | { 178 | "name": "Cambodia", 179 | "dial_code": "+855", 180 | "code": "KH" 181 | }, 182 | { 183 | "name": "Cameroon", 184 | "dial_code": "+237", 185 | "code": "CM" 186 | }, 187 | { 188 | "name": "Canada", 189 | "dial_code": "+1", 190 | "code": "CA" 191 | }, 192 | { 193 | "name": "Cape Verde", 194 | "dial_code": "+238", 195 | "code": "CV" 196 | }, 197 | { 198 | "name": "Cayman Islands", 199 | "dial_code": "+ 345", 200 | "code": "KY" 201 | }, 202 | { 203 | "name": "Central African Republic", 204 | "dial_code": "+236", 205 | "code": "CF" 206 | }, 207 | { 208 | "name": "Chad", 209 | "dial_code": "+235", 210 | "code": "TD" 211 | }, 212 | { 213 | "name": "Chile", 214 | "dial_code": "+56", 215 | "code": "CL" 216 | }, 217 | { 218 | "name": "China", 219 | "dial_code": "+86", 220 | "code": "CN" 221 | }, 222 | { 223 | "name": "Christmas Island", 224 | "dial_code": "+61", 225 | "code": "CX" 226 | }, 227 | { 228 | "name": "Cocos (Keeling) Islands", 229 | "dial_code": "+61", 230 | "code": "CC" 231 | }, 232 | { 233 | "name": "Colombia", 234 | "dial_code": "+57", 235 | "code": "CO" 236 | }, 237 | { 238 | "name": "Comoros", 239 | "dial_code": "+269", 240 | "code": "KM" 241 | }, 242 | { 243 | "name": "Congo", 244 | "dial_code": "+242", 245 | "code": "CG" 246 | }, 247 | { 248 | "name": "Congo, The Democratic Republic of the Congo", 249 | "dial_code": "+243", 250 | "code": "CD" 251 | }, 252 | { 253 | "name": "Cook Islands", 254 | "dial_code": "+682", 255 | "code": "CK" 256 | }, 257 | { 258 | "name": "Costa Rica", 259 | "dial_code": "+506", 260 | "code": "CR" 261 | }, 262 | { 263 | "name": "Cote d'Ivoire", 264 | "dial_code": "+225", 265 | "code": "CI" 266 | }, 267 | { 268 | "name": "Croatia", 269 | "dial_code": "+385", 270 | "code": "HR" 271 | }, 272 | { 273 | "name": "Cuba", 274 | "dial_code": "+53", 275 | "code": "CU" 276 | }, 277 | { 278 | "name": "Cyprus", 279 | "dial_code": "+357", 280 | "code": "CY" 281 | }, 282 | { 283 | "name": "Czech Republic", 284 | "dial_code": "+420", 285 | "code": "CZ" 286 | }, 287 | { 288 | "name": "Denmark", 289 | "dial_code": "+45", 290 | "code": "DK" 291 | }, 292 | { 293 | "name": "Djibouti", 294 | "dial_code": "+253", 295 | "code": "DJ" 296 | }, 297 | { 298 | "name": "Dominica", 299 | "dial_code": "+1767", 300 | "code": "DM" 301 | }, 302 | { 303 | "name": "Dominican Republic", 304 | "dial_code": "+1849", 305 | "code": "DO" 306 | }, 307 | { 308 | "name": "Ecuador", 309 | "dial_code": "+593", 310 | "code": "EC" 311 | }, 312 | { 313 | "name": "Egypt", 314 | "dial_code": "+20", 315 | "code": "EG" 316 | }, 317 | { 318 | "name": "El Salvador", 319 | "dial_code": "+503", 320 | "code": "SV" 321 | }, 322 | { 323 | "name": "Equatorial Guinea", 324 | "dial_code": "+240", 325 | "code": "GQ" 326 | }, 327 | { 328 | "name": "Eritrea", 329 | "dial_code": "+291", 330 | "code": "ER" 331 | }, 332 | { 333 | "name": "Estonia", 334 | "dial_code": "+372", 335 | "code": "EE" 336 | }, 337 | { 338 | "name": "Ethiopia", 339 | "dial_code": "+251", 340 | "code": "ET" 341 | }, 342 | { 343 | "name": "Falkland Islands (Malvinas)", 344 | "dial_code": "+500", 345 | "code": "FK" 346 | }, 347 | { 348 | "name": "Faroe Islands", 349 | "dial_code": "+298", 350 | "code": "FO" 351 | }, 352 | { 353 | "name": "Fiji", 354 | "dial_code": "+679", 355 | "code": "FJ" 356 | }, 357 | { 358 | "name": "Finland", 359 | "dial_code": "+358", 360 | "code": "FI" 361 | }, 362 | { 363 | "name": "France", 364 | "dial_code": "+33", 365 | "code": "FR" 366 | }, 367 | { 368 | "name": "French Guiana", 369 | "dial_code": "+594", 370 | "code": "GF" 371 | }, 372 | { 373 | "name": "French Polynesia", 374 | "dial_code": "+689", 375 | "code": "PF" 376 | }, 377 | { 378 | "name": "Gabon", 379 | "dial_code": "+241", 380 | "code": "GA" 381 | }, 382 | { 383 | "name": "Gambia", 384 | "dial_code": "+220", 385 | "code": "GM" 386 | }, 387 | { 388 | "name": "Georgia", 389 | "dial_code": "+995", 390 | "code": "GE" 391 | }, 392 | { 393 | "name": "Germany", 394 | "dial_code": "+49", 395 | "code": "DE" 396 | }, 397 | { 398 | "name": "Ghana", 399 | "dial_code": "+233", 400 | "code": "GH" 401 | }, 402 | { 403 | "name": "Gibraltar", 404 | "dial_code": "+350", 405 | "code": "GI" 406 | }, 407 | { 408 | "name": "Greece", 409 | "dial_code": "+30", 410 | "code": "GR" 411 | }, 412 | { 413 | "name": "Greenland", 414 | "dial_code": "+299", 415 | "code": "GL" 416 | }, 417 | { 418 | "name": "Grenada", 419 | "dial_code": "+1473", 420 | "code": "GD" 421 | }, 422 | { 423 | "name": "Guadeloupe", 424 | "dial_code": "+590", 425 | "code": "GP" 426 | }, 427 | { 428 | "name": "Guam", 429 | "dial_code": "+1671", 430 | "code": "GU" 431 | }, 432 | { 433 | "name": "Guatemala", 434 | "dial_code": "+502", 435 | "code": "GT" 436 | }, 437 | { 438 | "name": "Guernsey", 439 | "dial_code": "+44", 440 | "code": "GG" 441 | }, 442 | { 443 | "name": "Guinea", 444 | "dial_code": "+224", 445 | "code": "GN" 446 | }, 447 | { 448 | "name": "Guinea-Bissau", 449 | "dial_code": "+245", 450 | "code": "GW" 451 | }, 452 | { 453 | "name": "Guyana", 454 | "dial_code": "+595", 455 | "code": "GY" 456 | }, 457 | { 458 | "name": "Haiti", 459 | "dial_code": "+509", 460 | "code": "HT" 461 | }, 462 | { 463 | "name": "Holy See (Vatican City State)", 464 | "dial_code": "+379", 465 | "code": "VA" 466 | }, 467 | { 468 | "name": "Honduras", 469 | "dial_code": "+504", 470 | "code": "HN" 471 | }, 472 | { 473 | "name": "Hong Kong", 474 | "dial_code": "+852", 475 | "code": "HK" 476 | }, 477 | { 478 | "name": "Hungary", 479 | "dial_code": "+36", 480 | "code": "HU" 481 | }, 482 | { 483 | "name": "Iceland", 484 | "dial_code": "+354", 485 | "code": "IS" 486 | }, 487 | { 488 | "name": "India", 489 | "dial_code": "+91", 490 | "code": "IN" 491 | }, 492 | { 493 | "name": "Indonesia", 494 | "dial_code": "+62", 495 | "code": "ID" 496 | }, 497 | { 498 | "name": "Iran, Islamic Republic of Persian Gulf", 499 | "dial_code": "+98", 500 | "code": "IR" 501 | }, 502 | { 503 | "name": "Iraq", 504 | "dial_code": "+964", 505 | "code": "IQ" 506 | }, 507 | { 508 | "name": "Ireland", 509 | "dial_code": "+353", 510 | "code": "IE" 511 | }, 512 | { 513 | "name": "Isle of Man", 514 | "dial_code": "+44", 515 | "code": "IM" 516 | }, 517 | { 518 | "name": "Israel", 519 | "dial_code": "+972", 520 | "code": "IL" 521 | }, 522 | { 523 | "name": "Italy", 524 | "dial_code": "+39", 525 | "code": "IT" 526 | }, 527 | { 528 | "name": "Jamaica", 529 | "dial_code": "+1876", 530 | "code": "JM" 531 | }, 532 | { 533 | "name": "Japan", 534 | "dial_code": "+81", 535 | "code": "JP" 536 | }, 537 | { 538 | "name": "Jersey", 539 | "dial_code": "+44", 540 | "code": "JE" 541 | }, 542 | { 543 | "name": "Jordan", 544 | "dial_code": "+962", 545 | "code": "JO" 546 | }, 547 | { 548 | "name": "Kazakhstan", 549 | "dial_code": "+77", 550 | "code": "KZ" 551 | }, 552 | { 553 | "name": "Kenya", 554 | "dial_code": "+254", 555 | "code": "KE" 556 | }, 557 | { 558 | "name": "Kiribati", 559 | "dial_code": "+686", 560 | "code": "KI" 561 | }, 562 | { 563 | "name": "Korea, Democratic People's Republic of Korea", 564 | "dial_code": "+850", 565 | "code": "KP" 566 | }, 567 | { 568 | "name": "Korea, Republic of South Korea", 569 | "dial_code": "+82", 570 | "code": "KR" 571 | }, 572 | { 573 | "name": "Kuwait", 574 | "dial_code": "+965", 575 | "code": "KW" 576 | }, 577 | { 578 | "name": "Kyrgyzstan", 579 | "dial_code": "+996", 580 | "code": "KG" 581 | }, 582 | { 583 | "name": "Laos", 584 | "dial_code": "+856", 585 | "code": "LA" 586 | }, 587 | { 588 | "name": "Latvia", 589 | "dial_code": "+371", 590 | "code": "LV" 591 | }, 592 | { 593 | "name": "Lebanon", 594 | "dial_code": "+961", 595 | "code": "LB" 596 | }, 597 | { 598 | "name": "Lesotho", 599 | "dial_code": "+266", 600 | "code": "LS" 601 | }, 602 | { 603 | "name": "Liberia", 604 | "dial_code": "+231", 605 | "code": "LR" 606 | }, 607 | { 608 | "name": "Libyan Arab Jamahiriya", 609 | "dial_code": "+218", 610 | "code": "LY" 611 | }, 612 | { 613 | "name": "Liechtenstein", 614 | "dial_code": "+423", 615 | "code": "LI" 616 | }, 617 | { 618 | "name": "Lithuania", 619 | "dial_code": "+370", 620 | "code": "LT" 621 | }, 622 | { 623 | "name": "Luxembourg", 624 | "dial_code": "+352", 625 | "code": "LU" 626 | }, 627 | { 628 | "name": "Macao", 629 | "dial_code": "+853", 630 | "code": "MO" 631 | }, 632 | { 633 | "name": "Macedonia", 634 | "dial_code": "+389", 635 | "code": "MK" 636 | }, 637 | { 638 | "name": "Madagascar", 639 | "dial_code": "+261", 640 | "code": "MG" 641 | }, 642 | { 643 | "name": "Malawi", 644 | "dial_code": "+265", 645 | "code": "MW" 646 | }, 647 | { 648 | "name": "Malaysia", 649 | "dial_code": "+60", 650 | "code": "MY" 651 | }, 652 | { 653 | "name": "Maldives", 654 | "dial_code": "+960", 655 | "code": "MV" 656 | }, 657 | { 658 | "name": "Mali", 659 | "dial_code": "+223", 660 | "code": "ML" 661 | }, 662 | { 663 | "name": "Malta", 664 | "dial_code": "+356", 665 | "code": "MT" 666 | }, 667 | { 668 | "name": "Marshall Islands", 669 | "dial_code": "+692", 670 | "code": "MH" 671 | }, 672 | { 673 | "name": "Martinique", 674 | "dial_code": "+596", 675 | "code": "MQ" 676 | }, 677 | { 678 | "name": "Mauritania", 679 | "dial_code": "+222", 680 | "code": "MR" 681 | }, 682 | { 683 | "name": "Mauritius", 684 | "dial_code": "+230", 685 | "code": "MU" 686 | }, 687 | { 688 | "name": "Mayotte", 689 | "dial_code": "+262", 690 | "code": "YT" 691 | }, 692 | { 693 | "name": "Mexico", 694 | "dial_code": "+52", 695 | "code": "MX" 696 | }, 697 | { 698 | "name": "Micronesia, Federated States of Micronesia", 699 | "dial_code": "+691", 700 | "code": "FM" 701 | }, 702 | { 703 | "name": "Moldova", 704 | "dial_code": "+373", 705 | "code": "MD" 706 | }, 707 | { 708 | "name": "Monaco", 709 | "dial_code": "+377", 710 | "code": "MC" 711 | }, 712 | { 713 | "name": "Mongolia", 714 | "dial_code": "+976", 715 | "code": "MN" 716 | }, 717 | { 718 | "name": "Montenegro", 719 | "dial_code": "+382", 720 | "code": "ME" 721 | }, 722 | { 723 | "name": "Montserrat", 724 | "dial_code": "+1664", 725 | "code": "MS" 726 | }, 727 | { 728 | "name": "Morocco", 729 | "dial_code": "+212", 730 | "code": "MA" 731 | }, 732 | { 733 | "name": "Mozambique", 734 | "dial_code": "+258", 735 | "code": "MZ" 736 | }, 737 | { 738 | "name": "Myanmar", 739 | "dial_code": "+95", 740 | "code": "MM" 741 | }, 742 | { 743 | "name": "Namibia", 744 | "dial_code": "+264", 745 | "code": "NA" 746 | }, 747 | { 748 | "name": "Nauru", 749 | "dial_code": "+674", 750 | "code": "NR" 751 | }, 752 | { 753 | "name": "Nepal", 754 | "dial_code": "+977", 755 | "code": "NP" 756 | }, 757 | { 758 | "name": "Netherlands", 759 | "dial_code": "+31", 760 | "code": "NL" 761 | }, 762 | { 763 | "name": "New Caledonia", 764 | "dial_code": "+687", 765 | "code": "NC" 766 | }, 767 | { 768 | "name": "New Zealand", 769 | "dial_code": "+64", 770 | "code": "NZ" 771 | }, 772 | { 773 | "name": "Nicaragua", 774 | "dial_code": "+505", 775 | "code": "NI" 776 | }, 777 | { 778 | "name": "Niger", 779 | "dial_code": "+227", 780 | "code": "NE" 781 | }, 782 | { 783 | "name": "Nigeria", 784 | "dial_code": "+234", 785 | "code": "NG" 786 | }, 787 | { 788 | "name": "Niue", 789 | "dial_code": "+683", 790 | "code": "NU" 791 | }, 792 | { 793 | "name": "Norfolk Island", 794 | "dial_code": "+672", 795 | "code": "NF" 796 | }, 797 | { 798 | "name": "Northern Mariana Islands", 799 | "dial_code": "+1670", 800 | "code": "MP" 801 | }, 802 | { 803 | "name": "Norway", 804 | "dial_code": "+47", 805 | "code": "NO" 806 | }, 807 | { 808 | "name": "Oman", 809 | "dial_code": "+968", 810 | "code": "OM" 811 | }, 812 | { 813 | "name": "Pakistan", 814 | "dial_code": "+92", 815 | "code": "PK" 816 | }, 817 | { 818 | "name": "Palau", 819 | "dial_code": "+680", 820 | "code": "PW" 821 | }, 822 | { 823 | "name": "Palestinian Territory, Occupied", 824 | "dial_code": "+970", 825 | "code": "PS" 826 | }, 827 | { 828 | "name": "Panama", 829 | "dial_code": "+507", 830 | "code": "PA" 831 | }, 832 | { 833 | "name": "Papua New Guinea", 834 | "dial_code": "+675", 835 | "code": "PG" 836 | }, 837 | { 838 | "name": "Paraguay", 839 | "dial_code": "+595", 840 | "code": "PY" 841 | }, 842 | { 843 | "name": "Peru", 844 | "dial_code": "+51", 845 | "code": "PE" 846 | }, 847 | { 848 | "name": "Philippines", 849 | "dial_code": "+63", 850 | "code": "PH" 851 | }, 852 | { 853 | "name": "Pitcairn", 854 | "dial_code": "+872", 855 | "code": "PN" 856 | }, 857 | { 858 | "name": "Poland", 859 | "dial_code": "+48", 860 | "code": "PL" 861 | }, 862 | { 863 | "name": "Portugal", 864 | "dial_code": "+351", 865 | "code": "PT" 866 | }, 867 | { 868 | "name": "Puerto Rico", 869 | "dial_code": "+1939", 870 | "code": "PR" 871 | }, 872 | { 873 | "name": "Qatar", 874 | "dial_code": "+974", 875 | "code": "QA" 876 | }, 877 | { 878 | "name": "Romania", 879 | "dial_code": "+40", 880 | "code": "RO" 881 | }, 882 | { 883 | "name": "Russia", 884 | "dial_code": "+7", 885 | "code": "RU" 886 | }, 887 | { 888 | "name": "Rwanda", 889 | "dial_code": "+250", 890 | "code": "RW" 891 | }, 892 | { 893 | "name": "Reunion", 894 | "dial_code": "+262", 895 | "code": "RE" 896 | }, 897 | { 898 | "name": "Saint Barthelemy", 899 | "dial_code": "+590", 900 | "code": "BL" 901 | }, 902 | { 903 | "name": "Saint Helena, Ascension and Tristan Da Cunha", 904 | "dial_code": "+290", 905 | "code": "SH" 906 | }, 907 | { 908 | "name": "Saint Kitts and Nevis", 909 | "dial_code": "+1869", 910 | "code": "KN" 911 | }, 912 | { 913 | "name": "Saint Lucia", 914 | "dial_code": "+1758", 915 | "code": "LC" 916 | }, 917 | { 918 | "name": "Saint Martin", 919 | "dial_code": "+590", 920 | "code": "MF" 921 | }, 922 | { 923 | "name": "Saint Pierre and Miquelon", 924 | "dial_code": "+508", 925 | "code": "PM" 926 | }, 927 | { 928 | "name": "Saint Vincent and the Grenadines", 929 | "dial_code": "+1784", 930 | "code": "VC" 931 | }, 932 | { 933 | "name": "Samoa", 934 | "dial_code": "+685", 935 | "code": "WS" 936 | }, 937 | { 938 | "name": "San Marino", 939 | "dial_code": "+378", 940 | "code": "SM" 941 | }, 942 | { 943 | "name": "Sao Tome and Principe", 944 | "dial_code": "+239", 945 | "code": "ST" 946 | }, 947 | { 948 | "name": "Saudi Arabia", 949 | "dial_code": "+966", 950 | "code": "SA" 951 | }, 952 | { 953 | "name": "Senegal", 954 | "dial_code": "+221", 955 | "code": "SN" 956 | }, 957 | { 958 | "name": "Serbia", 959 | "dial_code": "+381", 960 | "code": "RS" 961 | }, 962 | { 963 | "name": "Seychelles", 964 | "dial_code": "+248", 965 | "code": "SC" 966 | }, 967 | { 968 | "name": "Sierra Leone", 969 | "dial_code": "+232", 970 | "code": "SL" 971 | }, 972 | { 973 | "name": "Singapore", 974 | "dial_code": "+65", 975 | "code": "SG" 976 | }, 977 | { 978 | "name": "Slovakia", 979 | "dial_code": "+421", 980 | "code": "SK" 981 | }, 982 | { 983 | "name": "Slovenia", 984 | "dial_code": "+386", 985 | "code": "SI" 986 | }, 987 | { 988 | "name": "Solomon Islands", 989 | "dial_code": "+677", 990 | "code": "SB" 991 | }, 992 | { 993 | "name": "Somalia", 994 | "dial_code": "+252", 995 | "code": "SO" 996 | }, 997 | { 998 | "name": "South Africa", 999 | "dial_code": "+27", 1000 | "code": "ZA" 1001 | }, 1002 | { 1003 | "name": "South Sudan", 1004 | "dial_code": "+211", 1005 | "code": "SS" 1006 | }, 1007 | { 1008 | "name": "South Georgia and the South Sandwich Islands", 1009 | "dial_code": "+500", 1010 | "code": "GS" 1011 | }, 1012 | { 1013 | "name": "Spain", 1014 | "dial_code": "+34", 1015 | "code": "ES" 1016 | }, 1017 | { 1018 | "name": "Sri Lanka", 1019 | "dial_code": "+94", 1020 | "code": "LK" 1021 | }, 1022 | { 1023 | "name": "Sudan", 1024 | "dial_code": "+249", 1025 | "code": "SD" 1026 | }, 1027 | { 1028 | "name": "Suriname", 1029 | "dial_code": "+597", 1030 | "code": "SR" 1031 | }, 1032 | { 1033 | "name": "Svalbard and Jan Mayen", 1034 | "dial_code": "+47", 1035 | "code": "SJ" 1036 | }, 1037 | { 1038 | "name": "Swaziland", 1039 | "dial_code": "+268", 1040 | "code": "SZ" 1041 | }, 1042 | { 1043 | "name": "Sweden", 1044 | "dial_code": "+46", 1045 | "code": "SE" 1046 | }, 1047 | { 1048 | "name": "Switzerland", 1049 | "dial_code": "+41", 1050 | "code": "CH" 1051 | }, 1052 | { 1053 | "name": "Syrian Arab Republic", 1054 | "dial_code": "+963", 1055 | "code": "SY" 1056 | }, 1057 | { 1058 | "name": "Taiwan", 1059 | "dial_code": "+886", 1060 | "code": "TW" 1061 | }, 1062 | { 1063 | "name": "Tajikistan", 1064 | "dial_code": "+992", 1065 | "code": "TJ" 1066 | }, 1067 | { 1068 | "name": "Tanzania, United Republic of Tanzania", 1069 | "dial_code": "+255", 1070 | "code": "TZ" 1071 | }, 1072 | { 1073 | "name": "Thailand", 1074 | "dial_code": "+66", 1075 | "code": "TH" 1076 | }, 1077 | { 1078 | "name": "Timor-Leste", 1079 | "dial_code": "+670", 1080 | "code": "TL" 1081 | }, 1082 | { 1083 | "name": "Togo", 1084 | "dial_code": "+228", 1085 | "code": "TG" 1086 | }, 1087 | { 1088 | "name": "Tokelau", 1089 | "dial_code": "+690", 1090 | "code": "TK" 1091 | }, 1092 | { 1093 | "name": "Tonga", 1094 | "dial_code": "+676", 1095 | "code": "TO" 1096 | }, 1097 | { 1098 | "name": "Trinidad and Tobago", 1099 | "dial_code": "+1868", 1100 | "code": "TT" 1101 | }, 1102 | { 1103 | "name": "Tunisia", 1104 | "dial_code": "+216", 1105 | "code": "TN" 1106 | }, 1107 | { 1108 | "name": "Turkey", 1109 | "dial_code": "+90", 1110 | "code": "TR" 1111 | }, 1112 | { 1113 | "name": "Turkmenistan", 1114 | "dial_code": "+993", 1115 | "code": "TM" 1116 | }, 1117 | { 1118 | "name": "Turks and Caicos Islands", 1119 | "dial_code": "+1649", 1120 | "code": "TC" 1121 | }, 1122 | { 1123 | "name": "Tuvalu", 1124 | "dial_code": "+688", 1125 | "code": "TV" 1126 | }, 1127 | { 1128 | "name": "Uganda", 1129 | "dial_code": "+256", 1130 | "code": "UG" 1131 | }, 1132 | { 1133 | "name": "Ukraine", 1134 | "dial_code": "+380", 1135 | "code": "UA" 1136 | }, 1137 | { 1138 | "name": "United Arab Emirates", 1139 | "dial_code": "+971", 1140 | "code": "AE" 1141 | }, 1142 | { 1143 | "name": "United Kingdom", 1144 | "dial_code": "+44", 1145 | "code": "GB" 1146 | }, 1147 | { 1148 | "name": "United States", 1149 | "dial_code": "+1", 1150 | "code": "US" 1151 | }, 1152 | { 1153 | "name": "Uruguay", 1154 | "dial_code": "+598", 1155 | "code": "UY" 1156 | }, 1157 | { 1158 | "name": "Uzbekistan", 1159 | "dial_code": "+998", 1160 | "code": "UZ" 1161 | }, 1162 | { 1163 | "name": "Vanuatu", 1164 | "dial_code": "+678", 1165 | "code": "VU" 1166 | }, 1167 | { 1168 | "name": "Venezuela, Bolivarian Republic of Venezuela", 1169 | "dial_code": "+58", 1170 | "code": "VE" 1171 | }, 1172 | { 1173 | "name": "Vietnam", 1174 | "dial_code": "+84", 1175 | "code": "VN" 1176 | }, 1177 | { 1178 | "name": "Virgin Islands, British", 1179 | "dial_code": "+1284", 1180 | "code": "VG" 1181 | }, 1182 | { 1183 | "name": "Virgin Islands, U.S.", 1184 | "dial_code": "+1340", 1185 | "code": "VI" 1186 | }, 1187 | { 1188 | "name": "Wallis and Futuna", 1189 | "dial_code": "+681", 1190 | "code": "WF" 1191 | }, 1192 | { 1193 | "name": "Yemen", 1194 | "dial_code": "+967", 1195 | "code": "YE" 1196 | }, 1197 | { 1198 | "name": "Zambia", 1199 | "dial_code": "+260", 1200 | "code": "ZM" 1201 | }, 1202 | { 1203 | "name": "Zimbabwe", 1204 | "dial_code": "+263", 1205 | "code": "ZW" 1206 | } 1207 | ] 1208 | -------------------------------------------------------------------------------- /Example/ColumbusExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B933821325CDF99400618FFD /* CountryPickerStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B933821225CDF99400618FFD /* CountryPickerStoryboard.storyboard */; }; 11 | B93D76DE23E4711B00E41863 /* Columbus.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9F8797221CD36B400273F82 /* Columbus.framework */; }; 12 | B93D76DF23E4711B00E41863 /* Columbus.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B9F8797221CD36B400273F82 /* Columbus.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 13 | B93D76E123E4712000E41863 /* Columbus.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B94B1B0C21CD394500FF1B72 /* Columbus.framework */; }; 14 | B93D76E223E4712000E41863 /* Columbus.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B94B1B0C21CD394500FF1B72 /* Columbus.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 15 | B93D76EF23E4A80900E41863 /* UIColor+SemanticColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D76EA23E4A80900E41863 /* UIColor+SemanticColors.swift */; }; 16 | B93D76F023E4A80900E41863 /* UIColor+SemanticColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D76EA23E4A80900E41863 /* UIColor+SemanticColors.swift */; }; 17 | B9F8790021CD2D7F00273F82 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9C8326021C84F3D0008ED90 /* AppDelegate.swift */; }; 18 | B9F8790221CD2D8400273F82 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B9F878C921CD2CF500273F82 /* Images.xcassets */; }; 19 | B9F8790421CD2D9800273F82 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9F878D221CD2CFE00273F82 /* LaunchScreen.storyboard */; }; 20 | B9F8791A21CD2DEB00273F82 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B9F878CE21CD2CFA00273F82 /* Images.xcassets */; }; 21 | B9F8791B21CD2DEF00273F82 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9C8326021C84F3D0008ED90 /* AppDelegate.swift */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | B94B1B0B21CD394500FF1B72 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 28 | proxyType = 2; 29 | remoteGlobalIDString = B94B1B0621CD38B400FF1B72; 30 | remoteInfo = "Columbus-tvOS"; 31 | }; 32 | B94B1B0D21CD394700FF1B72 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 35 | proxyType = 1; 36 | remoteGlobalIDString = B94B1AF421CD38B400FF1B72; 37 | remoteInfo = "Columbus-tvOS"; 38 | }; 39 | B94B1B2521CD3BEC00FF1B72 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 42 | proxyType = 1; 43 | remoteGlobalIDString = B9F8788221CD28A200273F82; 44 | remoteInfo = "Columbus-iOS"; 45 | }; 46 | B9693323228B54FF0002B855 /* PBXContainerItemProxy */ = { 47 | isa = PBXContainerItemProxy; 48 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 49 | proxyType = 2; 50 | remoteGlobalIDString = B9A4A67821D145EB001FF5DC; 51 | remoteInfo = "Resources-tvOS"; 52 | }; 53 | B96D498221CD3ED00010E69B /* PBXContainerItemProxy */ = { 54 | isa = PBXContainerItemProxy; 55 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 56 | proxyType = 2; 57 | remoteGlobalIDString = B96D496221CD3DC20010E69B; 58 | remoteInfo = "Resources-iOS"; 59 | }; 60 | B9A4A66021D0FC94001FF5DC /* PBXContainerItemProxy */ = { 61 | isa = PBXContainerItemProxy; 62 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 63 | proxyType = 2; 64 | remoteGlobalIDString = B9DB81FC21D0E9F500A39677; 65 | remoteInfo = "Columbus-tvOS-Tests"; 66 | }; 67 | B9F8797121CD36B400273F82 /* PBXContainerItemProxy */ = { 68 | isa = PBXContainerItemProxy; 69 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 70 | proxyType = 2; 71 | remoteGlobalIDString = B9F8788321CD28A200273F82; 72 | remoteInfo = Columbus; 73 | }; 74 | B9F8797321CD36B400273F82 /* PBXContainerItemProxy */ = { 75 | isa = PBXContainerItemProxy; 76 | containerPortal = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 77 | proxyType = 2; 78 | remoteGlobalIDString = B9F878AC21CD2A4D00273F82; 79 | remoteInfo = ColumbusTests; 80 | }; 81 | /* End PBXContainerItemProxy section */ 82 | 83 | /* Begin PBXCopyFilesBuildPhase section */ 84 | B93D76E023E4711B00E41863 /* Embed Frameworks */ = { 85 | isa = PBXCopyFilesBuildPhase; 86 | buildActionMask = 2147483647; 87 | dstPath = ""; 88 | dstSubfolderSpec = 10; 89 | files = ( 90 | B93D76DF23E4711B00E41863 /* Columbus.framework in Embed Frameworks */, 91 | ); 92 | name = "Embed Frameworks"; 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | B93D76E323E4712100E41863 /* Embed Frameworks */ = { 96 | isa = PBXCopyFilesBuildPhase; 97 | buildActionMask = 2147483647; 98 | dstPath = ""; 99 | dstSubfolderSpec = 10; 100 | files = ( 101 | B93D76E223E4712000E41863 /* Columbus.framework in Embed Frameworks */, 102 | ); 103 | name = "Embed Frameworks"; 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXCopyFilesBuildPhase section */ 107 | 108 | /* Begin PBXFileReference section */ 109 | B933821225CDF99400618FFD /* CountryPickerStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = CountryPickerStoryboard.storyboard; sourceTree = ""; }; 110 | B93D76EA23E4A80900E41863 /* UIColor+SemanticColors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+SemanticColors.swift"; sourceTree = ""; }; 111 | B9C8326021C84F3D0008ED90 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 112 | B9F878C921CD2CF500273F82 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 113 | B9F878CA21CD2CF500273F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 114 | B9F878CE21CD2CFA00273F82 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 115 | B9F878CF21CD2CFA00273F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 116 | B9F878D221CD2CFE00273F82 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 117 | B9F878D821CD2D5A00273F82 /* Columbus_iOS_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Columbus_iOS_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 118 | B9F8790A21CD2DDA00273F82 /* Columbus_tvOS_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Columbus_tvOS_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 119 | B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Columbus.xcodeproj; path = ../Columbus.xcodeproj; sourceTree = ""; }; 120 | /* End PBXFileReference section */ 121 | 122 | /* Begin PBXFrameworksBuildPhase section */ 123 | B9F878D521CD2D5A00273F82 /* Frameworks */ = { 124 | isa = PBXFrameworksBuildPhase; 125 | buildActionMask = 2147483647; 126 | files = ( 127 | B93D76DE23E4711B00E41863 /* Columbus.framework in Frameworks */, 128 | ); 129 | runOnlyForDeploymentPostprocessing = 0; 130 | }; 131 | B9F8790721CD2DDA00273F82 /* Frameworks */ = { 132 | isa = PBXFrameworksBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | B93D76E123E4712000E41863 /* Columbus.framework in Frameworks */, 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | /* End PBXFrameworksBuildPhase section */ 140 | 141 | /* Begin PBXGroup section */ 142 | B9C8325421C84F3D0008ED90 = { 143 | isa = PBXGroup; 144 | children = ( 145 | B9F8797B21CD373200273F82 /* Frameworks */, 146 | B9C8325E21C84F3D0008ED90 /* Products */, 147 | B9C8325F21C84F3D0008ED90 /* Source */, 148 | B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */, 149 | ); 150 | sourceTree = ""; 151 | }; 152 | B9C8325E21C84F3D0008ED90 /* Products */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | B9F878D821CD2D5A00273F82 /* Columbus_iOS_Example.app */, 156 | B9F8790A21CD2DDA00273F82 /* Columbus_tvOS_Example.app */, 157 | ); 158 | name = Products; 159 | sourceTree = ""; 160 | }; 161 | B9C8325F21C84F3D0008ED90 /* Source */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | B933821225CDF99400618FFD /* CountryPickerStoryboard.storyboard */, 165 | B9F878D221CD2CFE00273F82 /* LaunchScreen.storyboard */, 166 | B9C8326021C84F3D0008ED90 /* AppDelegate.swift */, 167 | B93D76EA23E4A80900E41863 /* UIColor+SemanticColors.swift */, 168 | B9F878C821CD2CF500273F82 /* iOS */, 169 | B9F878CD21CD2CFA00273F82 /* tvOS */, 170 | ); 171 | path = Source; 172 | sourceTree = ""; 173 | }; 174 | B9F878C821CD2CF500273F82 /* iOS */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | B9F878C921CD2CF500273F82 /* Images.xcassets */, 178 | B9F878CA21CD2CF500273F82 /* Info.plist */, 179 | ); 180 | path = iOS; 181 | sourceTree = ""; 182 | }; 183 | B9F878CD21CD2CFA00273F82 /* tvOS */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | B9F878CE21CD2CFA00273F82 /* Images.xcassets */, 187 | B9F878CF21CD2CFA00273F82 /* Info.plist */, 188 | ); 189 | path = tvOS; 190 | sourceTree = ""; 191 | }; 192 | B9F8796C21CD36B400273F82 /* Products */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | B9F8797221CD36B400273F82 /* Columbus.framework */, 196 | B96D498321CD3ED00010E69B /* Resources.bundle */, 197 | B9F8797421CD36B400273F82 /* Columbus-iOS-Tests.xctest */, 198 | B94B1B0C21CD394500FF1B72 /* Columbus.framework */, 199 | B9693324228B54FF0002B855 /* Resources.bundle */, 200 | B9A4A66121D0FC94001FF5DC /* Columbus-tvOS-Tests.xctest */, 201 | ); 202 | name = Products; 203 | sourceTree = ""; 204 | }; 205 | B9F8797B21CD373200273F82 /* Frameworks */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | ); 209 | name = Frameworks; 210 | sourceTree = ""; 211 | }; 212 | /* End PBXGroup section */ 213 | 214 | /* Begin PBXNativeTarget section */ 215 | B9F878D721CD2D5A00273F82 /* Columbus_iOS_Example */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = B9F878E721CD2D5B00273F82 /* Build configuration list for PBXNativeTarget "Columbus_iOS_Example" */; 218 | buildPhases = ( 219 | B9F878D421CD2D5A00273F82 /* Sources */, 220 | B9F878D521CD2D5A00273F82 /* Frameworks */, 221 | B9F878D621CD2D5A00273F82 /* Resources */, 222 | B93D76E023E4711B00E41863 /* Embed Frameworks */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | B94B1B2621CD3BEC00FF1B72 /* PBXTargetDependency */, 228 | ); 229 | name = Columbus_iOS_Example; 230 | productName = Columbus_iOS_Example; 231 | productReference = B9F878D821CD2D5A00273F82 /* Columbus_iOS_Example.app */; 232 | productType = "com.apple.product-type.application"; 233 | }; 234 | B9F8790921CD2DDA00273F82 /* Columbus_tvOS_Example */ = { 235 | isa = PBXNativeTarget; 236 | buildConfigurationList = B9F8791621CD2DDB00273F82 /* Build configuration list for PBXNativeTarget "Columbus_tvOS_Example" */; 237 | buildPhases = ( 238 | B9F8790621CD2DDA00273F82 /* Sources */, 239 | B9F8790721CD2DDA00273F82 /* Frameworks */, 240 | B9F8790821CD2DDA00273F82 /* Resources */, 241 | B93D76E323E4712100E41863 /* Embed Frameworks */, 242 | ); 243 | buildRules = ( 244 | ); 245 | dependencies = ( 246 | B94B1B0E21CD394700FF1B72 /* PBXTargetDependency */, 247 | ); 248 | name = Columbus_tvOS_Example; 249 | productName = Columbus_tvOS_Example; 250 | productReference = B9F8790A21CD2DDA00273F82 /* Columbus_tvOS_Example.app */; 251 | productType = "com.apple.product-type.application"; 252 | }; 253 | /* End PBXNativeTarget section */ 254 | 255 | /* Begin PBXProject section */ 256 | B9C8325521C84F3D0008ED90 /* Project object */ = { 257 | isa = PBXProject; 258 | attributes = { 259 | LastSwiftUpdateCheck = 1010; 260 | LastUpgradeCheck = 1240; 261 | ORGANIZATIONNAME = "Stefan Herold"; 262 | TargetAttributes = { 263 | B9F878D721CD2D5A00273F82 = { 264 | CreatedOnToolsVersion = 10.1; 265 | LastSwiftMigration = 1020; 266 | }; 267 | B9F8790921CD2DDA00273F82 = { 268 | CreatedOnToolsVersion = 10.1; 269 | LastSwiftMigration = 1020; 270 | }; 271 | }; 272 | }; 273 | buildConfigurationList = B9C8325821C84F3D0008ED90 /* Build configuration list for PBXProject "ColumbusExample" */; 274 | compatibilityVersion = "Xcode 11.0"; 275 | developmentRegion = en; 276 | hasScannedForEncodings = 0; 277 | knownRegions = ( 278 | en, 279 | Base, 280 | de, 281 | es, 282 | fr, 283 | it, 284 | ja, 285 | ru, 286 | "zh-Hans", 287 | ); 288 | mainGroup = B9C8325421C84F3D0008ED90; 289 | productRefGroup = B9C8325E21C84F3D0008ED90 /* Products */; 290 | projectDirPath = ""; 291 | projectReferences = ( 292 | { 293 | ProductGroup = B9F8796C21CD36B400273F82 /* Products */; 294 | ProjectRef = B9F8796B21CD36B400273F82 /* Columbus.xcodeproj */; 295 | }, 296 | ); 297 | projectRoot = ""; 298 | targets = ( 299 | B9F878D721CD2D5A00273F82 /* Columbus_iOS_Example */, 300 | B9F8790921CD2DDA00273F82 /* Columbus_tvOS_Example */, 301 | ); 302 | }; 303 | /* End PBXProject section */ 304 | 305 | /* Begin PBXReferenceProxy section */ 306 | B94B1B0C21CD394500FF1B72 /* Columbus.framework */ = { 307 | isa = PBXReferenceProxy; 308 | fileType = wrapper.framework; 309 | path = Columbus.framework; 310 | remoteRef = B94B1B0B21CD394500FF1B72 /* PBXContainerItemProxy */; 311 | sourceTree = BUILT_PRODUCTS_DIR; 312 | }; 313 | B9693324228B54FF0002B855 /* Resources.bundle */ = { 314 | isa = PBXReferenceProxy; 315 | fileType = wrapper.cfbundle; 316 | path = Resources.bundle; 317 | remoteRef = B9693323228B54FF0002B855 /* PBXContainerItemProxy */; 318 | sourceTree = BUILT_PRODUCTS_DIR; 319 | }; 320 | B96D498321CD3ED00010E69B /* Resources.bundle */ = { 321 | isa = PBXReferenceProxy; 322 | fileType = wrapper.cfbundle; 323 | path = Resources.bundle; 324 | remoteRef = B96D498221CD3ED00010E69B /* PBXContainerItemProxy */; 325 | sourceTree = BUILT_PRODUCTS_DIR; 326 | }; 327 | B9A4A66121D0FC94001FF5DC /* Columbus-tvOS-Tests.xctest */ = { 328 | isa = PBXReferenceProxy; 329 | fileType = wrapper.cfbundle; 330 | path = "Columbus-tvOS-Tests.xctest"; 331 | remoteRef = B9A4A66021D0FC94001FF5DC /* PBXContainerItemProxy */; 332 | sourceTree = BUILT_PRODUCTS_DIR; 333 | }; 334 | B9F8797221CD36B400273F82 /* Columbus.framework */ = { 335 | isa = PBXReferenceProxy; 336 | fileType = wrapper.framework; 337 | path = Columbus.framework; 338 | remoteRef = B9F8797121CD36B400273F82 /* PBXContainerItemProxy */; 339 | sourceTree = BUILT_PRODUCTS_DIR; 340 | }; 341 | B9F8797421CD36B400273F82 /* Columbus-iOS-Tests.xctest */ = { 342 | isa = PBXReferenceProxy; 343 | fileType = wrapper.cfbundle; 344 | path = "Columbus-iOS-Tests.xctest"; 345 | remoteRef = B9F8797321CD36B400273F82 /* PBXContainerItemProxy */; 346 | sourceTree = BUILT_PRODUCTS_DIR; 347 | }; 348 | /* End PBXReferenceProxy section */ 349 | 350 | /* Begin PBXResourcesBuildPhase section */ 351 | B9F878D621CD2D5A00273F82 /* Resources */ = { 352 | isa = PBXResourcesBuildPhase; 353 | buildActionMask = 2147483647; 354 | files = ( 355 | B933821325CDF99400618FFD /* CountryPickerStoryboard.storyboard in Resources */, 356 | B9F8790221CD2D8400273F82 /* Images.xcassets in Resources */, 357 | B9F8790421CD2D9800273F82 /* LaunchScreen.storyboard in Resources */, 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | }; 361 | B9F8790821CD2DDA00273F82 /* Resources */ = { 362 | isa = PBXResourcesBuildPhase; 363 | buildActionMask = 2147483647; 364 | files = ( 365 | B9F8791A21CD2DEB00273F82 /* Images.xcassets in Resources */, 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | /* End PBXResourcesBuildPhase section */ 370 | 371 | /* Begin PBXSourcesBuildPhase section */ 372 | B9F878D421CD2D5A00273F82 /* Sources */ = { 373 | isa = PBXSourcesBuildPhase; 374 | buildActionMask = 2147483647; 375 | files = ( 376 | B9F8790021CD2D7F00273F82 /* AppDelegate.swift in Sources */, 377 | B93D76EF23E4A80900E41863 /* UIColor+SemanticColors.swift in Sources */, 378 | ); 379 | runOnlyForDeploymentPostprocessing = 0; 380 | }; 381 | B9F8790621CD2DDA00273F82 /* Sources */ = { 382 | isa = PBXSourcesBuildPhase; 383 | buildActionMask = 2147483647; 384 | files = ( 385 | B9F8791B21CD2DEF00273F82 /* AppDelegate.swift in Sources */, 386 | B93D76F023E4A80900E41863 /* UIColor+SemanticColors.swift in Sources */, 387 | ); 388 | runOnlyForDeploymentPostprocessing = 0; 389 | }; 390 | /* End PBXSourcesBuildPhase section */ 391 | 392 | /* Begin PBXTargetDependency section */ 393 | B94B1B0E21CD394700FF1B72 /* PBXTargetDependency */ = { 394 | isa = PBXTargetDependency; 395 | name = "Columbus-tvOS"; 396 | targetProxy = B94B1B0D21CD394700FF1B72 /* PBXContainerItemProxy */; 397 | }; 398 | B94B1B2621CD3BEC00FF1B72 /* PBXTargetDependency */ = { 399 | isa = PBXTargetDependency; 400 | name = "Columbus-iOS"; 401 | targetProxy = B94B1B2521CD3BEC00FF1B72 /* PBXContainerItemProxy */; 402 | }; 403 | /* End PBXTargetDependency section */ 404 | 405 | /* Begin XCBuildConfiguration section */ 406 | B9C8326D21C84F400008ED90 /* Debug */ = { 407 | isa = XCBuildConfiguration; 408 | buildSettings = { 409 | ALWAYS_SEARCH_USER_PATHS = NO; 410 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 411 | CLANG_ANALYZER_NONNULL = YES; 412 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 413 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_MODULES = YES; 416 | CLANG_ENABLE_OBJC_ARC = YES; 417 | CLANG_ENABLE_OBJC_WEAK = YES; 418 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 419 | CLANG_WARN_BOOL_CONVERSION = YES; 420 | CLANG_WARN_COMMA = YES; 421 | CLANG_WARN_CONSTANT_CONVERSION = YES; 422 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 423 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 424 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 425 | CLANG_WARN_EMPTY_BODY = YES; 426 | CLANG_WARN_ENUM_CONVERSION = YES; 427 | CLANG_WARN_INFINITE_RECURSION = YES; 428 | CLANG_WARN_INT_CONVERSION = YES; 429 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 430 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 431 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 432 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 433 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 434 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 435 | CLANG_WARN_STRICT_PROTOTYPES = YES; 436 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 437 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 438 | CLANG_WARN_UNREACHABLE_CODE = YES; 439 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 440 | CODE_SIGN_IDENTITY = "iPhone Developer"; 441 | COPY_PHASE_STRIP = NO; 442 | DEBUG_INFORMATION_FORMAT = dwarf; 443 | ENABLE_STRICT_OBJC_MSGSEND = YES; 444 | ENABLE_TESTABILITY = YES; 445 | GCC_C_LANGUAGE_STANDARD = gnu11; 446 | GCC_DYNAMIC_NO_PIC = NO; 447 | GCC_NO_COMMON_BLOCKS = YES; 448 | GCC_OPTIMIZATION_LEVEL = 0; 449 | GCC_PREPROCESSOR_DEFINITIONS = ( 450 | "DEBUG=1", 451 | "$(inherited)", 452 | ); 453 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 454 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 455 | GCC_WARN_UNDECLARED_SELECTOR = YES; 456 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 457 | GCC_WARN_UNUSED_FUNCTION = YES; 458 | GCC_WARN_UNUSED_VARIABLE = YES; 459 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 460 | MTL_FAST_MATH = YES; 461 | ONLY_ACTIVE_ARCH = YES; 462 | SDKROOT = iphoneos; 463 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 464 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 465 | }; 466 | name = Debug; 467 | }; 468 | B9C8326E21C84F400008ED90 /* Release */ = { 469 | isa = XCBuildConfiguration; 470 | buildSettings = { 471 | ALWAYS_SEARCH_USER_PATHS = NO; 472 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 473 | CLANG_ANALYZER_NONNULL = YES; 474 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 475 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 476 | CLANG_CXX_LIBRARY = "libc++"; 477 | CLANG_ENABLE_MODULES = YES; 478 | CLANG_ENABLE_OBJC_ARC = YES; 479 | CLANG_ENABLE_OBJC_WEAK = YES; 480 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 481 | CLANG_WARN_BOOL_CONVERSION = YES; 482 | CLANG_WARN_COMMA = YES; 483 | CLANG_WARN_CONSTANT_CONVERSION = YES; 484 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 485 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 486 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 487 | CLANG_WARN_EMPTY_BODY = YES; 488 | CLANG_WARN_ENUM_CONVERSION = YES; 489 | CLANG_WARN_INFINITE_RECURSION = YES; 490 | CLANG_WARN_INT_CONVERSION = YES; 491 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 492 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 493 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 494 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 495 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 496 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 497 | CLANG_WARN_STRICT_PROTOTYPES = YES; 498 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 499 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 500 | CLANG_WARN_UNREACHABLE_CODE = YES; 501 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 502 | CODE_SIGN_IDENTITY = "iPhone Developer"; 503 | COPY_PHASE_STRIP = NO; 504 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 505 | ENABLE_NS_ASSERTIONS = NO; 506 | ENABLE_STRICT_OBJC_MSGSEND = YES; 507 | GCC_C_LANGUAGE_STANDARD = gnu11; 508 | GCC_NO_COMMON_BLOCKS = YES; 509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 511 | GCC_WARN_UNDECLARED_SELECTOR = YES; 512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 513 | GCC_WARN_UNUSED_FUNCTION = YES; 514 | GCC_WARN_UNUSED_VARIABLE = YES; 515 | MTL_ENABLE_DEBUG_INFO = NO; 516 | MTL_FAST_MATH = YES; 517 | SDKROOT = iphoneos; 518 | SWIFT_COMPILATION_MODE = wholemodule; 519 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 520 | VALIDATE_PRODUCT = YES; 521 | }; 522 | name = Release; 523 | }; 524 | B9F878E821CD2D5B00273F82 /* Debug */ = { 525 | isa = XCBuildConfiguration; 526 | buildSettings = { 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 528 | CODE_SIGN_STYLE = Automatic; 529 | DEVELOPMENT_TEAM = PCW579R278; 530 | INFOPLIST_FILE = Source/iOS/Info.plist; 531 | LD_RUNPATH_SEARCH_PATHS = ( 532 | "$(inherited)", 533 | "@executable_path/Frameworks", 534 | ); 535 | PRODUCT_BUNDLE_IDENTIFIER = "com.stherold.columbus-Ios-example"; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | SDKROOT = iphoneos; 538 | SWIFT_VERSION = 5.0; 539 | TARGETED_DEVICE_FAMILY = "1,2"; 540 | }; 541 | name = Debug; 542 | }; 543 | B9F878E921CD2D5B00273F82 /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 547 | CODE_SIGN_STYLE = Automatic; 548 | DEVELOPMENT_TEAM = PCW579R278; 549 | INFOPLIST_FILE = Source/iOS/Info.plist; 550 | LD_RUNPATH_SEARCH_PATHS = ( 551 | "$(inherited)", 552 | "@executable_path/Frameworks", 553 | ); 554 | PRODUCT_BUNDLE_IDENTIFIER = "com.stherold.columbus-Ios-example"; 555 | PRODUCT_NAME = "$(TARGET_NAME)"; 556 | SDKROOT = iphoneos; 557 | SWIFT_VERSION = 5.0; 558 | TARGETED_DEVICE_FAMILY = "1,2"; 559 | }; 560 | name = Release; 561 | }; 562 | B9F8791721CD2DDB00273F82 /* Debug */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 566 | CODE_SIGN_STYLE = Automatic; 567 | DEVELOPMENT_TEAM = PCW579R278; 568 | INFOPLIST_FILE = Source/tvOS/Info.plist; 569 | LD_RUNPATH_SEARCH_PATHS = ( 570 | "$(inherited)", 571 | "@executable_path/Frameworks", 572 | ); 573 | PRODUCT_BUNDLE_IDENTIFIER = "com.stherold.columbus-Ios-example"; 574 | PRODUCT_NAME = "$(TARGET_NAME)"; 575 | SDKROOT = appletvos; 576 | SWIFT_VERSION = 5.0; 577 | TARGETED_DEVICE_FAMILY = 3; 578 | }; 579 | name = Debug; 580 | }; 581 | B9F8791821CD2DDB00273F82 /* Release */ = { 582 | isa = XCBuildConfiguration; 583 | buildSettings = { 584 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 585 | CODE_SIGN_STYLE = Automatic; 586 | DEVELOPMENT_TEAM = PCW579R278; 587 | INFOPLIST_FILE = Source/tvOS/Info.plist; 588 | LD_RUNPATH_SEARCH_PATHS = ( 589 | "$(inherited)", 590 | "@executable_path/Frameworks", 591 | ); 592 | PRODUCT_BUNDLE_IDENTIFIER = "com.stherold.columbus-Ios-example"; 593 | PRODUCT_NAME = "$(TARGET_NAME)"; 594 | SDKROOT = appletvos; 595 | SWIFT_VERSION = 5.0; 596 | TARGETED_DEVICE_FAMILY = 3; 597 | }; 598 | name = Release; 599 | }; 600 | /* End XCBuildConfiguration section */ 601 | 602 | /* Begin XCConfigurationList section */ 603 | B9C8325821C84F3D0008ED90 /* Build configuration list for PBXProject "ColumbusExample" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | B9C8326D21C84F400008ED90 /* Debug */, 607 | B9C8326E21C84F400008ED90 /* Release */, 608 | ); 609 | defaultConfigurationIsVisible = 0; 610 | defaultConfigurationName = Release; 611 | }; 612 | B9F878E721CD2D5B00273F82 /* Build configuration list for PBXNativeTarget "Columbus_iOS_Example" */ = { 613 | isa = XCConfigurationList; 614 | buildConfigurations = ( 615 | B9F878E821CD2D5B00273F82 /* Debug */, 616 | B9F878E921CD2D5B00273F82 /* Release */, 617 | ); 618 | defaultConfigurationIsVisible = 0; 619 | defaultConfigurationName = Release; 620 | }; 621 | B9F8791621CD2DDB00273F82 /* Build configuration list for PBXNativeTarget "Columbus_tvOS_Example" */ = { 622 | isa = XCConfigurationList; 623 | buildConfigurations = ( 624 | B9F8791721CD2DDB00273F82 /* Debug */, 625 | B9F8791821CD2DDB00273F82 /* Release */, 626 | ); 627 | defaultConfigurationIsVisible = 0; 628 | defaultConfigurationName = Release; 629 | }; 630 | /* End XCConfigurationList section */ 631 | }; 632 | rootObject = B9C8325521C84F3D0008ED90 /* Project object */; 633 | } 634 | -------------------------------------------------------------------------------- /Columbus.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B905891D230233B800491105 /* UIView+Subviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = B905891C230233B800491105 /* UIView+Subviews.swift */; }; 11 | B905891E230233BC00491105 /* UIView+Subviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = B905891C230233B800491105 /* UIView+Subviews.swift */; }; 12 | B933818725CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B933818625CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift */; }; 13 | B933818825CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B933818625CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift */; }; 14 | B94B1AF921CD38B400FF1B72 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8788F21CD28EC00273F82 /* Country.swift */; }; 15 | B94B1AFA21CD38B400FF1B72 /* CountryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8788E21CD28EC00273F82 /* CountryList.swift */; }; 16 | B94B1AFB21CD38B400FF1B72 /* Configurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789421CD28EC00273F82 /* Configurable.swift */; }; 17 | B94B1AFC21CD38B400FF1B72 /* CountryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789321CD28EC00273F82 /* CountryCell.swift */; }; 18 | B94B1AFD21CD38B400FF1B72 /* CountryPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789221CD28EC00273F82 /* CountryPickerViewController.swift */; }; 19 | B94B1AFE21CD38B400FF1B72 /* ColumbusMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789021CD28EC00273F82 /* ColumbusMain.swift */; }; 20 | B94B1AFF21CD38B400FF1B72 /* CountryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789121CD28EC00273F82 /* CountryView.swift */; }; 21 | B96D495D21CD3DC20010E69B /* Countries.json in Resources */ = {isa = PBXBuildFile; fileRef = B9F8789721CD28EC00273F82 /* Countries.json */; }; 22 | B9A4A65721D0F409001FF5DC /* Resources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B96D496221CD3DC20010E69B /* Resources.bundle */; }; 23 | B9A4A65A21D0FC14001FF5DC /* ColumbusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A4A65921D0FC14001FF5DC /* ColumbusTests.swift */; }; 24 | B9A4A65B21D0FC14001FF5DC /* ColumbusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A4A65921D0FC14001FF5DC /* ColumbusTests.swift */; }; 25 | B9A4A67321D145EB001FF5DC /* Countries.json in Resources */ = {isa = PBXBuildFile; fileRef = B9F8789721CD28EC00273F82 /* Countries.json */; }; 26 | B9A4A67D21D146A1001FF5DC /* Resources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B9A4A67821D145EB001FF5DC /* Resources.bundle */; }; 27 | B9CAAB1425E1BEB4004BA1BF /* EmptyDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9CAAB1325E1BEB4004BA1BF /* EmptyDecodable.swift */; }; 28 | B9CAAB1525E1BEB4004BA1BF /* EmptyDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9CAAB1325E1BEB4004BA1BF /* EmptyDecodable.swift */; }; 29 | B9DB66ED21DF924600E9BB35 /* Columbus.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B94B1B0621CD38B400FF1B72 /* Columbus.framework */; }; 30 | B9F8789C21CD28EC00273F82 /* CountryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8788E21CD28EC00273F82 /* CountryList.swift */; }; 31 | B9F8789D21CD28EC00273F82 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8788F21CD28EC00273F82 /* Country.swift */; }; 32 | B9F8789E21CD28EC00273F82 /* ColumbusMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789021CD28EC00273F82 /* ColumbusMain.swift */; }; 33 | B9F8789F21CD28EC00273F82 /* CountryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789121CD28EC00273F82 /* CountryView.swift */; }; 34 | B9F878A021CD28EC00273F82 /* CountryPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789221CD28EC00273F82 /* CountryPickerViewController.swift */; }; 35 | B9F878A121CD28EC00273F82 /* CountryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789321CD28EC00273F82 /* CountryCell.swift */; }; 36 | B9F878A221CD28EC00273F82 /* Configurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F8789421CD28EC00273F82 /* Configurable.swift */; }; 37 | B9F878B121CD2A4E00273F82 /* Columbus.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9F8788321CD28A200273F82 /* Columbus.framework */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXContainerItemProxy section */ 41 | B96D496421CD3E4C0010E69B /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = B96D495921CD3DC20010E69B; 46 | remoteInfo = "Resources-iOS"; 47 | }; 48 | B9A4A67E21D1483C001FF5DC /* PBXContainerItemProxy */ = { 49 | isa = PBXContainerItemProxy; 50 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 51 | proxyType = 1; 52 | remoteGlobalIDString = B9A4A66F21D145EB001FF5DC; 53 | remoteInfo = "Resources-tvOS"; 54 | }; 55 | B9DB81FE21D0EE7800A39677 /* PBXContainerItemProxy */ = { 56 | isa = PBXContainerItemProxy; 57 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 58 | proxyType = 1; 59 | remoteGlobalIDString = B94B1AF421CD38B400FF1B72; 60 | remoteInfo = "Columbus-tvOS"; 61 | }; 62 | B9F878B221CD2A4E00273F82 /* PBXContainerItemProxy */ = { 63 | isa = PBXContainerItemProxy; 64 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 65 | proxyType = 1; 66 | remoteGlobalIDString = B9F8788221CD28A200273F82; 67 | remoteInfo = Columbus; 68 | }; 69 | /* End PBXContainerItemProxy section */ 70 | 71 | /* Begin PBXFileReference section */ 72 | B905891C230233B800491105 /* UIView+Subviews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Subviews.swift"; sourceTree = ""; }; 73 | B933818625CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CountryPickerViewController+DisplayState.swift"; sourceTree = ""; }; 74 | B94B1B0621CD38B400FF1B72 /* Columbus.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Columbus.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | B96D496221CD3DC20010E69B /* Resources.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Resources.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | B9A4A65921D0FC14001FF5DC /* ColumbusTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColumbusTests.swift; sourceTree = ""; }; 77 | B9A4A67821D145EB001FF5DC /* Resources.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Resources.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 78 | B9CAAB1325E1BEB4004BA1BF /* EmptyDecodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyDecodable.swift; sourceTree = ""; }; 79 | B9DB81FC21D0E9F500A39677 /* Columbus-tvOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Columbus-tvOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | B9F8787821CD27FE00273F82 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 81 | B9F8787921CD27FE00273F82 /* Gemfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Gemfile; sourceTree = ""; }; 82 | B9F8787A21CD27FE00273F82 /* Columbus.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = Columbus.podspec; sourceTree = ""; }; 83 | B9F8787B21CD27FE00273F82 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 84 | B9F8787C21CD27FE00273F82 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; }; 85 | B9F8787D21CD27FE00273F82 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = ""; }; 86 | B9F8788321CD28A200273F82 /* Columbus.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Columbus.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 87 | B9F8788E21CD28EC00273F82 /* CountryList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryList.swift; sourceTree = ""; }; 88 | B9F8788F21CD28EC00273F82 /* Country.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = ""; }; 89 | B9F8789021CD28EC00273F82 /* ColumbusMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColumbusMain.swift; sourceTree = ""; }; 90 | B9F8789121CD28EC00273F82 /* CountryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryView.swift; sourceTree = ""; }; 91 | B9F8789221CD28EC00273F82 /* CountryPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryPickerViewController.swift; sourceTree = ""; }; 92 | B9F8789321CD28EC00273F82 /* CountryCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryCell.swift; sourceTree = ""; }; 93 | B9F8789421CD28EC00273F82 /* Configurable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configurable.swift; sourceTree = ""; }; 94 | B9F8789721CD28EC00273F82 /* Countries.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Countries.json; sourceTree = ""; }; 95 | B9F8789921CD28EC00273F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 96 | B9F8789A21CD28EC00273F82 /* Columbus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Columbus.h; sourceTree = ""; }; 97 | B9F878AC21CD2A4D00273F82 /* Columbus-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Columbus-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 98 | B9F878B721CD2AB200273F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 99 | B9F8793721CD320600273F82 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 100 | /* End PBXFileReference section */ 101 | 102 | /* Begin PBXFrameworksBuildPhase section */ 103 | B94B1B0021CD38B400FF1B72 /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | B96D495B21CD3DC20010E69B /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | B9A4A67121D145EB001FF5DC /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | B9DB81F421D0E9F500A39677 /* Frameworks */ = { 125 | isa = PBXFrameworksBuildPhase; 126 | buildActionMask = 2147483647; 127 | files = ( 128 | B9DB66ED21DF924600E9BB35 /* Columbus.framework in Frameworks */, 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | B9F8788021CD28A200273F82 /* Frameworks */ = { 133 | isa = PBXFrameworksBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | B9F878A921CD2A4D00273F82 /* Frameworks */ = { 140 | isa = PBXFrameworksBuildPhase; 141 | buildActionMask = 2147483647; 142 | files = ( 143 | B9F878B121CD2A4E00273F82 /* Columbus.framework in Frameworks */, 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | /* End PBXFrameworksBuildPhase section */ 148 | 149 | /* Begin PBXGroup section */ 150 | 607FACC71AFB9204008FA782 = { 151 | isa = PBXGroup; 152 | children = ( 153 | 607FACF51AFB993E008FA782 /* Metadata */, 154 | B9F8788B21CD28EC00273F82 /* Source */, 155 | 607FACE81AFB9204008FA782 /* Tests */, 156 | 607FACD11AFB9204008FA782 /* Products */, 157 | 799CEB9EFAE19AD086AA53E6 /* Frameworks */, 158 | ); 159 | sourceTree = ""; 160 | }; 161 | 607FACD11AFB9204008FA782 /* Products */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | B9F8788321CD28A200273F82 /* Columbus.framework */, 165 | B9F878AC21CD2A4D00273F82 /* Columbus-iOS-Tests.xctest */, 166 | B94B1B0621CD38B400FF1B72 /* Columbus.framework */, 167 | B96D496221CD3DC20010E69B /* Resources.bundle */, 168 | B9DB81FC21D0E9F500A39677 /* Columbus-tvOS-Tests.xctest */, 169 | B9A4A67821D145EB001FF5DC /* Resources.bundle */, 170 | ); 171 | name = Products; 172 | sourceTree = ""; 173 | }; 174 | 607FACE81AFB9204008FA782 /* Tests */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | B9A4A65921D0FC14001FF5DC /* ColumbusTests.swift */, 178 | 607FACE91AFB9204008FA782 /* Supporting Files */, 179 | ); 180 | path = Tests; 181 | sourceTree = ""; 182 | }; 183 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | B9F878B721CD2AB200273F82 /* Info.plist */, 187 | ); 188 | name = "Supporting Files"; 189 | sourceTree = ""; 190 | }; 191 | 607FACF51AFB993E008FA782 /* Metadata */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | B9F8787D21CD27FE00273F82 /* AUTHORS */, 195 | B9F8787921CD27FE00273F82 /* Gemfile */, 196 | B9F8787821CD27FE00273F82 /* LICENSE */, 197 | B9F8787C21CD27FE00273F82 /* CHANGELOG.md */, 198 | B9F8787B21CD27FE00273F82 /* README.md */, 199 | B9F8787A21CD27FE00273F82 /* Columbus.podspec */, 200 | ); 201 | name = Metadata; 202 | sourceTree = ""; 203 | }; 204 | 799CEB9EFAE19AD086AA53E6 /* Frameworks */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | ); 208 | name = Frameworks; 209 | sourceTree = ""; 210 | }; 211 | B9F8788B21CD28EC00273F82 /* Source */ = { 212 | isa = PBXGroup; 213 | children = ( 214 | B9F8789A21CD28EC00273F82 /* Columbus.h */, 215 | B9F8789921CD28EC00273F82 /* Info.plist */, 216 | B9F8788C21CD28EC00273F82 /* Classes */, 217 | B9F8789521CD28EC00273F82 /* Resources */, 218 | ); 219 | path = Source; 220 | sourceTree = ""; 221 | }; 222 | B9F8788C21CD28EC00273F82 /* Classes */ = { 223 | isa = PBXGroup; 224 | children = ( 225 | B9F8789021CD28EC00273F82 /* ColumbusMain.swift */, 226 | B9F8789421CD28EC00273F82 /* Configurable.swift */, 227 | B9F8788F21CD28EC00273F82 /* Country.swift */, 228 | B9CAAB1325E1BEB4004BA1BF /* EmptyDecodable.swift */, 229 | B9F8789321CD28EC00273F82 /* CountryCell.swift */, 230 | B9F8788E21CD28EC00273F82 /* CountryList.swift */, 231 | B9F8789221CD28EC00273F82 /* CountryPickerViewController.swift */, 232 | B933818625CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift */, 233 | B9F8789121CD28EC00273F82 /* CountryView.swift */, 234 | B905891C230233B800491105 /* UIView+Subviews.swift */, 235 | ); 236 | path = Classes; 237 | sourceTree = ""; 238 | }; 239 | B9F8789521CD28EC00273F82 /* Resources */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | B9F8793721CD320600273F82 /* Info.plist */, 243 | B9F8789721CD28EC00273F82 /* Countries.json */, 244 | ); 245 | path = Resources; 246 | sourceTree = ""; 247 | }; 248 | /* End PBXGroup section */ 249 | 250 | /* Begin PBXHeadersBuildPhase section */ 251 | B94B1AF721CD38B400FF1B72 /* Headers */ = { 252 | isa = PBXHeadersBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | B9F8787E21CD28A200273F82 /* Headers */ = { 259 | isa = PBXHeadersBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXHeadersBuildPhase section */ 266 | 267 | /* Begin PBXNativeTarget section */ 268 | B94B1AF421CD38B400FF1B72 /* Columbus-tvOS */ = { 269 | isa = PBXNativeTarget; 270 | buildConfigurationList = B94B1B0321CD38B400FF1B72 /* Build configuration list for PBXNativeTarget "Columbus-tvOS" */; 271 | buildPhases = ( 272 | B94B1AF721CD38B400FF1B72 /* Headers */, 273 | B94B1AF821CD38B400FF1B72 /* Sources */, 274 | B94B1B0021CD38B400FF1B72 /* Frameworks */, 275 | B94B1B0121CD38B400FF1B72 /* Resources */, 276 | ); 277 | buildRules = ( 278 | ); 279 | dependencies = ( 280 | B9A4A67F21D1483C001FF5DC /* PBXTargetDependency */, 281 | ); 282 | name = "Columbus-tvOS"; 283 | productName = Columbus; 284 | productReference = B94B1B0621CD38B400FF1B72 /* Columbus.framework */; 285 | productType = "com.apple.product-type.framework"; 286 | }; 287 | B96D495921CD3DC20010E69B /* Resources-iOS */ = { 288 | isa = PBXNativeTarget; 289 | buildConfigurationList = B96D495F21CD3DC20010E69B /* Build configuration list for PBXNativeTarget "Resources-iOS" */; 290 | buildPhases = ( 291 | B96D495A21CD3DC20010E69B /* Sources */, 292 | B96D495B21CD3DC20010E69B /* Frameworks */, 293 | B96D495C21CD3DC20010E69B /* Resources */, 294 | ); 295 | buildRules = ( 296 | ); 297 | dependencies = ( 298 | ); 299 | name = "Resources-iOS"; 300 | productName = Flags; 301 | productReference = B96D496221CD3DC20010E69B /* Resources.bundle */; 302 | productType = "com.apple.product-type.bundle"; 303 | }; 304 | B9A4A66F21D145EB001FF5DC /* Resources-tvOS */ = { 305 | isa = PBXNativeTarget; 306 | buildConfigurationList = B9A4A67521D145EB001FF5DC /* Build configuration list for PBXNativeTarget "Resources-tvOS" */; 307 | buildPhases = ( 308 | B9A4A67021D145EB001FF5DC /* Sources */, 309 | B9A4A67121D145EB001FF5DC /* Frameworks */, 310 | B9A4A67221D145EB001FF5DC /* Resources */, 311 | ); 312 | buildRules = ( 313 | ); 314 | dependencies = ( 315 | ); 316 | name = "Resources-tvOS"; 317 | productName = Flags; 318 | productReference = B9A4A67821D145EB001FF5DC /* Resources.bundle */; 319 | productType = "com.apple.product-type.bundle"; 320 | }; 321 | B9DB81EE21D0E9F500A39677 /* Columbus-tvOS-Tests */ = { 322 | isa = PBXNativeTarget; 323 | buildConfigurationList = B9DB81F921D0E9F500A39677 /* Build configuration list for PBXNativeTarget "Columbus-tvOS-Tests" */; 324 | buildPhases = ( 325 | B9DB81F221D0E9F500A39677 /* Sources */, 326 | B9DB81F421D0E9F500A39677 /* Frameworks */, 327 | B9DB81F721D0E9F500A39677 /* Resources */, 328 | ); 329 | buildRules = ( 330 | ); 331 | dependencies = ( 332 | B9DB81FF21D0EE7800A39677 /* PBXTargetDependency */, 333 | ); 334 | name = "Columbus-tvOS-Tests"; 335 | productName = ColumbusTests; 336 | productReference = B9DB81FC21D0E9F500A39677 /* Columbus-tvOS-Tests.xctest */; 337 | productType = "com.apple.product-type.bundle.unit-test"; 338 | }; 339 | B9F8788221CD28A200273F82 /* Columbus-iOS */ = { 340 | isa = PBXNativeTarget; 341 | buildConfigurationList = B9F8788821CD28A200273F82 /* Build configuration list for PBXNativeTarget "Columbus-iOS" */; 342 | buildPhases = ( 343 | B9F8787E21CD28A200273F82 /* Headers */, 344 | B9F8787F21CD28A200273F82 /* Sources */, 345 | B9F8788021CD28A200273F82 /* Frameworks */, 346 | B9F8788121CD28A200273F82 /* Resources */, 347 | ); 348 | buildRules = ( 349 | ); 350 | dependencies = ( 351 | B96D496521CD3E4C0010E69B /* PBXTargetDependency */, 352 | ); 353 | name = "Columbus-iOS"; 354 | productName = Columbus; 355 | productReference = B9F8788321CD28A200273F82 /* Columbus.framework */; 356 | productType = "com.apple.product-type.framework"; 357 | }; 358 | B9F878AB21CD2A4D00273F82 /* Columbus-iOS-Tests */ = { 359 | isa = PBXNativeTarget; 360 | buildConfigurationList = B9F878B421CD2A4E00273F82 /* Build configuration list for PBXNativeTarget "Columbus-iOS-Tests" */; 361 | buildPhases = ( 362 | B9F878A821CD2A4D00273F82 /* Sources */, 363 | B9F878A921CD2A4D00273F82 /* Frameworks */, 364 | B9F878AA21CD2A4D00273F82 /* Resources */, 365 | ); 366 | buildRules = ( 367 | ); 368 | dependencies = ( 369 | B9F878B321CD2A4E00273F82 /* PBXTargetDependency */, 370 | ); 371 | name = "Columbus-iOS-Tests"; 372 | productName = ColumbusTests; 373 | productReference = B9F878AC21CD2A4D00273F82 /* Columbus-iOS-Tests.xctest */; 374 | productType = "com.apple.product-type.bundle.unit-test"; 375 | }; 376 | /* End PBXNativeTarget section */ 377 | 378 | /* Begin PBXProject section */ 379 | 607FACC81AFB9204008FA782 /* Project object */ = { 380 | isa = PBXProject; 381 | attributes = { 382 | BuildIndependentTargetsInParallel = YES; 383 | LastSwiftUpdateCheck = 1010; 384 | LastUpgradeCheck = 1430; 385 | ORGANIZATIONNAME = "Stefan Herold"; 386 | TargetAttributes = { 387 | B94B1AF421CD38B400FF1B72 = { 388 | LastSwiftMigration = 1020; 389 | }; 390 | B9DB81EE21D0E9F500A39677 = { 391 | LastSwiftMigration = 1020; 392 | }; 393 | B9F8788221CD28A200273F82 = { 394 | CreatedOnToolsVersion = 10.1; 395 | LastSwiftMigration = 1020; 396 | }; 397 | B9F878AB21CD2A4D00273F82 = { 398 | CreatedOnToolsVersion = 10.1; 399 | LastSwiftMigration = 1020; 400 | }; 401 | }; 402 | }; 403 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Columbus" */; 404 | compatibilityVersion = "Xcode 13.0"; 405 | developmentRegion = en; 406 | hasScannedForEncodings = 0; 407 | knownRegions = ( 408 | en, 409 | Base, 410 | ); 411 | mainGroup = 607FACC71AFB9204008FA782; 412 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 413 | projectDirPath = ""; 414 | projectRoot = ""; 415 | targets = ( 416 | B9F8788221CD28A200273F82 /* Columbus-iOS */, 417 | B96D495921CD3DC20010E69B /* Resources-iOS */, 418 | B9F878AB21CD2A4D00273F82 /* Columbus-iOS-Tests */, 419 | B94B1AF421CD38B400FF1B72 /* Columbus-tvOS */, 420 | B9A4A66F21D145EB001FF5DC /* Resources-tvOS */, 421 | B9DB81EE21D0E9F500A39677 /* Columbus-tvOS-Tests */, 422 | ); 423 | }; 424 | /* End PBXProject section */ 425 | 426 | /* Begin PBXResourcesBuildPhase section */ 427 | B94B1B0121CD38B400FF1B72 /* Resources */ = { 428 | isa = PBXResourcesBuildPhase; 429 | buildActionMask = 2147483647; 430 | files = ( 431 | B9A4A67D21D146A1001FF5DC /* Resources.bundle in Resources */, 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | B96D495C21CD3DC20010E69B /* Resources */ = { 436 | isa = PBXResourcesBuildPhase; 437 | buildActionMask = 2147483647; 438 | files = ( 439 | B96D495D21CD3DC20010E69B /* Countries.json in Resources */, 440 | ); 441 | runOnlyForDeploymentPostprocessing = 0; 442 | }; 443 | B9A4A67221D145EB001FF5DC /* Resources */ = { 444 | isa = PBXResourcesBuildPhase; 445 | buildActionMask = 2147483647; 446 | files = ( 447 | B9A4A67321D145EB001FF5DC /* Countries.json in Resources */, 448 | ); 449 | runOnlyForDeploymentPostprocessing = 0; 450 | }; 451 | B9DB81F721D0E9F500A39677 /* Resources */ = { 452 | isa = PBXResourcesBuildPhase; 453 | buildActionMask = 2147483647; 454 | files = ( 455 | ); 456 | runOnlyForDeploymentPostprocessing = 0; 457 | }; 458 | B9F8788121CD28A200273F82 /* Resources */ = { 459 | isa = PBXResourcesBuildPhase; 460 | buildActionMask = 2147483647; 461 | files = ( 462 | B9A4A65721D0F409001FF5DC /* Resources.bundle in Resources */, 463 | ); 464 | runOnlyForDeploymentPostprocessing = 0; 465 | }; 466 | B9F878AA21CD2A4D00273F82 /* Resources */ = { 467 | isa = PBXResourcesBuildPhase; 468 | buildActionMask = 2147483647; 469 | files = ( 470 | ); 471 | runOnlyForDeploymentPostprocessing = 0; 472 | }; 473 | /* End PBXResourcesBuildPhase section */ 474 | 475 | /* Begin PBXSourcesBuildPhase section */ 476 | B94B1AF821CD38B400FF1B72 /* Sources */ = { 477 | isa = PBXSourcesBuildPhase; 478 | buildActionMask = 2147483647; 479 | files = ( 480 | B94B1AF921CD38B400FF1B72 /* Country.swift in Sources */, 481 | B9CAAB1525E1BEB4004BA1BF /* EmptyDecodable.swift in Sources */, 482 | B94B1AFA21CD38B400FF1B72 /* CountryList.swift in Sources */, 483 | B94B1AFB21CD38B400FF1B72 /* Configurable.swift in Sources */, 484 | B94B1AFC21CD38B400FF1B72 /* CountryCell.swift in Sources */, 485 | B905891E230233BC00491105 /* UIView+Subviews.swift in Sources */, 486 | B933818825CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift in Sources */, 487 | B94B1AFD21CD38B400FF1B72 /* CountryPickerViewController.swift in Sources */, 488 | B94B1AFE21CD38B400FF1B72 /* ColumbusMain.swift in Sources */, 489 | B94B1AFF21CD38B400FF1B72 /* CountryView.swift in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | B96D495A21CD3DC20010E69B /* Sources */ = { 494 | isa = PBXSourcesBuildPhase; 495 | buildActionMask = 2147483647; 496 | files = ( 497 | ); 498 | runOnlyForDeploymentPostprocessing = 0; 499 | }; 500 | B9A4A67021D145EB001FF5DC /* Sources */ = { 501 | isa = PBXSourcesBuildPhase; 502 | buildActionMask = 2147483647; 503 | files = ( 504 | ); 505 | runOnlyForDeploymentPostprocessing = 0; 506 | }; 507 | B9DB81F221D0E9F500A39677 /* Sources */ = { 508 | isa = PBXSourcesBuildPhase; 509 | buildActionMask = 2147483647; 510 | files = ( 511 | B9A4A65B21D0FC14001FF5DC /* ColumbusTests.swift in Sources */, 512 | ); 513 | runOnlyForDeploymentPostprocessing = 0; 514 | }; 515 | B9F8787F21CD28A200273F82 /* Sources */ = { 516 | isa = PBXSourcesBuildPhase; 517 | buildActionMask = 2147483647; 518 | files = ( 519 | B9F8789D21CD28EC00273F82 /* Country.swift in Sources */, 520 | B9CAAB1425E1BEB4004BA1BF /* EmptyDecodable.swift in Sources */, 521 | B9F8789C21CD28EC00273F82 /* CountryList.swift in Sources */, 522 | B9F878A221CD28EC00273F82 /* Configurable.swift in Sources */, 523 | B9F878A121CD28EC00273F82 /* CountryCell.swift in Sources */, 524 | B905891D230233B800491105 /* UIView+Subviews.swift in Sources */, 525 | B933818725CDD4F200618FFD /* CountryPickerViewController+DisplayState.swift in Sources */, 526 | B9F878A021CD28EC00273F82 /* CountryPickerViewController.swift in Sources */, 527 | B9F8789E21CD28EC00273F82 /* ColumbusMain.swift in Sources */, 528 | B9F8789F21CD28EC00273F82 /* CountryView.swift in Sources */, 529 | ); 530 | runOnlyForDeploymentPostprocessing = 0; 531 | }; 532 | B9F878A821CD2A4D00273F82 /* Sources */ = { 533 | isa = PBXSourcesBuildPhase; 534 | buildActionMask = 2147483647; 535 | files = ( 536 | B9A4A65A21D0FC14001FF5DC /* ColumbusTests.swift in Sources */, 537 | ); 538 | runOnlyForDeploymentPostprocessing = 0; 539 | }; 540 | /* End PBXSourcesBuildPhase section */ 541 | 542 | /* Begin PBXTargetDependency section */ 543 | B96D496521CD3E4C0010E69B /* PBXTargetDependency */ = { 544 | isa = PBXTargetDependency; 545 | target = B96D495921CD3DC20010E69B /* Resources-iOS */; 546 | targetProxy = B96D496421CD3E4C0010E69B /* PBXContainerItemProxy */; 547 | }; 548 | B9A4A67F21D1483C001FF5DC /* PBXTargetDependency */ = { 549 | isa = PBXTargetDependency; 550 | target = B9A4A66F21D145EB001FF5DC /* Resources-tvOS */; 551 | targetProxy = B9A4A67E21D1483C001FF5DC /* PBXContainerItemProxy */; 552 | }; 553 | B9DB81FF21D0EE7800A39677 /* PBXTargetDependency */ = { 554 | isa = PBXTargetDependency; 555 | target = B94B1AF421CD38B400FF1B72 /* Columbus-tvOS */; 556 | targetProxy = B9DB81FE21D0EE7800A39677 /* PBXContainerItemProxy */; 557 | }; 558 | B9F878B321CD2A4E00273F82 /* PBXTargetDependency */ = { 559 | isa = PBXTargetDependency; 560 | target = B9F8788221CD28A200273F82 /* Columbus-iOS */; 561 | targetProxy = B9F878B221CD2A4E00273F82 /* PBXContainerItemProxy */; 562 | }; 563 | /* End PBXTargetDependency section */ 564 | 565 | /* Begin XCBuildConfiguration section */ 566 | 607FACED1AFB9204008FA782 /* Debug */ = { 567 | isa = XCBuildConfiguration; 568 | buildSettings = { 569 | ALWAYS_SEARCH_USER_PATHS = NO; 570 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 571 | CLANG_CXX_LIBRARY = "libc++"; 572 | CLANG_ENABLE_MODULES = YES; 573 | CLANG_ENABLE_OBJC_ARC = YES; 574 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 575 | CLANG_WARN_BOOL_CONVERSION = YES; 576 | CLANG_WARN_COMMA = YES; 577 | CLANG_WARN_CONSTANT_CONVERSION = YES; 578 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 579 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 580 | CLANG_WARN_EMPTY_BODY = YES; 581 | CLANG_WARN_ENUM_CONVERSION = YES; 582 | CLANG_WARN_INFINITE_RECURSION = YES; 583 | CLANG_WARN_INT_CONVERSION = YES; 584 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 585 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 586 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 587 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 588 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 589 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 590 | CLANG_WARN_STRICT_PROTOTYPES = YES; 591 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 592 | CLANG_WARN_UNREACHABLE_CODE = YES; 593 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 594 | CODE_SIGN_IDENTITY = ""; 595 | CODE_SIGN_STYLE = Manual; 596 | COPY_PHASE_STRIP = NO; 597 | DEAD_CODE_STRIPPING = YES; 598 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 599 | ENABLE_STRICT_OBJC_MSGSEND = YES; 600 | ENABLE_TESTABILITY = YES; 601 | GCC_C_LANGUAGE_STANDARD = gnu99; 602 | GCC_DYNAMIC_NO_PIC = NO; 603 | GCC_NO_COMMON_BLOCKS = YES; 604 | GCC_OPTIMIZATION_LEVEL = 0; 605 | GCC_PREPROCESSOR_DEFINITIONS = ( 606 | "DEBUG=1", 607 | "$(inherited)", 608 | ); 609 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 610 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 611 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 612 | GCC_WARN_UNDECLARED_SELECTOR = YES; 613 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 614 | GCC_WARN_UNUSED_FUNCTION = YES; 615 | GCC_WARN_UNUSED_VARIABLE = YES; 616 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 617 | MTL_ENABLE_DEBUG_INFO = YES; 618 | ONLY_ACTIVE_ARCH = YES; 619 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 620 | TVOS_DEPLOYMENT_TARGET = 13.0; 621 | }; 622 | name = Debug; 623 | }; 624 | 607FACEE1AFB9204008FA782 /* Release */ = { 625 | isa = XCBuildConfiguration; 626 | buildSettings = { 627 | ALWAYS_SEARCH_USER_PATHS = NO; 628 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 629 | CLANG_CXX_LIBRARY = "libc++"; 630 | CLANG_ENABLE_MODULES = YES; 631 | CLANG_ENABLE_OBJC_ARC = YES; 632 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 633 | CLANG_WARN_BOOL_CONVERSION = YES; 634 | CLANG_WARN_COMMA = YES; 635 | CLANG_WARN_CONSTANT_CONVERSION = YES; 636 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 637 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 638 | CLANG_WARN_EMPTY_BODY = YES; 639 | CLANG_WARN_ENUM_CONVERSION = YES; 640 | CLANG_WARN_INFINITE_RECURSION = YES; 641 | CLANG_WARN_INT_CONVERSION = YES; 642 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 643 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 644 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 645 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 646 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 647 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 648 | CLANG_WARN_STRICT_PROTOTYPES = YES; 649 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 650 | CLANG_WARN_UNREACHABLE_CODE = YES; 651 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 652 | CODE_SIGN_IDENTITY = ""; 653 | CODE_SIGN_STYLE = Manual; 654 | COPY_PHASE_STRIP = YES; 655 | DEAD_CODE_STRIPPING = YES; 656 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 657 | ENABLE_NS_ASSERTIONS = NO; 658 | ENABLE_STRICT_OBJC_MSGSEND = YES; 659 | GCC_C_LANGUAGE_STANDARD = gnu99; 660 | GCC_NO_COMMON_BLOCKS = YES; 661 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 662 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 663 | GCC_WARN_UNDECLARED_SELECTOR = YES; 664 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 665 | GCC_WARN_UNUSED_FUNCTION = YES; 666 | GCC_WARN_UNUSED_VARIABLE = YES; 667 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 668 | MTL_ENABLE_DEBUG_INFO = NO; 669 | SWIFT_COMPILATION_MODE = wholemodule; 670 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 671 | TVOS_DEPLOYMENT_TARGET = 13.0; 672 | VALIDATE_PRODUCT = YES; 673 | }; 674 | name = Release; 675 | }; 676 | B94B1B0421CD38B400FF1B72 /* Debug */ = { 677 | isa = XCBuildConfiguration; 678 | buildSettings = { 679 | APPLICATION_EXTENSION_API_ONLY = YES; 680 | CLANG_ANALYZER_NONNULL = YES; 681 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 682 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 683 | CLANG_ENABLE_OBJC_WEAK = YES; 684 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 685 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 686 | CURRENT_PROJECT_VERSION = 37; 687 | DEBUG_INFORMATION_FORMAT = dwarf; 688 | DEFINES_MODULE = YES; 689 | DYLIB_COMPATIBILITY_VERSION = 1; 690 | DYLIB_CURRENT_VERSION = 37; 691 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 692 | ENABLE_MODULE_VERIFIER = YES; 693 | GCC_C_LANGUAGE_STANDARD = gnu11; 694 | INFOPLIST_FILE = Source/Info.plist; 695 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 696 | LD_RUNPATH_SEARCH_PATHS = ( 697 | "$(inherited)", 698 | "@executable_path/Frameworks", 699 | "@loader_path/Frameworks", 700 | ); 701 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 702 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14"; 703 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 704 | MTL_FAST_MATH = YES; 705 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus; 706 | PRODUCT_MODULE_NAME = "$(PRODUCT_NAME:c99extidentifier)"; 707 | PRODUCT_NAME = Columbus; 708 | SDKROOT = appletvos; 709 | SKIP_INSTALL = YES; 710 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 711 | SWIFT_VERSION = 5.0; 712 | VERSIONING_SYSTEM = "apple-generic"; 713 | VERSION_INFO_PREFIX = ""; 714 | }; 715 | name = Debug; 716 | }; 717 | B94B1B0521CD38B400FF1B72 /* Release */ = { 718 | isa = XCBuildConfiguration; 719 | buildSettings = { 720 | APPLICATION_EXTENSION_API_ONLY = YES; 721 | BUILD_LIBRARY_FOR_DISTRIBUTION = YES; 722 | CLANG_ANALYZER_NONNULL = YES; 723 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 724 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 725 | CLANG_ENABLE_OBJC_WEAK = YES; 726 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 727 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 728 | CURRENT_PROJECT_VERSION = 37; 729 | DEFINES_MODULE = YES; 730 | DYLIB_COMPATIBILITY_VERSION = 1; 731 | DYLIB_CURRENT_VERSION = 37; 732 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 733 | ENABLE_MODULE_VERIFIER = YES; 734 | GCC_C_LANGUAGE_STANDARD = gnu11; 735 | INFOPLIST_FILE = Source/Info.plist; 736 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 737 | LD_RUNPATH_SEARCH_PATHS = ( 738 | "$(inherited)", 739 | "@executable_path/Frameworks", 740 | "@loader_path/Frameworks", 741 | ); 742 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 743 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14"; 744 | MTL_FAST_MATH = YES; 745 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus; 746 | PRODUCT_MODULE_NAME = "$(PRODUCT_NAME:c99extidentifier)"; 747 | PRODUCT_NAME = Columbus; 748 | SDKROOT = appletvos; 749 | SKIP_INSTALL = NO; 750 | SWIFT_VERSION = 5.0; 751 | VERSIONING_SYSTEM = "apple-generic"; 752 | VERSION_INFO_PREFIX = ""; 753 | }; 754 | name = Release; 755 | }; 756 | B96D496021CD3DC20010E69B /* Debug */ = { 757 | isa = XCBuildConfiguration; 758 | buildSettings = { 759 | CLANG_ANALYZER_NONNULL = YES; 760 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 761 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 762 | CLANG_ENABLE_OBJC_WEAK = YES; 763 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 764 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 765 | COMBINE_HIDPI_IMAGES = YES; 766 | DEBUG_INFORMATION_FORMAT = dwarf; 767 | GCC_C_LANGUAGE_STANDARD = gnu11; 768 | INFOPLIST_FILE = Source/Resources/Info.plist; 769 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 770 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 771 | MTL_FAST_MATH = YES; 772 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus.resources; 773 | PRODUCT_NAME = Resources; 774 | SDKROOT = iphoneos; 775 | SKIP_INSTALL = YES; 776 | WRAPPER_EXTENSION = bundle; 777 | }; 778 | name = Debug; 779 | }; 780 | B96D496121CD3DC20010E69B /* Release */ = { 781 | isa = XCBuildConfiguration; 782 | buildSettings = { 783 | CLANG_ANALYZER_NONNULL = YES; 784 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 785 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 786 | CLANG_ENABLE_OBJC_WEAK = YES; 787 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 788 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 789 | COMBINE_HIDPI_IMAGES = YES; 790 | GCC_C_LANGUAGE_STANDARD = gnu11; 791 | INFOPLIST_FILE = Source/Resources/Info.plist; 792 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 793 | MTL_FAST_MATH = YES; 794 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus.resources; 795 | PRODUCT_NAME = Resources; 796 | SDKROOT = iphoneos; 797 | SKIP_INSTALL = YES; 798 | WRAPPER_EXTENSION = bundle; 799 | }; 800 | name = Release; 801 | }; 802 | B9A4A67621D145EB001FF5DC /* Debug */ = { 803 | isa = XCBuildConfiguration; 804 | buildSettings = { 805 | CLANG_ANALYZER_NONNULL = YES; 806 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 807 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 808 | CLANG_ENABLE_OBJC_WEAK = YES; 809 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 810 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 811 | COMBINE_HIDPI_IMAGES = YES; 812 | DEBUG_INFORMATION_FORMAT = dwarf; 813 | GCC_C_LANGUAGE_STANDARD = gnu11; 814 | INFOPLIST_FILE = Source/Resources/Info.plist; 815 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 816 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 817 | MTL_FAST_MATH = YES; 818 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus.resources; 819 | PRODUCT_NAME = Resources; 820 | SDKROOT = appletvos; 821 | SKIP_INSTALL = YES; 822 | WRAPPER_EXTENSION = bundle; 823 | }; 824 | name = Debug; 825 | }; 826 | B9A4A67721D145EB001FF5DC /* Release */ = { 827 | isa = XCBuildConfiguration; 828 | buildSettings = { 829 | CLANG_ANALYZER_NONNULL = YES; 830 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 831 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 832 | CLANG_ENABLE_OBJC_WEAK = YES; 833 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 834 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 835 | COMBINE_HIDPI_IMAGES = YES; 836 | GCC_C_LANGUAGE_STANDARD = gnu11; 837 | INFOPLIST_FILE = Source/Resources/Info.plist; 838 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 839 | MTL_FAST_MATH = YES; 840 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus.resources; 841 | PRODUCT_NAME = Resources; 842 | SDKROOT = appletvos; 843 | SKIP_INSTALL = YES; 844 | WRAPPER_EXTENSION = bundle; 845 | }; 846 | name = Release; 847 | }; 848 | B9DB81FA21D0E9F500A39677 /* Debug */ = { 849 | isa = XCBuildConfiguration; 850 | buildSettings = { 851 | CLANG_ANALYZER_NONNULL = YES; 852 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 853 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 854 | CLANG_ENABLE_OBJC_WEAK = YES; 855 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 856 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 857 | DEBUG_INFORMATION_FORMAT = dwarf; 858 | GCC_C_LANGUAGE_STANDARD = gnu11; 859 | INFOPLIST_FILE = Tests/Info.plist; 860 | LD_RUNPATH_SEARCH_PATHS = ( 861 | "$(inherited)", 862 | "@executable_path/Frameworks", 863 | "@loader_path/Frameworks", 864 | ); 865 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 866 | MTL_FAST_MATH = YES; 867 | PRODUCT_BUNDLE_IDENTIFIER = com.stefanherold.ColumbusTests; 868 | PRODUCT_NAME = "$(TARGET_NAME)"; 869 | SDKROOT = appletvos; 870 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 871 | SWIFT_VERSION = 5.0; 872 | }; 873 | name = Debug; 874 | }; 875 | B9DB81FB21D0E9F500A39677 /* Release */ = { 876 | isa = XCBuildConfiguration; 877 | buildSettings = { 878 | CLANG_ANALYZER_NONNULL = YES; 879 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 880 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 881 | CLANG_ENABLE_OBJC_WEAK = YES; 882 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 883 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 884 | GCC_C_LANGUAGE_STANDARD = gnu11; 885 | INFOPLIST_FILE = Tests/Info.plist; 886 | LD_RUNPATH_SEARCH_PATHS = ( 887 | "$(inherited)", 888 | "@executable_path/Frameworks", 889 | "@loader_path/Frameworks", 890 | ); 891 | MTL_FAST_MATH = YES; 892 | PRODUCT_BUNDLE_IDENTIFIER = com.stefanherold.ColumbusTests; 893 | PRODUCT_NAME = "$(TARGET_NAME)"; 894 | SDKROOT = appletvos; 895 | SWIFT_VERSION = 5.0; 896 | }; 897 | name = Release; 898 | }; 899 | B9F8788921CD28A200273F82 /* Debug */ = { 900 | isa = XCBuildConfiguration; 901 | buildSettings = { 902 | APPLICATION_EXTENSION_API_ONLY = YES; 903 | CLANG_ANALYZER_NONNULL = YES; 904 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 905 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 906 | CLANG_ENABLE_OBJC_WEAK = YES; 907 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 908 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 909 | CURRENT_PROJECT_VERSION = 37; 910 | DEBUG_INFORMATION_FORMAT = dwarf; 911 | DEFINES_MODULE = YES; 912 | DYLIB_COMPATIBILITY_VERSION = 1; 913 | DYLIB_CURRENT_VERSION = 37; 914 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 915 | ENABLE_MODULE_VERIFIER = YES; 916 | GCC_C_LANGUAGE_STANDARD = gnu11; 917 | INFOPLIST_FILE = Source/Info.plist; 918 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 919 | LD_RUNPATH_SEARCH_PATHS = ( 920 | "$(inherited)", 921 | "@executable_path/Frameworks", 922 | "@loader_path/Frameworks", 923 | ); 924 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 925 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14"; 926 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 927 | MTL_FAST_MATH = YES; 928 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus; 929 | PRODUCT_MODULE_NAME = "$(PRODUCT_NAME:c99extidentifier)"; 930 | PRODUCT_NAME = Columbus; 931 | SDKROOT = iphoneos; 932 | SKIP_INSTALL = YES; 933 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 934 | SWIFT_VERSION = 5.0; 935 | TARGETED_DEVICE_FAMILY = "1,2"; 936 | VERSIONING_SYSTEM = "apple-generic"; 937 | VERSION_INFO_PREFIX = ""; 938 | }; 939 | name = Debug; 940 | }; 941 | B9F8788A21CD28A200273F82 /* Release */ = { 942 | isa = XCBuildConfiguration; 943 | buildSettings = { 944 | APPLICATION_EXTENSION_API_ONLY = YES; 945 | BUILD_LIBRARY_FOR_DISTRIBUTION = YES; 946 | CLANG_ANALYZER_NONNULL = YES; 947 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 948 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 949 | CLANG_ENABLE_OBJC_WEAK = YES; 950 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 951 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 952 | CURRENT_PROJECT_VERSION = 37; 953 | DEFINES_MODULE = YES; 954 | DYLIB_COMPATIBILITY_VERSION = 1; 955 | DYLIB_CURRENT_VERSION = 37; 956 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 957 | ENABLE_MODULE_VERIFIER = YES; 958 | GCC_C_LANGUAGE_STANDARD = gnu11; 959 | INFOPLIST_FILE = Source/Info.plist; 960 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 961 | LD_RUNPATH_SEARCH_PATHS = ( 962 | "$(inherited)", 963 | "@executable_path/Frameworks", 964 | "@loader_path/Frameworks", 965 | ); 966 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 967 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14"; 968 | MTL_FAST_MATH = YES; 969 | PRODUCT_BUNDLE_IDENTIFIER = com.stherold.columbus; 970 | PRODUCT_MODULE_NAME = "$(PRODUCT_NAME:c99extidentifier)"; 971 | PRODUCT_NAME = Columbus; 972 | SDKROOT = iphoneos; 973 | SKIP_INSTALL = NO; 974 | SWIFT_VERSION = 5.0; 975 | TARGETED_DEVICE_FAMILY = "1,2"; 976 | VERSIONING_SYSTEM = "apple-generic"; 977 | VERSION_INFO_PREFIX = ""; 978 | }; 979 | name = Release; 980 | }; 981 | B9F878B521CD2A4E00273F82 /* Debug */ = { 982 | isa = XCBuildConfiguration; 983 | buildSettings = { 984 | CLANG_ANALYZER_NONNULL = YES; 985 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 986 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 987 | CLANG_ENABLE_OBJC_WEAK = YES; 988 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 989 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 990 | DEBUG_INFORMATION_FORMAT = dwarf; 991 | GCC_C_LANGUAGE_STANDARD = gnu11; 992 | INFOPLIST_FILE = Tests/Info.plist; 993 | LD_RUNPATH_SEARCH_PATHS = ( 994 | "$(inherited)", 995 | "@executable_path/Frameworks", 996 | "@loader_path/Frameworks", 997 | ); 998 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 999 | MTL_FAST_MATH = YES; 1000 | PRODUCT_BUNDLE_IDENTIFIER = com.stefanherold.ColumbusTests; 1001 | PRODUCT_NAME = "$(TARGET_NAME)"; 1002 | SDKROOT = iphoneos; 1003 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1004 | SWIFT_VERSION = 5.0; 1005 | TARGETED_DEVICE_FAMILY = "1,2"; 1006 | }; 1007 | name = Debug; 1008 | }; 1009 | B9F878B621CD2A4E00273F82 /* Release */ = { 1010 | isa = XCBuildConfiguration; 1011 | buildSettings = { 1012 | CLANG_ANALYZER_NONNULL = YES; 1013 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1014 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1015 | CLANG_ENABLE_OBJC_WEAK = YES; 1016 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1017 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1018 | GCC_C_LANGUAGE_STANDARD = gnu11; 1019 | INFOPLIST_FILE = Tests/Info.plist; 1020 | LD_RUNPATH_SEARCH_PATHS = ( 1021 | "$(inherited)", 1022 | "@executable_path/Frameworks", 1023 | "@loader_path/Frameworks", 1024 | ); 1025 | MTL_FAST_MATH = YES; 1026 | PRODUCT_BUNDLE_IDENTIFIER = com.stefanherold.ColumbusTests; 1027 | PRODUCT_NAME = "$(TARGET_NAME)"; 1028 | SDKROOT = iphoneos; 1029 | SWIFT_VERSION = 5.0; 1030 | TARGETED_DEVICE_FAMILY = "1,2"; 1031 | }; 1032 | name = Release; 1033 | }; 1034 | /* End XCBuildConfiguration section */ 1035 | 1036 | /* Begin XCConfigurationList section */ 1037 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Columbus" */ = { 1038 | isa = XCConfigurationList; 1039 | buildConfigurations = ( 1040 | 607FACED1AFB9204008FA782 /* Debug */, 1041 | 607FACEE1AFB9204008FA782 /* Release */, 1042 | ); 1043 | defaultConfigurationIsVisible = 0; 1044 | defaultConfigurationName = Release; 1045 | }; 1046 | B94B1B0321CD38B400FF1B72 /* Build configuration list for PBXNativeTarget "Columbus-tvOS" */ = { 1047 | isa = XCConfigurationList; 1048 | buildConfigurations = ( 1049 | B94B1B0421CD38B400FF1B72 /* Debug */, 1050 | B94B1B0521CD38B400FF1B72 /* Release */, 1051 | ); 1052 | defaultConfigurationIsVisible = 0; 1053 | defaultConfigurationName = Release; 1054 | }; 1055 | B96D495F21CD3DC20010E69B /* Build configuration list for PBXNativeTarget "Resources-iOS" */ = { 1056 | isa = XCConfigurationList; 1057 | buildConfigurations = ( 1058 | B96D496021CD3DC20010E69B /* Debug */, 1059 | B96D496121CD3DC20010E69B /* Release */, 1060 | ); 1061 | defaultConfigurationIsVisible = 0; 1062 | defaultConfigurationName = Release; 1063 | }; 1064 | B9A4A67521D145EB001FF5DC /* Build configuration list for PBXNativeTarget "Resources-tvOS" */ = { 1065 | isa = XCConfigurationList; 1066 | buildConfigurations = ( 1067 | B9A4A67621D145EB001FF5DC /* Debug */, 1068 | B9A4A67721D145EB001FF5DC /* Release */, 1069 | ); 1070 | defaultConfigurationIsVisible = 0; 1071 | defaultConfigurationName = Release; 1072 | }; 1073 | B9DB81F921D0E9F500A39677 /* Build configuration list for PBXNativeTarget "Columbus-tvOS-Tests" */ = { 1074 | isa = XCConfigurationList; 1075 | buildConfigurations = ( 1076 | B9DB81FA21D0E9F500A39677 /* Debug */, 1077 | B9DB81FB21D0E9F500A39677 /* Release */, 1078 | ); 1079 | defaultConfigurationIsVisible = 0; 1080 | defaultConfigurationName = Release; 1081 | }; 1082 | B9F8788821CD28A200273F82 /* Build configuration list for PBXNativeTarget "Columbus-iOS" */ = { 1083 | isa = XCConfigurationList; 1084 | buildConfigurations = ( 1085 | B9F8788921CD28A200273F82 /* Debug */, 1086 | B9F8788A21CD28A200273F82 /* Release */, 1087 | ); 1088 | defaultConfigurationIsVisible = 0; 1089 | defaultConfigurationName = Release; 1090 | }; 1091 | B9F878B421CD2A4E00273F82 /* Build configuration list for PBXNativeTarget "Columbus-iOS-Tests" */ = { 1092 | isa = XCConfigurationList; 1093 | buildConfigurations = ( 1094 | B9F878B521CD2A4E00273F82 /* Debug */, 1095 | B9F878B621CD2A4E00273F82 /* Release */, 1096 | ); 1097 | defaultConfigurationIsVisible = 0; 1098 | defaultConfigurationName = Release; 1099 | }; 1100 | /* End XCConfigurationList section */ 1101 | }; 1102 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 1103 | } 1104 | --------------------------------------------------------------------------------