├── .DS_Store ├── OEMentionsExample ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── ViewController.swift ├── Info.plist ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard └── AppDelegate.swift ├── OEMentions.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── omar.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── omar.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── xcshareddata │ └── xcschemes │ │ ├── OEMentionsExample.xcscheme │ │ └── OEMentions.xcscheme └── project.pbxproj ├── .travis.yml ├── OEMentions ├── OEMentions.h ├── Info.plist └── OEMentions.swift ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── OEMentionsTests ├── Info.plist └── OEMentionsTests.swift ├── OEMentions.podspec ├── LICENSE ├── CODE_OF_CONDUCT.md └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omar14/OEMentions/HEAD/.DS_Store -------------------------------------------------------------------------------- /OEMentionsExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /OEMentions.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OEMentions.xcodeproj/project.xcworkspace/xcuserdata/omar.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omar14/OEMentions/HEAD/OEMentions.xcodeproj/project.xcworkspace/xcuserdata/omar.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /OEMentions.xcodeproj/xcuserdata/omar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /OEMentions.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | 3 | osx_image: xcode10.1 4 | env: 5 | matrix: 6 | - TEST_SDK=iphonesimulator12.1 OS=12.1 NAME='iPhone XR' 7 | - TEST_SDK=iphonesimulator12.1 OS=12.1 NAME='iPhone 7' 8 | 9 | script: 10 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -project OEMentions.xcodeproj -scheme OEMentions -sdk $TEST_SDK -destination "platform=iOS Simulator,OS=$OS,name=$NAME" ONLY_ACTIVE_ARCH=YES -------------------------------------------------------------------------------- /OEMentions/OEMentions.h: -------------------------------------------------------------------------------- 1 | // 2 | // OEMentions.h 3 | // OEMentions 4 | // 5 | // Created by Omar Alessa on 23/03/2019. 6 | // Copyright © 2019 Omar Alessa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for OEMentions. 12 | FOUNDATION_EXPORT double OEMentionsVersionNumber; 13 | 14 | //! Project version string for OEMentions. 15 | FOUNDATION_EXPORT const unsigned char OEMentionsVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /OEMentionsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /OEMentions/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 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /OEMentions.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | 3 | spec.name = "OEMentions" 4 | spec.version = "0.1.4" 5 | spec.summary = "An easy way to add mentions to UITextView like Facebook and Instagram" 6 | 7 | spec.description = <<-DESC 8 | An easy way to add mentions to UITextView like Facebook and Instagram. It also include a tableview to show the users list to choose from. The component is written in Swift. 9 | DESC 10 | 11 | spec.homepage = "https://github.com/omar14/OEMentions" 12 | spec.license = { :type => "MIT", :file => "LICENSE" } 13 | spec.author = { 'omar14' => 'omaressa10@gmail.com' } 14 | 15 | spec.ios.deployment_target = "13.0" 16 | spec.swift_version = "5.0" 17 | 18 | spec.source = { :git => 'https://github.com/omar14/OEMentions.git', :tag => "#{spec.version}" } 19 | spec.source_files = "OEMentions/**/*.{h,m,swift}" 20 | 21 | end -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /OEMentions.xcodeproj/xcuserdata/omar.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | OEMentions.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | OEMentionsExample.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 071978AC2246F7AF00A0F09D 21 | 22 | primary 23 | 24 | 25 | 0784A28E2246B1B400C32BFB 26 | 27 | primary 28 | 29 | 30 | 0784A2972246B1B400C32BFB 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Omar Alessa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /OEMentionsTests/OEMentionsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OEMentionsTests.swift 3 | // OEMentionsTests 4 | // 5 | // Created by Omar Alessa on 23/03/2019. 6 | // Copyright © 2019 Omar Alessa. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import OEMentions 11 | 12 | class OEMentionsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /OEMentionsExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // OEMentionsExample 4 | // 5 | // Created by Omar Alessa on 24/03/2019. 6 | // Copyright © 2019 Omar Alessa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import OEMentions 11 | 12 | class ViewController: UIViewController, OEMentionsDelegate { 13 | 14 | @IBOutlet weak var myContainer: UIView! 15 | @IBOutlet weak var myTextView: UITextView! 16 | 17 | var oeMentions:OEMentions! 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | let oeObjects = [OEObject(id: 1,name: "Elsie Easterling"), OEObject(id: 2,name: "Caterina Misiewicz"), OEObject(id: 3,name: "Ruben Dematteo")] 23 | 24 | oeMentions = OEMentions(containerView: myContainer, textView: myTextView, mainView: self.view, oeObjects: oeObjects) 25 | 26 | oeMentions.delegate = self 27 | 28 | myTextView.delegate = oeMentions 29 | 30 | } 31 | 32 | 33 | func mentionSelected(id: Int, name: String) { 34 | print("id \(id)") 35 | print("name \(name)") 36 | } 37 | 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /OEMentionsExample/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 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /OEMentionsExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /OEMentionsExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /OEMentionsExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // OEMentionsExample 4 | // 5 | // Created by Omar Alessa on 24/03/2019. 6 | // Copyright © 2019 Omar Alessa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /OEMentions.xcodeproj/xcshareddata/xcschemes/OEMentionsExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at omaressa10@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /OEMentions.xcodeproj/xcshareddata/xcschemes/OEMentions.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OEMentions 2 | 3 | [![Platforms](https://img.shields.io/badge/platform-iOS-yellow.svg)]() 4 | [![Language](https://img.shields.io/badge/language-Swift_5.0-orange.svg)]() 5 | [![CocoaPod](https://img.shields.io/badge/pod-0.1.4-lightblue.svg)](https://github.com/omar14/OEMentions/releases/tag/0.1.4) 6 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)]() 7 | 8 | An easy way to add mentions to uitextview like Facebook and Instagram. It also include a tableview to show the users list to choose from. The component is written in 9 | **Swift**. 10 | 11 | 12 | ![demo2_gif](https://cloud.githubusercontent.com/assets/3969198/17277971/849e7a16-5758-11e6-9589-d6f3f0a8c8e4.gif) 13 | ![demo3_gif](https://cloud.githubusercontent.com/assets/3969198/17277992/17f54448-5759-11e6-8107-ac5b0f9deb08.gif) 14 | 15 | 16 | 17 | ## Main features 18 | * Expandale UITextView (also expandle UITextView container) 19 | * Show and manage position of users list when "@" is typed ("@" can be changed to any character) 20 | * Customizable mention text 21 | 22 | 23 | ## Installation 24 | 25 | ### Cocoapods 26 | 27 | ```swift 28 | pod 'OEMentions' 29 | ``` 30 | 31 | ### Manual 32 | 33 | You can import `OEMentions.swift` file manually to your project folder 34 | 35 | 36 | ## Usage Example 37 | You can see a full implementation in ViewController.swift 38 | 39 | 1. Refrence UITextView outlet and "Optional: Container (UIView that has UITextView in it)" 40 | 41 | ```swift 42 | @IBOutlet weak var containerView: UIView! 43 | @IBOutlet weak var textView: UITextView! 44 | ``` 45 | 46 | 2. Create a OEMention variable 47 | 48 | ```swift 49 | var oeMentions:OEMentions! 50 | ``` 51 | 52 | 3. Create an OEObejct array that contain users info (id, name) 53 | 54 | ```swift 55 | let oeObjects = [OEObject(id: 1,name: "Elsie Easterling"), OEObject(id: 2,name: "Caterina Misiewicz"), OEObject(id: 3,name: "Ruben Dematteo")] 56 | ``` 57 | 58 | 4. Initialize the OEMentions 59 | 60 | ```swift 61 | oeMentions = OEMentions(containerView: containerView, textView: textView, mainView: self.view, oeObjects: oeObjects) 62 | ``` 63 | 64 | 5. Assign UITextView delegate to OEMentions 65 | 66 | ```swift 67 | textView.delegate = oeMentions 68 | ``` 69 | 70 | 6. (Optional) OEMentionsDelegate: delegate method for the chosen user 71 | 72 | ```swift 73 | class ViewController: UIViewController, OEMentionsDelegate 74 | ``` 75 | ```swift 76 | oeMentions.delegate = self 77 | ``` 78 | ```swift 79 | func mentionSelected(id:Int, name: String) { 80 | 81 | // Do something with selected id and name 82 | 83 | } 84 | ``` 85 | 86 | 87 | ## Customization 88 | 89 | ```swift 90 | changeMentionCharacter(character: String) 91 | ``` 92 | ```swift 93 | changeMentionTableviewBackground(color: UIColor) 94 | ``` 95 | ```swift 96 | // Color of the mention tableview name text 97 | OEMentions.nameColor 98 | // Font of the mention tableview name text 99 | OEMentions.nameFont 100 | // Rest of the UITextView text color 101 | OEMentions.notMentionColor 102 | ``` 103 | 104 | ## License 105 | 106 | MIT License 107 | 108 | Copyright (c) 2019 Omar Alessa 109 | 110 | Permission is hereby granted, free of charge, to any person obtaining a copy 111 | of this software and associated documentation files (the "Software"), to deal 112 | in the Software without restriction, including without limitation the rights 113 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 114 | copies of the Software, and to permit persons to whom the Software is 115 | furnished to do so, subject to the following conditions: 116 | 117 | The above copyright notice and this permission notice shall be included in all 118 | copies or substantial portions of the Software. 119 | 120 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 121 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 122 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 123 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 124 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 125 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 126 | SOFTWARE. 127 | -------------------------------------------------------------------------------- /OEMentionsExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /OEMentions/OEMentions.swift: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // OEMentions.swift 4 | // OEMentions 5 | // 6 | // Created by Omar Alessa on 7/31/16. 7 | // Copyright © 2019 omaressa. All rights reserved. 8 | // 9 | 10 | import UIKit 11 | 12 | public protocol OEMentionsDelegate 13 | { 14 | // To respond to the selected name 15 | func mentionSelected(id:Int, name:String) 16 | } 17 | 18 | 19 | public class OEMentions: NSObject, UITextViewDelegate, UITableViewDelegate, UITableViewDataSource { 20 | 21 | // UIViewController view 22 | var mainView:UIView? 23 | 24 | // UIView for the textview container 25 | var containerView:UIView? 26 | 27 | // The UITextView we want to add mention to 28 | var textView:UITextView? 29 | 30 | // List of names to show in the list 31 | var oeObjects:[OEObject]? 32 | 33 | // The list after the query filter 34 | var theFilteredList = [OEObject]() 35 | 36 | // [Index:Length] of added mentions to textview 37 | var mentionsIndexes = [Int:Int]() 38 | 39 | // Keep track if still searching for a name 40 | var isMentioning = Bool() 41 | 42 | // The search query 43 | var mentionQuery = String() 44 | 45 | // The start of mention index 46 | var startMentionIndex = Int() 47 | 48 | // Character that show the mention list (Default is "@"), It can be changed using changeMentionCharacter func 49 | private var mentionCharater = "@" 50 | 51 | // Keyboard hieght after it shows 52 | var keyboardHieght:CGFloat? 53 | 54 | 55 | // Mentions tableview 56 | var tableView: UITableView! 57 | 58 | //MARK: Customizable mention list properties 59 | 60 | // Color of the mention tableview name text 61 | var nameColor = UIColor.blue 62 | 63 | // Font of the mention tableview name text 64 | var nameFont = UIFont.boldSystemFont(ofSize: 14.0) 65 | 66 | // Color if the rest of the UITextView text 67 | var notMentionColor = UIColor.label 68 | 69 | 70 | // OEMention Delegate 71 | var delegate:OEMentionsDelegate? 72 | 73 | 74 | var textViewWidth:CGFloat? 75 | var textViewHieght:CGFloat? 76 | var textViewYPosition:CGFloat? 77 | 78 | var containerHieght:CGFloat? 79 | 80 | //MARK: - init 81 | 82 | //MARK: class init without container 83 | public init(textView:UITextView, mainView:UIView, oeObjects:[OEObject]){ 84 | super.init() 85 | 86 | self.mainView = mainView 87 | self.oeObjects = oeObjects 88 | self.textView = textView 89 | 90 | self.textViewWidth = textView.frame.width 91 | 92 | initMentionsList() 93 | 94 | NotificationCenter.default.addObserver( 95 | self, 96 | selector: #selector(OEMentions.keyboardWillShow(notification:)), 97 | name: UIResponder.keyboardWillShowNotification, 98 | object: nil) 99 | } 100 | 101 | //MARK: class init with container 102 | public init(containerView:UIView, textView:UITextView, mainView:UIView, oeObjects:[OEObject]){ 103 | super.init() 104 | 105 | self.containerView = containerView 106 | self.mainView = mainView 107 | self.oeObjects = oeObjects 108 | self.textView = textView 109 | 110 | self.containerHieght = containerView.frame.height 111 | 112 | self.textViewWidth = textView.frame.width 113 | self.textViewHieght = textView.frame.height 114 | self.textViewYPosition = textView.frame.origin.y 115 | 116 | initMentionsList() 117 | 118 | NotificationCenter.default.addObserver(self, selector: #selector(OEMentions.keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil) 119 | } 120 | 121 | 122 | //MARK: - UITextView delegate functions: 123 | 124 | public func textViewDidEndEditing(_ textView: UITextView) { 125 | 126 | self.mentionQuery = "" 127 | self.isMentioning = false 128 | UIView.animate(withDuration: 0.2, animations: { 129 | self.tableView.isHidden = true 130 | }) 131 | 132 | } 133 | 134 | public func textViewDidChange(_ textView: UITextView) { 135 | updatePosition() 136 | } 137 | 138 | public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { 139 | 140 | let str = String(textView.text) 141 | var lastCharacter = "nothing" 142 | 143 | if !str.isEmpty && range.location != 0{ 144 | lastCharacter = String(str[str.index(before: str.endIndex)]) 145 | } 146 | 147 | // Check if there is mentions 148 | if mentionsIndexes.count != 0 { 149 | 150 | for (index,length) in mentionsIndexes { 151 | 152 | if case index ... index+length = range.location { 153 | // If start typing within a mention rang delete that name: 154 | 155 | textView.replace(textView.textRangeFromNSRange(range: NSMakeRange(index, length))!, withText: "") 156 | mentionsIndexes.removeValue(forKey: index) 157 | } 158 | 159 | } 160 | } 161 | 162 | 163 | if isMentioning { 164 | if text == " " || (text.count == 0 && self.mentionQuery == ""){ // If Space or delete the "@" 165 | self.mentionQuery = "" 166 | self.isMentioning = false 167 | UIView.animate(withDuration: 0.2, animations: { 168 | 169 | self.tableView.isHidden = true 170 | 171 | }) 172 | } 173 | else if text.count == 0 { 174 | self.mentionQuery.remove(at: self.mentionQuery.index(before: self.mentionQuery.endIndex)) 175 | self.filterList(query: self.mentionQuery) 176 | self.tableView.reloadData() 177 | } 178 | else { 179 | self.mentionQuery += text 180 | self.filterList(query: self.mentionQuery) 181 | self.tableView.reloadData() 182 | } 183 | } else { 184 | 185 | /* (Beginning of textView) OR (space then @) OR (Beginning of new line) */ 186 | if text == self.mentionCharater && ( range.location == 0 || lastCharacter == " " || lastCharacter == "\n") { 187 | 188 | self.isMentioning = true 189 | self.startMentionIndex = range.location 190 | theFilteredList = oeObjects! 191 | self.tableView.reloadData() 192 | UIView.animate(withDuration: 0.2, animations: { 193 | self.tableView.isHidden = false 194 | }) 195 | 196 | } 197 | } 198 | 199 | return true 200 | } 201 | 202 | 203 | 204 | //MARK: - Keyboard will show NSNotification: 205 | 206 | @objc public func keyboardWillShow(notification:NSNotification) { 207 | 208 | let userInfo:NSDictionary = notification.userInfo! as NSDictionary 209 | let keyboardFrame:NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue 210 | let keyboardRectangle = keyboardFrame.cgRectValue 211 | let thekeyboardHeight = keyboardRectangle.height 212 | self.keyboardHieght = thekeyboardHeight 213 | 214 | UIView.animate(withDuration: 0.3, animations: { 215 | 216 | self.updatePosition() 217 | 218 | }) 219 | 220 | } 221 | 222 | 223 | 224 | //MARK: - UITableView deleget functions: 225 | 226 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 227 | return self.theFilteredList.count 228 | } 229 | 230 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 231 | let cell:UITableViewCell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell") 232 | cell.backgroundColor = UIColor.clear 233 | cell.selectionStyle = UITableViewCell.SelectionStyle.none 234 | cell.textLabel!.text = theFilteredList[indexPath.row].name 235 | 236 | return cell 237 | } 238 | 239 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 240 | addMentionToTextView(name: theFilteredList[indexPath.row].name!) 241 | 242 | if delegate != nil { 243 | self.delegate!.mentionSelected(id: theFilteredList[indexPath.row].id!, name: theFilteredList[indexPath.row].name!) 244 | } 245 | 246 | self.mentionQuery = "" 247 | self.isMentioning = false 248 | self.theFilteredList = oeObjects! 249 | UIView.animate(withDuration: 0.2, animations: { 250 | self.tableView.isHidden = true 251 | }) 252 | } 253 | 254 | // Add a mention name to the UITextView 255 | public func addMentionToTextView(name: String){ 256 | 257 | mentionsIndexes[self.startMentionIndex] = name.count 258 | 259 | let range: Range = self.textView!.text.range(of: "@" + self.mentionQuery)! 260 | self.textView!.text.replaceSubrange(range, with: name) 261 | 262 | let theText = self.textView!.text + " " 263 | 264 | let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: theText) 265 | 266 | 267 | // Add color attribute for the whole text 268 | if let count = self.textView?.text.count { 269 | attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: notMentionColor, range: NSMakeRange(0, count)) 270 | } 271 | 272 | 273 | // Add color & font attributes for the mention 274 | for (startIndex, length) in mentionsIndexes { 275 | attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: nameColor, range: NSMakeRange(startIndex, length)) 276 | attributedString.addAttribute(NSAttributedString.Key.font, value: nameFont, range: NSMakeRange(startIndex, length)) 277 | } 278 | 279 | 280 | // Add color attribute the next text 281 | if let count = self.textView?.text.count { 282 | attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: notMentionColor, range: NSMakeRange(count, 1)) 283 | } 284 | 285 | 286 | self.textView!.attributedText = attributedString 287 | 288 | updatePosition() 289 | 290 | } 291 | 292 | //MARK: - Utilities 293 | 294 | 295 | //Mentions UITableView init 296 | public func initMentionsList(){ 297 | 298 | tableView = UITableView(frame: CGRect(x: 0, y: 0, width: self.mainView!.frame.width, height: 100), style: UITableView.Style.plain) 299 | tableView.delegate = self 300 | tableView.dataSource = self 301 | tableView.tableFooterView = UIView() 302 | tableView.allowsSelection = true 303 | tableView.separatorColor = UIColor.clear 304 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 305 | self.mainView!.addSubview(self.tableView) 306 | 307 | self.tableView.isHidden = true 308 | } 309 | 310 | 311 | public func filterList(query: String) { 312 | 313 | theFilteredList.removeAll() 314 | 315 | if query.isEmpty { 316 | theFilteredList = oeObjects! 317 | } 318 | 319 | if let myOEobjects = oeObjects { 320 | for object in myOEobjects { 321 | if object.name?.lowercased().contains(query.lowercased()) ?? false { 322 | theFilteredList.append(object) 323 | } 324 | } 325 | } 326 | 327 | } 328 | 329 | // Set the mention character. Should be one character only, default is "@" 330 | public func changeMentionCharacter(character: String){ 331 | if character.count == 1 && character != " " { 332 | self.mentionCharater = character 333 | } 334 | } 335 | 336 | // Change tableview background color 337 | public func changeMentionTableviewBackground(color: UIColor){ 338 | self.tableView.backgroundColor = color 339 | } 340 | 341 | // Update views potision for the textview and tableview 342 | public func updatePosition(){ 343 | 344 | if containerView != nil { 345 | 346 | self.containerView!.frame.size.height = self.containerHieght! + ( self.textView!.frame.height - self.textViewHieght! ) 347 | self.containerView!.frame.origin.y = UIScreen.main.bounds.height - self.keyboardHieght! - self.containerView!.frame.height 348 | 349 | self.textView!.frame.origin.y = self.textViewYPosition! 350 | 351 | self.tableView.frame.size.height = UIScreen.main.bounds.height - self.keyboardHieght! - self.containerView!.frame.size.height 352 | } 353 | else { 354 | self.textView!.frame.origin.y = UIScreen.main.bounds.height - self.keyboardHieght! - self.textView!.frame.height 355 | self.tableView.frame.size.height = UIScreen.main.bounds.height - self.keyboardHieght! - self.textView!.frame.height 356 | } 357 | 358 | 359 | } 360 | 361 | } 362 | 363 | 364 | // OEMentions object (id,name) 365 | 366 | public class OEObject { 367 | 368 | var id:Int? 369 | var name:String? 370 | 371 | public init(id:Int, name:String){ 372 | self.id = id 373 | self.name = name 374 | } 375 | 376 | } 377 | 378 | 379 | extension UITextView 380 | { 381 | public func textRangeFromNSRange(range:NSRange) -> UITextRange? 382 | { 383 | let beginning = self.beginningOfDocument 384 | guard let start = self.position(from: beginning, offset: range.location), let end = self.position(from: start, offset: range.length) else { return nil} 385 | return self.textRange(from: start, to: end) 386 | } 387 | } 388 | -------------------------------------------------------------------------------- /OEMentions.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 071978B02246F7AF00A0F09D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071978AF2246F7AF00A0F09D /* AppDelegate.swift */; }; 11 | 071978B22246F7AF00A0F09D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071978B12246F7AF00A0F09D /* ViewController.swift */; }; 12 | 071978B52246F7AF00A0F09D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 071978B32246F7AF00A0F09D /* Main.storyboard */; }; 13 | 071978B72246F7AF00A0F09D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 071978B62246F7AF00A0F09D /* Assets.xcassets */; }; 14 | 071978BA2246F7AF00A0F09D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 071978B82246F7AF00A0F09D /* LaunchScreen.storyboard */; }; 15 | 071978BF2246F9BE00A0F09D /* OEMentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0784A2A92246B20100C32BFB /* OEMentions.swift */; }; 16 | 07218FC12370A4940013082B /* OEMentions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0784A28F2246B1B400C32BFB /* OEMentions.framework */; }; 17 | 07218FC22370A4940013082B /* OEMentions.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0784A28F2246B1B400C32BFB /* OEMentions.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | 0784A2992246B1B400C32BFB /* OEMentions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0784A28F2246B1B400C32BFB /* OEMentions.framework */; }; 19 | 0784A29E2246B1B400C32BFB /* OEMentionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0784A29D2246B1B400C32BFB /* OEMentionsTests.swift */; }; 20 | 0784A2A02246B1B400C32BFB /* OEMentions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0784A2922246B1B400C32BFB /* OEMentions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 0784A2AA2246B20100C32BFB /* OEMentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0784A2A92246B20100C32BFB /* OEMentions.swift */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 07218FC32370A4940013082B /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 0784A2862246B1B400C32BFB /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 0784A28E2246B1B400C32BFB; 30 | remoteInfo = OEMentions; 31 | }; 32 | 0784A29A2246B1B400C32BFB /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 0784A2862246B1B400C32BFB /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 0784A28E2246B1B400C32BFB; 37 | remoteInfo = OEMentions; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 07218FC52370A4940013082B /* Embed Frameworks */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | 07218FC22370A4940013082B /* OEMentions.framework in Embed Frameworks */, 49 | ); 50 | name = "Embed Frameworks"; 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXCopyFilesBuildPhase section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 071978AD2246F7AF00A0F09D /* OEMentionsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OEMentionsExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | 071978AF2246F7AF00A0F09D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 58 | 071978B12246F7AF00A0F09D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 59 | 071978B42246F7AF00A0F09D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 60 | 071978B62246F7AF00A0F09D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 61 | 071978B92246F7AF00A0F09D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 62 | 071978BB2246F7AF00A0F09D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | 0784A28F2246B1B400C32BFB /* OEMentions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OEMentions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 0784A2922246B1B400C32BFB /* OEMentions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OEMentions.h; sourceTree = ""; }; 65 | 0784A2932246B1B400C32BFB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 0784A2982246B1B400C32BFB /* OEMentionsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OEMentionsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 0784A29D2246B1B400C32BFB /* OEMentionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OEMentionsTests.swift; sourceTree = ""; }; 68 | 0784A29F2246B1B400C32BFB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | 0784A2A92246B20100C32BFB /* OEMentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OEMentions.swift; sourceTree = ""; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | 071978AA2246F7AF00A0F09D /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | 07218FC12370A4940013082B /* OEMentions.framework in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 0784A28C2246B1B400C32BFB /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | 0784A2952246B1B400C32BFB /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | 0784A2992246B1B400C32BFB /* OEMentions.framework in Frameworks */, 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | /* End PBXFrameworksBuildPhase section */ 97 | 98 | /* Begin PBXGroup section */ 99 | 071978AE2246F7AF00A0F09D /* OEMentionsExample */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 071978AF2246F7AF00A0F09D /* AppDelegate.swift */, 103 | 071978B12246F7AF00A0F09D /* ViewController.swift */, 104 | 071978B32246F7AF00A0F09D /* Main.storyboard */, 105 | 071978B62246F7AF00A0F09D /* Assets.xcassets */, 106 | 071978B82246F7AF00A0F09D /* LaunchScreen.storyboard */, 107 | 071978BB2246F7AF00A0F09D /* Info.plist */, 108 | ); 109 | path = OEMentionsExample; 110 | sourceTree = ""; 111 | }; 112 | 07218FC02370A4940013082B /* Frameworks */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | ); 116 | name = Frameworks; 117 | sourceTree = ""; 118 | }; 119 | 0784A2852246B1B400C32BFB = { 120 | isa = PBXGroup; 121 | children = ( 122 | 0784A2912246B1B400C32BFB /* OEMentions */, 123 | 0784A29C2246B1B400C32BFB /* OEMentionsTests */, 124 | 071978AE2246F7AF00A0F09D /* OEMentionsExample */, 125 | 0784A2902246B1B400C32BFB /* Products */, 126 | 07218FC02370A4940013082B /* Frameworks */, 127 | ); 128 | sourceTree = ""; 129 | }; 130 | 0784A2902246B1B400C32BFB /* Products */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 0784A28F2246B1B400C32BFB /* OEMentions.framework */, 134 | 0784A2982246B1B400C32BFB /* OEMentionsTests.xctest */, 135 | 071978AD2246F7AF00A0F09D /* OEMentionsExample.app */, 136 | ); 137 | name = Products; 138 | sourceTree = ""; 139 | }; 140 | 0784A2912246B1B400C32BFB /* OEMentions */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 0784A2922246B1B400C32BFB /* OEMentions.h */, 144 | 0784A2932246B1B400C32BFB /* Info.plist */, 145 | 0784A2A92246B20100C32BFB /* OEMentions.swift */, 146 | ); 147 | path = OEMentions; 148 | sourceTree = ""; 149 | }; 150 | 0784A29C2246B1B400C32BFB /* OEMentionsTests */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 0784A29D2246B1B400C32BFB /* OEMentionsTests.swift */, 154 | 0784A29F2246B1B400C32BFB /* Info.plist */, 155 | ); 156 | path = OEMentionsTests; 157 | sourceTree = ""; 158 | }; 159 | /* End PBXGroup section */ 160 | 161 | /* Begin PBXHeadersBuildPhase section */ 162 | 0784A28A2246B1B400C32BFB /* Headers */ = { 163 | isa = PBXHeadersBuildPhase; 164 | buildActionMask = 2147483647; 165 | files = ( 166 | 0784A2A02246B1B400C32BFB /* OEMentions.h in Headers */, 167 | ); 168 | runOnlyForDeploymentPostprocessing = 0; 169 | }; 170 | /* End PBXHeadersBuildPhase section */ 171 | 172 | /* Begin PBXNativeTarget section */ 173 | 071978AC2246F7AF00A0F09D /* OEMentionsExample */ = { 174 | isa = PBXNativeTarget; 175 | buildConfigurationList = 071978BE2246F7AF00A0F09D /* Build configuration list for PBXNativeTarget "OEMentionsExample" */; 176 | buildPhases = ( 177 | 071978A92246F7AF00A0F09D /* Sources */, 178 | 071978AA2246F7AF00A0F09D /* Frameworks */, 179 | 071978AB2246F7AF00A0F09D /* Resources */, 180 | 07218FC52370A4940013082B /* Embed Frameworks */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | 07218FC42370A4940013082B /* PBXTargetDependency */, 186 | ); 187 | name = OEMentionsExample; 188 | productName = OEMentionsExample; 189 | productReference = 071978AD2246F7AF00A0F09D /* OEMentionsExample.app */; 190 | productType = "com.apple.product-type.application"; 191 | }; 192 | 0784A28E2246B1B400C32BFB /* OEMentions */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 0784A2A32246B1B400C32BFB /* Build configuration list for PBXNativeTarget "OEMentions" */; 195 | buildPhases = ( 196 | 0784A28A2246B1B400C32BFB /* Headers */, 197 | 0784A28B2246B1B400C32BFB /* Sources */, 198 | 0784A28C2246B1B400C32BFB /* Frameworks */, 199 | 0784A28D2246B1B400C32BFB /* Resources */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | ); 205 | name = OEMentions; 206 | productName = OEMentions; 207 | productReference = 0784A28F2246B1B400C32BFB /* OEMentions.framework */; 208 | productType = "com.apple.product-type.framework"; 209 | }; 210 | 0784A2972246B1B400C32BFB /* OEMentionsTests */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 0784A2A62246B1B400C32BFB /* Build configuration list for PBXNativeTarget "OEMentionsTests" */; 213 | buildPhases = ( 214 | 0784A2942246B1B400C32BFB /* Sources */, 215 | 0784A2952246B1B400C32BFB /* Frameworks */, 216 | 0784A2962246B1B400C32BFB /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | 0784A29B2246B1B400C32BFB /* PBXTargetDependency */, 222 | ); 223 | name = OEMentionsTests; 224 | productName = OEMentionsTests; 225 | productReference = 0784A2982246B1B400C32BFB /* OEMentionsTests.xctest */; 226 | productType = "com.apple.product-type.bundle.unit-test"; 227 | }; 228 | /* End PBXNativeTarget section */ 229 | 230 | /* Begin PBXProject section */ 231 | 0784A2862246B1B400C32BFB /* Project object */ = { 232 | isa = PBXProject; 233 | attributes = { 234 | LastSwiftUpdateCheck = 1010; 235 | LastUpgradeCheck = 1010; 236 | ORGANIZATIONNAME = "Omar Alessa"; 237 | TargetAttributes = { 238 | 071978AC2246F7AF00A0F09D = { 239 | CreatedOnToolsVersion = 10.1; 240 | }; 241 | 0784A28E2246B1B400C32BFB = { 242 | CreatedOnToolsVersion = 10.1; 243 | LastSwiftMigration = 1010; 244 | }; 245 | 0784A2972246B1B400C32BFB = { 246 | CreatedOnToolsVersion = 10.1; 247 | }; 248 | }; 249 | }; 250 | buildConfigurationList = 0784A2892246B1B400C32BFB /* Build configuration list for PBXProject "OEMentions" */; 251 | compatibilityVersion = "Xcode 9.3"; 252 | developmentRegion = en; 253 | hasScannedForEncodings = 0; 254 | knownRegions = ( 255 | en, 256 | Base, 257 | ); 258 | mainGroup = 0784A2852246B1B400C32BFB; 259 | productRefGroup = 0784A2902246B1B400C32BFB /* Products */; 260 | projectDirPath = ""; 261 | projectRoot = ""; 262 | targets = ( 263 | 0784A28E2246B1B400C32BFB /* OEMentions */, 264 | 0784A2972246B1B400C32BFB /* OEMentionsTests */, 265 | 071978AC2246F7AF00A0F09D /* OEMentionsExample */, 266 | ); 267 | }; 268 | /* End PBXProject section */ 269 | 270 | /* Begin PBXResourcesBuildPhase section */ 271 | 071978AB2246F7AF00A0F09D /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 071978BA2246F7AF00A0F09D /* LaunchScreen.storyboard in Resources */, 276 | 071978B72246F7AF00A0F09D /* Assets.xcassets in Resources */, 277 | 071978B52246F7AF00A0F09D /* Main.storyboard in Resources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | 0784A28D2246B1B400C32BFB /* Resources */ = { 282 | isa = PBXResourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | 0784A2962246B1B400C32BFB /* Resources */ = { 289 | isa = PBXResourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXResourcesBuildPhase section */ 296 | 297 | /* Begin PBXSourcesBuildPhase section */ 298 | 071978A92246F7AF00A0F09D /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 071978B22246F7AF00A0F09D /* ViewController.swift in Sources */, 303 | 071978BF2246F9BE00A0F09D /* OEMentions.swift in Sources */, 304 | 071978B02246F7AF00A0F09D /* AppDelegate.swift in Sources */, 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | }; 308 | 0784A28B2246B1B400C32BFB /* Sources */ = { 309 | isa = PBXSourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | 0784A2AA2246B20100C32BFB /* OEMentions.swift in Sources */, 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | 0784A2942246B1B400C32BFB /* Sources */ = { 317 | isa = PBXSourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | 0784A29E2246B1B400C32BFB /* OEMentionsTests.swift in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | /* End PBXSourcesBuildPhase section */ 325 | 326 | /* Begin PBXTargetDependency section */ 327 | 07218FC42370A4940013082B /* PBXTargetDependency */ = { 328 | isa = PBXTargetDependency; 329 | target = 0784A28E2246B1B400C32BFB /* OEMentions */; 330 | targetProxy = 07218FC32370A4940013082B /* PBXContainerItemProxy */; 331 | }; 332 | 0784A29B2246B1B400C32BFB /* PBXTargetDependency */ = { 333 | isa = PBXTargetDependency; 334 | target = 0784A28E2246B1B400C32BFB /* OEMentions */; 335 | targetProxy = 0784A29A2246B1B400C32BFB /* PBXContainerItemProxy */; 336 | }; 337 | /* End PBXTargetDependency section */ 338 | 339 | /* Begin PBXVariantGroup section */ 340 | 071978B32246F7AF00A0F09D /* Main.storyboard */ = { 341 | isa = PBXVariantGroup; 342 | children = ( 343 | 071978B42246F7AF00A0F09D /* Base */, 344 | ); 345 | name = Main.storyboard; 346 | sourceTree = ""; 347 | }; 348 | 071978B82246F7AF00A0F09D /* LaunchScreen.storyboard */ = { 349 | isa = PBXVariantGroup; 350 | children = ( 351 | 071978B92246F7AF00A0F09D /* Base */, 352 | ); 353 | name = LaunchScreen.storyboard; 354 | sourceTree = ""; 355 | }; 356 | /* End PBXVariantGroup section */ 357 | 358 | /* Begin XCBuildConfiguration section */ 359 | 071978BC2246F7AF00A0F09D /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | CODE_SIGN_STYLE = Automatic; 364 | CURRENT_PROJECT_VERSION = 2; 365 | DEVELOPMENT_TEAM = D4HUYC7CVS; 366 | INFOPLIST_FILE = OEMentionsExample/Info.plist; 367 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 368 | LD_RUNPATH_SEARCH_PATHS = ( 369 | "$(inherited)", 370 | "@executable_path/Frameworks", 371 | ); 372 | MARKETING_VERSION = 1.0.1; 373 | PRODUCT_BUNDLE_IDENTIFIER = omaressa.OEMentionsExample; 374 | PRODUCT_NAME = "$(TARGET_NAME)"; 375 | SWIFT_VERSION = 5.0; 376 | TARGETED_DEVICE_FAMILY = "1,2"; 377 | }; 378 | name = Debug; 379 | }; 380 | 071978BD2246F7AF00A0F09D /* Release */ = { 381 | isa = XCBuildConfiguration; 382 | buildSettings = { 383 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 384 | CODE_SIGN_STYLE = Automatic; 385 | CURRENT_PROJECT_VERSION = 2; 386 | DEVELOPMENT_TEAM = D4HUYC7CVS; 387 | INFOPLIST_FILE = OEMentionsExample/Info.plist; 388 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 389 | LD_RUNPATH_SEARCH_PATHS = ( 390 | "$(inherited)", 391 | "@executable_path/Frameworks", 392 | ); 393 | MARKETING_VERSION = 1.0.1; 394 | PRODUCT_BUNDLE_IDENTIFIER = omaressa.OEMentionsExample; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SWIFT_VERSION = 5.0; 397 | TARGETED_DEVICE_FAMILY = "1,2"; 398 | }; 399 | name = Release; 400 | }; 401 | 0784A2A12246B1B400C32BFB /* Debug */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ALWAYS_SEARCH_USER_PATHS = NO; 405 | CLANG_ANALYZER_NONNULL = YES; 406 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 408 | CLANG_CXX_LIBRARY = "libc++"; 409 | CLANG_ENABLE_MODULES = YES; 410 | CLANG_ENABLE_OBJC_ARC = YES; 411 | CLANG_ENABLE_OBJC_WEAK = YES; 412 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 413 | CLANG_WARN_BOOL_CONVERSION = YES; 414 | CLANG_WARN_COMMA = YES; 415 | CLANG_WARN_CONSTANT_CONVERSION = YES; 416 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 417 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 418 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 419 | CLANG_WARN_EMPTY_BODY = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INFINITE_RECURSION = YES; 422 | CLANG_WARN_INT_CONVERSION = YES; 423 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 424 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 425 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 426 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 427 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 428 | CLANG_WARN_STRICT_PROTOTYPES = YES; 429 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 430 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 431 | CLANG_WARN_UNREACHABLE_CODE = YES; 432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 433 | CODE_SIGN_IDENTITY = "iPhone Developer"; 434 | COPY_PHASE_STRIP = NO; 435 | CURRENT_PROJECT_VERSION = 1; 436 | DEBUG_INFORMATION_FORMAT = dwarf; 437 | ENABLE_STRICT_OBJC_MSGSEND = YES; 438 | ENABLE_TESTABILITY = YES; 439 | GCC_C_LANGUAGE_STANDARD = gnu11; 440 | GCC_DYNAMIC_NO_PIC = NO; 441 | GCC_NO_COMMON_BLOCKS = YES; 442 | GCC_OPTIMIZATION_LEVEL = 0; 443 | GCC_PREPROCESSOR_DEFINITIONS = ( 444 | "DEBUG=1", 445 | "$(inherited)", 446 | ); 447 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 448 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 449 | GCC_WARN_UNDECLARED_SELECTOR = YES; 450 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 451 | GCC_WARN_UNUSED_FUNCTION = YES; 452 | GCC_WARN_UNUSED_VARIABLE = YES; 453 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 454 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 455 | MTL_FAST_MATH = YES; 456 | ONLY_ACTIVE_ARCH = YES; 457 | SDKROOT = iphoneos; 458 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 459 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 460 | VERSIONING_SYSTEM = "apple-generic"; 461 | VERSION_INFO_PREFIX = ""; 462 | }; 463 | name = Debug; 464 | }; 465 | 0784A2A22246B1B400C32BFB /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ALWAYS_SEARCH_USER_PATHS = NO; 469 | CLANG_ANALYZER_NONNULL = YES; 470 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 471 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 472 | CLANG_CXX_LIBRARY = "libc++"; 473 | CLANG_ENABLE_MODULES = YES; 474 | CLANG_ENABLE_OBJC_ARC = YES; 475 | CLANG_ENABLE_OBJC_WEAK = YES; 476 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 477 | CLANG_WARN_BOOL_CONVERSION = YES; 478 | CLANG_WARN_COMMA = YES; 479 | CLANG_WARN_CONSTANT_CONVERSION = YES; 480 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 481 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 482 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 483 | CLANG_WARN_EMPTY_BODY = YES; 484 | CLANG_WARN_ENUM_CONVERSION = YES; 485 | CLANG_WARN_INFINITE_RECURSION = YES; 486 | CLANG_WARN_INT_CONVERSION = YES; 487 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 488 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 489 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 490 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 491 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 492 | CLANG_WARN_STRICT_PROTOTYPES = YES; 493 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 494 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 495 | CLANG_WARN_UNREACHABLE_CODE = YES; 496 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 497 | CODE_SIGN_IDENTITY = "iPhone Developer"; 498 | COPY_PHASE_STRIP = NO; 499 | CURRENT_PROJECT_VERSION = 1; 500 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 501 | ENABLE_NS_ASSERTIONS = NO; 502 | ENABLE_STRICT_OBJC_MSGSEND = YES; 503 | GCC_C_LANGUAGE_STANDARD = gnu11; 504 | GCC_NO_COMMON_BLOCKS = YES; 505 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 506 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 507 | GCC_WARN_UNDECLARED_SELECTOR = YES; 508 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 509 | GCC_WARN_UNUSED_FUNCTION = YES; 510 | GCC_WARN_UNUSED_VARIABLE = YES; 511 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 512 | MTL_ENABLE_DEBUG_INFO = NO; 513 | MTL_FAST_MATH = YES; 514 | SDKROOT = iphoneos; 515 | SWIFT_COMPILATION_MODE = wholemodule; 516 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 517 | VALIDATE_PRODUCT = YES; 518 | VERSIONING_SYSTEM = "apple-generic"; 519 | VERSION_INFO_PREFIX = ""; 520 | }; 521 | name = Release; 522 | }; 523 | 0784A2A42246B1B400C32BFB /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | CLANG_ENABLE_MODULES = YES; 527 | CODE_SIGN_IDENTITY = ""; 528 | CODE_SIGN_STYLE = Automatic; 529 | CURRENT_PROJECT_VERSION = 2; 530 | DEFINES_MODULE = YES; 531 | DYLIB_COMPATIBILITY_VERSION = 1; 532 | DYLIB_CURRENT_VERSION = 1; 533 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 534 | INFOPLIST_FILE = OEMentions/Info.plist; 535 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 536 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 537 | LD_RUNPATH_SEARCH_PATHS = ( 538 | "$(inherited)", 539 | "@executable_path/Frameworks", 540 | "@loader_path/Frameworks", 541 | ); 542 | MARKETING_VERSION = 1.0.1; 543 | PRODUCT_BUNDLE_IDENTIFIER = omaressa.OEMentions; 544 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 545 | SKIP_INSTALL = YES; 546 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 547 | SWIFT_VERSION = 5.0; 548 | TARGETED_DEVICE_FAMILY = "1,2"; 549 | }; 550 | name = Debug; 551 | }; 552 | 0784A2A52246B1B400C32BFB /* Release */ = { 553 | isa = XCBuildConfiguration; 554 | buildSettings = { 555 | CLANG_ENABLE_MODULES = YES; 556 | CODE_SIGN_IDENTITY = ""; 557 | CODE_SIGN_STYLE = Automatic; 558 | CURRENT_PROJECT_VERSION = 2; 559 | DEFINES_MODULE = YES; 560 | DYLIB_COMPATIBILITY_VERSION = 1; 561 | DYLIB_CURRENT_VERSION = 1; 562 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 563 | INFOPLIST_FILE = OEMentions/Info.plist; 564 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 565 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 566 | LD_RUNPATH_SEARCH_PATHS = ( 567 | "$(inherited)", 568 | "@executable_path/Frameworks", 569 | "@loader_path/Frameworks", 570 | ); 571 | MARKETING_VERSION = 1.0.1; 572 | PRODUCT_BUNDLE_IDENTIFIER = omaressa.OEMentions; 573 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 574 | SKIP_INSTALL = YES; 575 | SWIFT_VERSION = 5.0; 576 | TARGETED_DEVICE_FAMILY = "1,2"; 577 | }; 578 | name = Release; 579 | }; 580 | 0784A2A72246B1B400C32BFB /* Debug */ = { 581 | isa = XCBuildConfiguration; 582 | buildSettings = { 583 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 584 | CODE_SIGN_STYLE = Automatic; 585 | INFOPLIST_FILE = OEMentionsTests/Info.plist; 586 | LD_RUNPATH_SEARCH_PATHS = ( 587 | "$(inherited)", 588 | "@executable_path/Frameworks", 589 | "@loader_path/Frameworks", 590 | ); 591 | PRODUCT_BUNDLE_IDENTIFIER = omaressa.OEMentionsTests; 592 | PRODUCT_NAME = "$(TARGET_NAME)"; 593 | SWIFT_VERSION = 4.2; 594 | TARGETED_DEVICE_FAMILY = "1,2"; 595 | }; 596 | name = Debug; 597 | }; 598 | 0784A2A82246B1B400C32BFB /* Release */ = { 599 | isa = XCBuildConfiguration; 600 | buildSettings = { 601 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 602 | CODE_SIGN_STYLE = Automatic; 603 | INFOPLIST_FILE = OEMentionsTests/Info.plist; 604 | LD_RUNPATH_SEARCH_PATHS = ( 605 | "$(inherited)", 606 | "@executable_path/Frameworks", 607 | "@loader_path/Frameworks", 608 | ); 609 | PRODUCT_BUNDLE_IDENTIFIER = omaressa.OEMentionsTests; 610 | PRODUCT_NAME = "$(TARGET_NAME)"; 611 | SWIFT_VERSION = 4.2; 612 | TARGETED_DEVICE_FAMILY = "1,2"; 613 | }; 614 | name = Release; 615 | }; 616 | /* End XCBuildConfiguration section */ 617 | 618 | /* Begin XCConfigurationList section */ 619 | 071978BE2246F7AF00A0F09D /* Build configuration list for PBXNativeTarget "OEMentionsExample" */ = { 620 | isa = XCConfigurationList; 621 | buildConfigurations = ( 622 | 071978BC2246F7AF00A0F09D /* Debug */, 623 | 071978BD2246F7AF00A0F09D /* Release */, 624 | ); 625 | defaultConfigurationIsVisible = 0; 626 | defaultConfigurationName = Release; 627 | }; 628 | 0784A2892246B1B400C32BFB /* Build configuration list for PBXProject "OEMentions" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 0784A2A12246B1B400C32BFB /* Debug */, 632 | 0784A2A22246B1B400C32BFB /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | 0784A2A32246B1B400C32BFB /* Build configuration list for PBXNativeTarget "OEMentions" */ = { 638 | isa = XCConfigurationList; 639 | buildConfigurations = ( 640 | 0784A2A42246B1B400C32BFB /* Debug */, 641 | 0784A2A52246B1B400C32BFB /* Release */, 642 | ); 643 | defaultConfigurationIsVisible = 0; 644 | defaultConfigurationName = Release; 645 | }; 646 | 0784A2A62246B1B400C32BFB /* Build configuration list for PBXNativeTarget "OEMentionsTests" */ = { 647 | isa = XCConfigurationList; 648 | buildConfigurations = ( 649 | 0784A2A72246B1B400C32BFB /* Debug */, 650 | 0784A2A82246B1B400C32BFB /* Release */, 651 | ); 652 | defaultConfigurationIsVisible = 0; 653 | defaultConfigurationName = Release; 654 | }; 655 | /* End XCConfigurationList section */ 656 | }; 657 | rootObject = 0784A2862246B1B400C32BFB /* Project object */; 658 | } 659 | --------------------------------------------------------------------------------