├── .travis.yml ├── Gemfile ├── Screenshots ├── menu.png └── dialog.png ├── Resources ├── ContentfulModelGenerator └── ContentTypeSelectionDialog.xib ├── README.md ├── ContentfulPlugin.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ ├── ContentfulModelGenerator.xcscheme │ │ └── ContentfulPlugin.xcscheme └── project.pbxproj ├── ContentfulPlugin.xcworkspace └── contents.xcworkspacedata ├── Podfile ├── .gitignore ├── Code ├── ContentTypeSelectionDialog.h ├── ContentfulPlugin.h ├── ContentfulModelGenerator-Bridge.h ├── XcodeProjectManipulation.h ├── ContentfulModelGenerator.h ├── ContentfulPlugin.m ├── main.swift ├── XcodeProjectManipulation.m ├── ContentTypeSelectionDialog.m └── ContentfulModelGenerator.m ├── test.sh ├── .gitmodules ├── LICENSE ├── Podfile.lock ├── Gemfile.lock ├── Supporting Files └── Info.plist └── Tests └── a3rsszoo7qqp.xml /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: ./test.sh 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'cocoapods', '1.1.0.beta.1' 4 | -------------------------------------------------------------------------------- /Screenshots/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/ContentfulXcodePlugin/master/Screenshots/menu.png -------------------------------------------------------------------------------- /Screenshots/dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/ContentfulXcodePlugin/master/Screenshots/dialog.png -------------------------------------------------------------------------------- /Resources/ContentfulModelGenerator: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/ContentfulXcodePlugin/master/Resources/ContentfulModelGenerator -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Contentful Xcode Plugin 2 | 3 | ## Xcode versions 8 and above no longer support plugins. As a consequence, this repository is deprecated and no longer supported by Contentful. 4 | 5 | -------------------------------------------------------------------------------- /ContentfulPlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ContentfulPlugin.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | inhibit_all_warnings! 2 | platform :osx, '10.9' 3 | 4 | target 'ContentfulModelGenerator' do 5 | 6 | pod 'ContentfulDeliveryAPI', '~> 1.10.3' 7 | pod 'ContentfulManagementAPI', '~> 0.8.0' 8 | 9 | end 10 | 11 | target 'ContentfulPlugin' do 12 | 13 | pod 'ContentfulManagementAPI', '~> 0.8.0' 14 | 15 | end 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Appledoc 2 | 3 | doc 4 | 5 | ## OS X 6 | 7 | .DS_Store 8 | 9 | ## Other 10 | 11 | .pt 12 | Examples/ContentfulDeliveryAPI.zip 13 | Examples/UFO.zip 14 | compile_commands.json 15 | .gutter.json 16 | 17 | ## Xcode 18 | 19 | build 20 | *.xccheckout 21 | xcuserdata 22 | .idea 23 | Pods 24 | *.xcscmblueprint 25 | -------------------------------------------------------------------------------- /Code/ContentTypeSelectionDialog.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentTypeSelectionDialog.h 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 10/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ContentTypeSelectionDialog : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Code/ContentfulPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentfulPlugin.h 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 10/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ContentfulPlugin : NSObject 12 | 13 | + (instancetype)sharedPlugin; 14 | 15 | @property (nonatomic, strong, readonly) NSBundle* bundle; 16 | @end -------------------------------------------------------------------------------- /Code/ContentfulModelGenerator-Bridge.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentfulModelGenerator-Bridge.h 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 13/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "ContentfulModelGenerator.h" 13 | -------------------------------------------------------------------------------- /Code/XcodeProjectManipulation.h: -------------------------------------------------------------------------------- 1 | // 2 | // XcodeProjectManipulation.h 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 25/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface XcodeProjectManipulation : NSObject 13 | 14 | -(void)addFileAtPath:(NSString *)filePath toTarget:(id)target; 15 | -(void)addModelFileAtPath:(NSString *)filePath toTarget:(id)target; 16 | -(NSArray*)targets; 17 | -(NSString*)workspacePath; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | function lint() { 4 | xmllint --c14n "$1"|xmllint --format - 5 | } 6 | 7 | set -o pipefail && xcodebuild -workspace ContentfulPlugin.xcworkspace \ 8 | -scheme ContentfulModelGenerator 2>/dev/null | xcpretty -c 9 | 10 | BUILD="`ls -d $HOME/Library/Developer/Xcode/DerivedData/ContentfulPlugin-*`" 11 | $BUILD/Build/Products/Debug/ContentfulModelGenerator \ 12 | a3rsszoo7qqp $CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN 13 | 14 | lint Tests/a3rsszoo7qqp.xml >1.xml 15 | lint ContentfulModel.xcdatamodeld/ContentfulModel.xcdatamodel/contents >2.xml 16 | diff -w 1.xml 2.xml 17 | 18 | rm -f 1.xml 2.xml 19 | rm -rf ContentfulModel.xcdatamodeld 20 | -------------------------------------------------------------------------------- /Code/ContentfulModelGenerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContentfulModelGenerator.h 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 10/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class CMAClient; 13 | 14 | typedef void(^CDAModelGenerationHandler)(NSManagedObjectModel* model, NSError* error); 15 | 16 | @interface ContentfulModelGenerator : NSObject 17 | 18 | -(void)generateModelForContentTypesWithCompletionHandler:(CDAModelGenerationHandler)handler; 19 | -(instancetype)initWithClient:(CMAClient*)client spaceKey:(NSString*)spaceKey; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/ManagedObjectModelSerializer"] 2 | path = vendor/ManagedObjectModelSerializer 3 | url = git@github.com:contentful/ManagedObjectModelSerializer.git 4 | [submodule "vendor/CLIKit"] 5 | path = vendor/CLIKit 6 | url = git@github.com:kylef/CLIKit.git 7 | [submodule "vendor/xcproj"] 8 | path = vendor/xcproj 9 | url = https://github.com/neonichu/xcproj.git 10 | [submodule "vendor/DJProgressHUD"] 11 | path = vendor/DJProgressHUD 12 | url = https://github.com/danielmj/DJProgressHUD_OSX.git 13 | [submodule "vendor/sskeychain"] 14 | path = vendor/sskeychain 15 | url = https://github.com/soffes/sskeychain.git 16 | [submodule "vendor/segmentio-simple"] 17 | path = vendor/segmentio-simple 18 | url = https://github.com/neonichu/segmentio-simple.git 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Contentful GmbH - https://www.contentful.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (2.5.4): 3 | - AFNetworking/NSURLConnection (= 2.5.4) 4 | - AFNetworking/NSURLSession (= 2.5.4) 5 | - AFNetworking/Reachability (= 2.5.4) 6 | - AFNetworking/Security (= 2.5.4) 7 | - AFNetworking/Serialization (= 2.5.4) 8 | - AFNetworking/UIKit (= 2.5.4) 9 | - AFNetworking/NSURLConnection (2.5.4): 10 | - AFNetworking/Reachability 11 | - AFNetworking/Security 12 | - AFNetworking/Serialization 13 | - AFNetworking/NSURLSession (2.5.4): 14 | - AFNetworking/Reachability 15 | - AFNetworking/Security 16 | - AFNetworking/Serialization 17 | - AFNetworking/Reachability (2.5.4) 18 | - AFNetworking/Security (2.5.4) 19 | - AFNetworking/Serialization (2.5.4) 20 | - ContentfulDeliveryAPI (1.10.3): 21 | - AFNetworking (~> 2.5.3) 22 | - ISO8601DateFormatter (= 0.7) 23 | - ContentfulManagementAPI (0.8.0): 24 | - ContentfulDeliveryAPI (~> 1.10.3) 25 | - ISO8601DateFormatter (0.7) 26 | 27 | DEPENDENCIES: 28 | - ContentfulDeliveryAPI (~> 1.10.3) 29 | - ContentfulManagementAPI (~> 0.8.0) 30 | 31 | SPEC CHECKSUMS: 32 | AFNetworking: 05edc0ac4c4c8cf57bcf4b84be5b0744b6d8e71e 33 | ContentfulDeliveryAPI: 5f20fcf45c620a288a5aef941bb57acb14c3ca5c 34 | ContentfulManagementAPI: dd47124ad3ee1a702e27b8001677b0efa8b70187 35 | ISO8601DateFormatter: ab926648eebe497f4d167c0fd083992f959f1274 36 | 37 | PODFILE CHECKSUM: 041e9e9b33ae16770603612aefd93f71e0bb89f2 38 | 39 | COCOAPODS: 1.1.0.beta.1 40 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (4.2.7) 5 | i18n (~> 0.7) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | claide (1.0.0) 11 | cocoapods (1.1.0.beta.1) 12 | activesupport (>= 4.0.2, < 5) 13 | claide (>= 1.0.0, < 2.0) 14 | cocoapods-core (= 1.1.0.beta.1) 15 | cocoapods-deintegrate (>= 1.0.0, < 2.0) 16 | cocoapods-downloader (>= 1.1.0, < 2.0) 17 | cocoapods-plugins (>= 1.0.0, < 2.0) 18 | cocoapods-search (>= 1.0.0, < 2.0) 19 | cocoapods-stats (>= 1.0.0, < 2.0) 20 | cocoapods-trunk (>= 1.0.0, < 2.0) 21 | cocoapods-try (>= 1.1.0, < 2.0) 22 | colored (~> 1.2) 23 | escape (~> 0.0.4) 24 | fourflusher (~> 1.0.1) 25 | gh_inspector (~> 1.0) 26 | molinillo (~> 0.5.0) 27 | nap (~> 1.0) 28 | xcodeproj (>= 1.2.0, < 2.0) 29 | cocoapods-core (1.1.0.beta.1) 30 | activesupport (>= 4.0.2) 31 | fuzzy_match (~> 2.0.4) 32 | nap (~> 1.0) 33 | cocoapods-deintegrate (1.0.0) 34 | cocoapods-downloader (1.1.0) 35 | cocoapods-plugins (1.0.0) 36 | nap 37 | cocoapods-search (1.0.0) 38 | cocoapods-stats (1.0.0) 39 | cocoapods-trunk (1.0.0) 40 | nap (>= 0.8, < 2.0) 41 | netrc (= 0.7.8) 42 | cocoapods-try (1.1.0) 43 | colored (1.2) 44 | escape (0.0.4) 45 | fourflusher (1.0.1) 46 | fuzzy_match (2.0.4) 47 | gh_inspector (1.0.2) 48 | i18n (0.7.0) 49 | json (1.8.3) 50 | minitest (5.9.0) 51 | molinillo (0.5.0) 52 | nap (1.1.0) 53 | netrc (0.7.8) 54 | thread_safe (0.3.5) 55 | tzinfo (1.2.2) 56 | thread_safe (~> 0.1) 57 | xcodeproj (1.2.0) 58 | activesupport (>= 3) 59 | claide (>= 1.0.0, < 2.0) 60 | colored (~> 1.2) 61 | 62 | PLATFORMS 63 | ruby 64 | 65 | DEPENDENCIES 66 | cocoapods (= 1.1.0.beta.1) 67 | 68 | BUNDLED WITH 69 | 1.12.5 70 | -------------------------------------------------------------------------------- /Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | DVTPlugInCompatibilityUUIDs 26 | 27 | F41BD31E-2683-44B8-AE7F-5F09E919790E 28 | 992275C1-432A-4CF7-B659-D84ED6D42D3F 29 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED 30 | C4A681B0-4A26-480E-93EC-1218098B9AA0 31 | AD68E85B-441B-4301-B564-A45E4919A6AD 32 | FEC992CC-CA4A-4CFD-8881-77300FCB848A 33 | A16FF353-8441-459E-A50C-B071F53F51B7 34 | E969541F-E6F9-4D25-8158-72DC3545A6C6 35 | 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 36 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7 37 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 38 | E71C2CFE-BFD8-4044-8F06-00AE685A406C 39 | AABB7188-E14E-4433-AD3B-5CD791EAD9A3 40 | 9AFF134A-08DC-4096-8CEE-62A4BB123046 41 | CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 42 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 43 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 44 | 7265231C-39B4-402C-89E1-16167C4CC990 45 | 46 | LSMinimumSystemVersion 47 | $(MACOSX_DEPLOYMENT_TARGET) 48 | NSPrincipalClass 49 | ContentfulPlugin 50 | XC4Compatible 51 | 52 | XCPluginHasUI 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Code/ContentfulPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentfulPlugin.m 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 10/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import "ContentfulPlugin.h" 10 | #import "ContentTypeSelectionDialog.h" 11 | 12 | static ContentfulPlugin *sharedPlugin; 13 | 14 | @interface ContentfulPlugin() 15 | 16 | @property (nonatomic, strong, readwrite) NSBundle *bundle; 17 | @property (nonatomic, strong, readwrite) ContentTypeSelectionDialog* contentTypeSelectionDialog; 18 | 19 | @end 20 | 21 | #pragma mark - 22 | 23 | @implementation ContentfulPlugin 24 | 25 | + (void)pluginDidLoad:(NSBundle *)plugin 26 | { 27 | static dispatch_once_t onceToken; 28 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; 29 | if ([currentApplicationName isEqual:@"Xcode"]) { 30 | dispatch_once(&onceToken, ^{ 31 | sharedPlugin = [[self alloc] initWithBundle:plugin]; 32 | }); 33 | } 34 | } 35 | 36 | + (instancetype)sharedPlugin 37 | { 38 | return sharedPlugin; 39 | } 40 | 41 | #pragma mark - 42 | 43 | - (id)initWithBundle:(NSBundle *)plugin 44 | { 45 | if (self = [super init]) { 46 | self.bundle = plugin; 47 | 48 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 49 | [self createMenuItem]; 50 | }]; 51 | } 52 | return self; 53 | } 54 | 55 | - (void)createMenuItem { 56 | NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Product"]; 57 | if (menuItem) { 58 | [[menuItem submenu] addItem:[NSMenuItem separatorItem]]; 59 | NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Generate Model from Contentful..." action:@selector(doMenuAction) keyEquivalent:@""]; 60 | [actionMenuItem setTarget:self]; 61 | [[menuItem submenu] addItem:actionMenuItem]; 62 | } 63 | } 64 | 65 | - (void)doMenuAction 66 | { 67 | self.contentTypeSelectionDialog = [ContentTypeSelectionDialog new]; 68 | [[NSApp keyWindow] beginSheet:self.contentTypeSelectionDialog.window completionHandler:nil]; 69 | } 70 | 71 | - (void)dealloc 72 | { 73 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 74 | } 75 | 76 | -(BOOL)validateMenuItem:(NSMenuItem *)menuItem { 77 | return [NSStringFromClass([NSApp keyWindow].class) isEqualToString:@"IDEWorkspaceWindow"]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Tests/a3rsszoo7qqp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Code/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // ContentfulModelGenerator 4 | // 5 | // Created by Boris Bügling on 13/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func generate(spaceKey: String, _ accessToken: String) { 12 | let configuration = CDAConfiguration.defaultConfiguration() 13 | configuration.userAgent = "ContentfulModelGenerator/0.3" 14 | 15 | let client = CMAClient(accessToken: accessToken, configuration:configuration) 16 | let generator = ContentfulModelGenerator(client: client, spaceKey: spaceKey) 17 | 18 | var waiting = true 19 | 20 | generator.generateModelForContentTypesWithCompletionHandler { (model, error) -> Void in 21 | if (error != nil) { 22 | print("Error: " + error.localizedDescription) 23 | waiting = false 24 | return 25 | } 26 | 27 | let cwdUrl = NSURL(fileURLWithPath: NSFileManager().currentDirectoryPath) 28 | do { 29 | try ModelSerializer(model: model).generateBundle("ContentfulModel", atPath: cwdUrl) 30 | } catch let error { 31 | print("Error: \(error)") 32 | waiting = false 33 | return 34 | } 35 | 36 | waiting = false 37 | } 38 | 39 | while(waiting) { 40 | NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, 41 | beforeDate: NSDate(timeIntervalSinceNow: 0.1)) 42 | } 43 | } 44 | 45 | // Manually copied from `Command.swift` of SwiftShell, because of a naming conflict with Commander 46 | private func newtask (shellcommand: String) -> NSTask { 47 | let task = NSTask() 48 | task.arguments = ["-c", shellcommand] 49 | task.launchPath = "/bin/bash" 50 | 51 | return task 52 | } 53 | 54 | public func $ (shellcommand: String) -> String { 55 | let task = newtask(shellcommand) 56 | 57 | // avoids implicit reading of the main script's standardInput 58 | task.standardInput = NSPipe () 59 | 60 | let output = NSPipe () 61 | task.standardOutput = output 62 | task.launch() 63 | task.waitUntilExit() 64 | 65 | return output.fileHandleForReading.read().trim() 66 | } 67 | 68 | // Manually copied from `Commands.swift` of Commander because that file requires a separate module 69 | public func command(descriptor:A, _ descriptor1:A1, closure:(A.ValueType, A1.ValueType) throws -> ()) -> CommandType { 70 | return AnonymousCommand { parser in 71 | let help = Help([ 72 | BoxedArgumentDescriptor(value: descriptor), 73 | BoxedArgumentDescriptor(value: descriptor1), 74 | ]) 75 | 76 | if parser.hasOption("help") { 77 | throw help 78 | } 79 | 80 | let value0 = try descriptor.parse(parser) 81 | let value1 = try descriptor1.parse(parser) 82 | 83 | if !parser.isEmpty { 84 | throw UsageError("Unknown Arguments: \(parser)", help) 85 | } 86 | 87 | try closure(value0, value1) 88 | } 89 | } 90 | 91 | command(Argument("Space ID", description: "ID of the Space"), 92 | Argument("Access Token", description: "Access token of the Space")) 93 | { (spaceKey, accessToken) in 94 | generate(spaceKey, accessToken) 95 | }.run() 96 | -------------------------------------------------------------------------------- /ContentfulPlugin.xcodeproj/xcshareddata/xcschemes/ContentfulModelGenerator.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ContentfulPlugin.xcodeproj/xcshareddata/xcschemes/ContentfulPlugin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 53 | 54 | 55 | 56 | 57 | 58 | 70 | 73 | 74 | 75 | 81 | 82 | 83 | 84 | 85 | 86 | 92 | 93 | 99 | 100 | 101 | 102 | 104 | 105 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /Code/XcodeProjectManipulation.m: -------------------------------------------------------------------------------- 1 | // 2 | // XcodeProjectManipulation.m 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 25/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "XcodeProjectManipulation.h" 13 | 14 | @interface XcodeProjectManipulation () 15 | 16 | @property (nonatomic, readonly) id project; 17 | 18 | @end 19 | 20 | #pragma mark - 21 | 22 | @implementation XcodeProjectManipulation 23 | 24 | -(void)addFileAtPath:(NSString *)filePath toTarget:(id)target { 25 | id reference = [self addFileAtPath:filePath]; 26 | [self addFileReference:reference inGroupNamed:@"Resources"]; 27 | [self addFileReference:reference toBuildPhase:@"Sources" target:target]; 28 | } 29 | 30 | -(void)addModelFileAtPath:(NSString *)filePath toTarget:(id)target { 31 | id group = [self groupNamed:@"Resources" parentGroup:nil]; 32 | 33 | for (id child in group.children) { 34 | if ([child.name isEqualToString:filePath.lastPathComponent]) { 35 | return; 36 | } 37 | } 38 | 39 | [self addFileAtPath:filePath toTarget:target]; 40 | } 41 | 42 | -(id)project { 43 | NSString* workspacePath = [self workspacePath]; 44 | NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:workspacePath]; 45 | 46 | NSMutableDictionary* foundProjects = [@{} mutableCopy]; 47 | 48 | for (NSString* file in enumerator) { 49 | if ([file.pathExtension isEqualToString:@"xcodeproj"]) { 50 | NSString* fullPath = [workspacePath stringByAppendingPathComponent:file]; 51 | id project = [objc_getClass("PBXProject") projectWithFile:fullPath]; 52 | 53 | NSMutableArray* levelProjects = foundProjects[@(enumerator.level)] ?: [@[] mutableCopy]; 54 | [levelProjects addObject:project]; 55 | foundProjects[@(enumerator.level)] = levelProjects; 56 | } 57 | } 58 | 59 | NSArray* levels = [foundProjects.allKeys sortedArrayUsingSelector:@selector(compare:)]; 60 | return [foundProjects[[levels firstObject]] firstObject]; 61 | } 62 | 63 | -(NSArray*)targets { 64 | return [self.project targets]; 65 | } 66 | 67 | -(NSString*)workspacePath { 68 | id workspaceWindowController = [self keyWorkspaceWindowController]; 69 | id workspace = [workspaceWindowController valueForKey:@"_workspace"]; 70 | 71 | NSString* path = [[workspace valueForKey:@"representingFilePath"] valueForKey:@"_pathString"]; 72 | return [path stringByDeletingLastPathComponent]; 73 | } 74 | 75 | - (id)keyWorkspaceWindowController { 76 | NSArray* workspaceWindowControllers = [objc_getClass("IDEWorkspaceWindowController") 77 | performSelector:@selector(workspaceWindowControllers)]; 78 | 79 | for (NSWindowController* controller in workspaceWindowControllers) { 80 | if (controller.window == [NSApp keyWindow].sheetParent) { 81 | return controller; 82 | } 83 | } 84 | 85 | return workspaceWindowControllers[0]; 86 | } 87 | 88 | #pragma mark - Taken from xcproj 89 | 90 | - (id) groupNamed:(NSString *)groupName inGroup:(id)rootGroup parentGroup:(id *) parentGroup 91 | { 92 | for (id group in [rootGroup children]) 93 | { 94 | if ([group isKindOfClass:objc_getClass("PBXGroup")]) 95 | { 96 | if (parentGroup) 97 | *parentGroup = rootGroup; 98 | 99 | if ([[group name] isEqualToString:groupName]) 100 | { 101 | return group; 102 | } 103 | else 104 | { 105 | id subGroup = [self groupNamed:groupName inGroup:group parentGroup:parentGroup]; 106 | if (subGroup) 107 | return subGroup; 108 | } 109 | } 110 | } 111 | 112 | if (parentGroup) 113 | *parentGroup = nil; 114 | return nil; 115 | } 116 | 117 | - (id) groupNamed:(NSString *)groupName parentGroup:(id *) parentGroup 118 | { 119 | return [self groupNamed:groupName inGroup:[self.project rootGroup] parentGroup:parentGroup]; 120 | } 121 | 122 | - (id) addFileAtPath:(NSString *)filePath 123 | { 124 | if (![filePath hasPrefix:@"/"]) 125 | filePath = [[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:filePath]; 126 | 127 | id fileReference = [self.project fileReferenceForPath:filePath]; 128 | if (!fileReference) 129 | { 130 | NSArray *references = [[self.project rootGroup] addFiles:[NSArray arrayWithObject:filePath] copy:NO createGroupsRecursively:NO]; 131 | fileReference = [references lastObject]; 132 | } 133 | return fileReference; 134 | } 135 | 136 | - (BOOL) addFileReference:(id)fileReference inGroupNamed:(NSString *)groupName 137 | { 138 | id group = [self groupNamed:groupName parentGroup:NULL]; 139 | if (!group) 140 | group = [self.project rootGroup]; 141 | 142 | if ([group containsItem:fileReference]) 143 | return YES; 144 | 145 | [group addItem:fileReference]; 146 | 147 | return YES; 148 | } 149 | 150 | - (BOOL) addFileReference:(id)fileReference 151 | toBuildPhase:(NSString *)buildPhaseName 152 | target:(id)target 153 | { 154 | Class buildPhaseClass = NSClassFromString([NSString stringWithFormat:@"PBX%@BuildPhase", buildPhaseName]); 155 | id buildPhase = [target buildPhaseOfClass:buildPhaseClass]; 156 | if (!buildPhase) 157 | { 158 | if ([buildPhaseClass respondsToSelector:@selector(buildPhase)]) 159 | { 160 | buildPhase = [buildPhaseClass performSelector:@selector(buildPhase)]; 161 | [target addBuildPhase:buildPhase]; 162 | } 163 | } 164 | 165 | if ([buildPhase containsFileReferenceIdenticalTo:fileReference]) 166 | return YES; 167 | 168 | return [buildPhase addReference:fileReference]; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /Code/ContentTypeSelectionDialog.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentTypeSelectionDialog.m 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 10/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "BBUSegmentTracker.h" 12 | #import "ContentTypeSelectionDialog.h" 13 | #import "DJProgressHUD.h" 14 | #import "SSKeychain.h" 15 | #import "XcodeProjectManipulation.h" 16 | 17 | static NSString* const kContentful = @"com.contentful.xcode-plugin"; 18 | static NSString* const kTrackingOptOut = @"com.contentful.trackingOptOut"; 19 | static NSString* const kSegmentToken = @"9hgd0ujgqy"; 20 | 21 | @interface ContentTypeSelectionDialog () 22 | 23 | @property (weak) IBOutlet NSTextField *accessTokenTextField; 24 | @property (strong) CMAClient* client; 25 | @property (weak) IBOutlet NSButton *generateButton; 26 | @property (weak) IBOutlet NSButton *loginButton; 27 | @property (strong) XcodeProjectManipulation* projectManipulation; 28 | @property (strong) CMASpace* selectedSpace; 29 | @property (strong) id selectedTarget; 30 | @property (weak) IBOutlet NSButton *spaceSelection; 31 | @property (weak) IBOutlet NSMenu *spaceSelectionMenu; 32 | @property (weak) IBOutlet NSButton *targetSelection; 33 | @property (weak) IBOutlet NSMenu *targetSelectionMenu; 34 | @property (strong) BBUSegmentTracker* tracker; 35 | @property (weak) IBOutlet NSButton *trackingOptOut; 36 | 37 | @end 38 | 39 | #pragma mark - 40 | 41 | @implementation ContentTypeSelectionDialog 42 | 43 | - (void)closeSheet { 44 | [self.window close]; 45 | [[NSApp keyWindow] endSheet:self.window]; 46 | } 47 | 48 | - (void)fillMenuWithSpaces:(NSArray*)spaces { 49 | self.spaceSelection.enabled = spaces.count > 0; 50 | 51 | [self.spaceSelectionMenu removeAllItems]; 52 | 53 | spaces = [spaces sortedArrayUsingComparator:^NSComparisonResult(CMASpace* space1, CMASpace* space2) { 54 | return [space1.name localizedStandardCompare:space2.name]; 55 | }]; 56 | self.selectedSpace = spaces[0]; 57 | 58 | [spaces enumerateObjectsUsingBlock:^(CMASpace* space, NSUInteger idx, BOOL *stop) { 59 | NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:space.name 60 | action:@selector(selectSpace:) 61 | keyEquivalent:@""]; 62 | menuItem.representedObject = space; 63 | [self.spaceSelectionMenu addItem:menuItem]; 64 | }]; 65 | } 66 | 67 | - (void)fillMenuWithTargets:(NSArray*)targets { 68 | self.targetSelection.enabled = targets.count > 0; 69 | 70 | [self.targetSelectionMenu removeAllItems]; 71 | 72 | targets = [targets sortedArrayUsingComparator:^NSComparisonResult(id t1, id t2) { 73 | return [[t1 name] localizedStandardCompare:[t2 name]]; 74 | }]; 75 | self.selectedTarget = targets[0]; 76 | 77 | [targets enumerateObjectsUsingBlock:^(id target, NSUInteger idx, BOOL *stop) { 78 | NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:target.name 79 | action:@selector(selectTarget:) 80 | keyEquivalent:@""]; 81 | menuItem.representedObject = target; 82 | [self.targetSelectionMenu addItem:menuItem]; 83 | }]; 84 | } 85 | 86 | - (instancetype)init { 87 | self = [super initWithWindowNibName:NSStringFromClass(self.class)]; 88 | if (self) { 89 | self.projectManipulation = [XcodeProjectManipulation new]; 90 | self.tracker = [[BBUSegmentTracker alloc] initWithToken:kSegmentToken]; 91 | } 92 | return self; 93 | } 94 | 95 | -(void)performLogin { 96 | CDAConfiguration* configuration = [CDAConfiguration defaultConfiguration]; 97 | configuration.userAgent = @"Contentful Xcode Plugin/0.3"; 98 | 99 | self.client = [[CMAClient alloc] initWithAccessToken:self.accessTokenTextField.stringValue 100 | configuration:configuration]; 101 | 102 | [self.client fetchAllSpacesWithSuccess:^(CDAResponse *response, CDAArray *array) { 103 | [SSKeychain setPassword:self.accessTokenTextField.stringValue 104 | forService:kContentful 105 | account:kContentful]; 106 | 107 | [self fillMenuWithSpaces:array.items]; 108 | [self fillMenuWithTargets:[self.projectManipulation targets]]; 109 | 110 | self.generateButton.enabled = self.spaceSelection.enabled && self.targetSelection.enabled; 111 | } failure:^(CDAResponse *response, NSError *error) { 112 | NSAlert* alert = [NSAlert alertWithError:error]; 113 | [alert runModal]; 114 | }]; 115 | } 116 | 117 | -(void)selectSpace:(NSMenuItem*)menuItem { 118 | self.selectedSpace = menuItem.representedObject; 119 | } 120 | 121 | -(void)selectTarget:(NSMenuItem*)menuItem { 122 | self.selectedTarget = menuItem.representedObject; 123 | } 124 | 125 | -(void)windowDidLoad { 126 | [super windowDidLoad]; 127 | 128 | self.trackingOptOut.state = [[NSUserDefaults standardUserDefaults] boolForKey:kTrackingOptOut] ? NSOffState : NSOnState; 129 | 130 | self.accessTokenTextField.stringValue = [SSKeychain passwordForService:kContentful 131 | account:kContentful] ?: @""; 132 | [self performLogin]; 133 | } 134 | 135 | #pragma mark - Actions 136 | 137 | - (IBAction)cancelButtonClicked:(NSButton *)sender { 138 | [self closeSheet]; 139 | } 140 | 141 | - (IBAction)generateClicked:(NSButton *)sender { 142 | if (self.trackingOptOut.state == NSOnState) { 143 | [self.tracker trackEvent:@"Generated Core Data model" withProperties:@{} completionHandler:nil]; 144 | } 145 | 146 | NSString* potentialPath = [[self.projectManipulation workspacePath] stringByAppendingPathComponent:@"ContentfulModel.xcdatamodeld"]; 147 | 148 | if ([[NSFileManager defaultManager] fileExistsAtPath:potentialPath]) { 149 | NSAlert* question = [NSAlert alertWithMessageText:NSLocalizedString(@"Data model already exists", nil) defaultButton:NSLocalizedString(@"Overwrite existing model", nil) alternateButton:NSLocalizedString(@"Cancel", nil) otherButton:NSLocalizedString(@"Create new model version", nil) informativeTextWithFormat:NSLocalizedString(@"A data model already exists at %@, do you want to overwrite it or generate a new version of the existing model?", nil), potentialPath]; 150 | NSModalResponse response = [question runModal]; 151 | 152 | switch (response) { 153 | case NSAlertDefaultReturn: 154 | [[NSFileManager defaultManager] removeItemAtPath:potentialPath error:nil]; 155 | break; 156 | 157 | case NSAlertOtherReturn: 158 | break; 159 | 160 | default: 161 | return; 162 | } 163 | } 164 | 165 | NSString* generatorBinaryPath = [[NSBundle bundleForClass:self.class] pathForResource:@"ContentfulModelGenerator" ofType:nil]; 166 | 167 | NSTask* task = [NSTask new]; 168 | task.arguments = @[self.selectedSpace.identifier, self.accessTokenTextField.stringValue]; 169 | task.currentDirectoryPath = [self.projectManipulation workspacePath]; 170 | task.launchPath = generatorBinaryPath; 171 | 172 | NSPipe* errorPipe = [NSPipe pipe]; 173 | task.standardError = errorPipe; 174 | 175 | [DJProgressHUD showStatus:NSLocalizedString(@"Generating...", nil) 176 | FromView:self.window.contentView]; 177 | 178 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 179 | [task launch]; 180 | [task waitUntilExit]; 181 | 182 | dispatch_sync(dispatch_get_main_queue(), ^{ 183 | [DJProgressHUD dismiss]; 184 | }); 185 | 186 | BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:potentialPath]; 187 | 188 | dispatch_sync(dispatch_get_main_queue(), ^{ 189 | if (!exists) { 190 | NSString* errorString = [[NSString alloc] initWithData:[[errorPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding]; 191 | 192 | NSAlert* alert = [NSAlert new]; 193 | alert.messageText = [NSString stringWithFormat:NSLocalizedString(@"Could not generate data model: %@", nil), errorString]; 194 | [alert runModal]; 195 | } else { 196 | [self.projectManipulation addModelFileAtPath:potentialPath toTarget:self.selectedTarget]; 197 | } 198 | 199 | [self closeSheet]; 200 | }); 201 | }); 202 | } 203 | 204 | - (IBAction)loginClicked:(NSButton*)sender { 205 | [self performLogin]; 206 | } 207 | 208 | - (IBAction)obtainAccessTokenClicked:(NSButton*)sender { 209 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.contentful.com/developers/documentation/content-management-api/http/#getting-started"]]; 210 | } 211 | 212 | - (IBAction)trackingOptOutClicked:(NSButton*)sender { 213 | [[NSUserDefaults standardUserDefaults] setBool:sender.state == NSOffState forKey:kTrackingOptOut]; 214 | } 215 | 216 | @end 217 | -------------------------------------------------------------------------------- /Resources/ContentTypeSelectionDialog.xib: -------------------------------------------------------------------------------- 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 | Give the plugin access to your spaces by logging in to Contentful, then select space and target to generate a coressponding Core Data model. 53 | 54 | 55 | 56 | 57 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 93 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 124 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Code/ContentfulModelGenerator.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContentfulModelGenerator.m 3 | // ContentfulPlugin 4 | // 5 | // Created by Boris Bügling on 10/11/14. 6 | // Copyright (c) 2014 Contentful GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "ContentfulModelGenerator.h" 13 | 14 | @interface ContentfulModelGenerator () 15 | 16 | @property (nonatomic) NSEntityDescription* assetEntity; 17 | @property (nonatomic) CMAClient* client; 18 | @property (nonatomic) NSDictionary* contentTypes; 19 | @property (nonatomic) NSMutableDictionary* entities; 20 | @property (nonatomic) NSString* spaceKey; 21 | 22 | @end 23 | 24 | #pragma mark - 25 | 26 | @implementation ContentfulModelGenerator 27 | 28 | + (NSAttributeType)attributeTypeFromFieldType:(CDAFieldType)fieldType { 29 | switch (fieldType) { 30 | case CDAFieldTypeBoolean: 31 | return NSBooleanAttributeType; 32 | case CDAFieldTypeDate: 33 | return NSDateAttributeType; 34 | case CDAFieldTypeInteger: 35 | return NSInteger64AttributeType; 36 | case CDAFieldTypeLocation: 37 | case CDAFieldTypeObject: 38 | return NSTransformableAttributeType; 39 | case CDAFieldTypeNumber: 40 | return NSDoubleAttributeType; 41 | case CDAFieldTypeSymbol: 42 | case CDAFieldTypeText: 43 | return NSStringAttributeType; 44 | default: 45 | break; 46 | } 47 | 48 | return NSUndefinedAttributeType; 49 | } 50 | 51 | + (NSAttributeDescription*)attributeWithName:(NSString*)name type:(NSAttributeType)type { 52 | unsigned int numberOfMethods = 0; 53 | Method* methods = class_copyMethodList(NSManagedObject.class, &numberOfMethods); 54 | 55 | for (int i = 0; i < numberOfMethods; i++) { 56 | NSString* methodName = NSStringFromSelector(method_getName(methods[i])); 57 | 58 | if ([name isEqualToString:methodName]) { 59 | fprintf(stderr, "%s\n", [[NSString stringWithFormat:@"Error: field '%@' redefines a method already present on NSObject or NSManagedObject. ", name] cStringUsingEncoding:NSUTF8StringEncoding]); 60 | exit(1); 61 | } 62 | } 63 | 64 | free(methods); 65 | 66 | NSAttributeDescription* veryAttribute = [NSAttributeDescription new]; 67 | veryAttribute.name = name; 68 | veryAttribute.attributeType = type; 69 | return veryAttribute; 70 | } 71 | 72 | + (NSEntityDescription*)entityWithName:(NSString*)name { 73 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^_a-zA-Z0-9]" options:0 error:nil]; 74 | 75 | NSEntityDescription* suchEntity = [NSEntityDescription new]; 76 | suchEntity.name = [regex stringByReplacingMatchesInString:name options:0 range:NSMakeRange(0, [name length]) withTemplate:@"_"]; 77 | suchEntity.managedObjectClassName = suchEntity.name; 78 | return suchEntity; 79 | } 80 | 81 | #pragma mark - 82 | 83 | -(CDAContentType*)contentTypeValidationForField:(CMAField*)field { 84 | if (field.itemType != CDAFieldTypeEntry) { 85 | return nil; 86 | } 87 | 88 | NSArray* validations = [field.validations valueForKey:@"dictionaryRepresentation"]; 89 | 90 | for (NSDictionary* validation in validations) { 91 | NSArray* possibleValidation = validation[@"linkContentType"]; 92 | 93 | if ([possibleValidation isKindOfClass:NSString.class]) { 94 | return self.contentTypes[possibleValidation]; 95 | } 96 | 97 | if (possibleValidation.count == 1) { 98 | return self.contentTypes[possibleValidation[0]]; 99 | } 100 | } 101 | 102 | return nil; 103 | } 104 | 105 | -(instancetype)initWithClient:(CMAClient *)client spaceKey:(NSString *)spaceKey { 106 | self = [super init]; 107 | if (self) { 108 | self.client = client; 109 | self.entities = [@{} mutableCopy]; 110 | self.spaceKey = spaceKey; 111 | } 112 | return self; 113 | } 114 | 115 | -(NSEntityDescription*)generateEntityForContentType:(CDAContentType*)contentType { 116 | NSEntityDescription* entity = [[self class] entityWithName:contentType.name]; 117 | self.entities[contentType.identifier] = entity; 118 | return entity; 119 | } 120 | 121 | -(void)handleFieldsForContentType:(CDAContentType*)contentType { 122 | NSEntityDescription* entity = self.entities[contentType.identifier]; 123 | 124 | NSMutableArray* properties = [@[] mutableCopy]; 125 | 126 | for (CMAField* field in contentType.fields) { 127 | if (field.disabled || field.omitted) { 128 | continue; 129 | } 130 | 131 | switch (field.type) { 132 | case CDAFieldTypeArray: 133 | case CDAFieldTypeLink: { 134 | if (field.itemType == CDAFieldTypeSymbol) { 135 | NSAttributeDescription* attribute = [[self class] attributeWithName:field.identifier type:NSBinaryDataAttributeType]; 136 | 137 | [properties addObject:attribute]; 138 | continue; 139 | } 140 | 141 | if (field.itemType != CDAFieldTypeAsset && field.itemType != CDAFieldTypeEntry) { 142 | continue; 143 | } 144 | 145 | NSRelationshipDescription* relation = [NSRelationshipDescription new]; 146 | relation.name = field.identifier; 147 | relation.maxCount = field.type == CDAFieldTypeArray ? 0 : 1; 148 | relation.ordered = field.type == CDAFieldTypeArray; 149 | relation.optional = YES; 150 | 151 | if (field.itemType == CDAFieldTypeAsset) { 152 | relation.destinationEntity = self.assetEntity; 153 | 154 | NSRelationshipDescription* inverse = [NSRelationshipDescription new]; 155 | inverse.name = [NSString stringWithFormat:@"%@_%@_Inverse", field.identifier, 156 | contentType.identifier]; 157 | inverse.optional = YES; 158 | inverse.destinationEntity = entity; 159 | 160 | inverse.inverseRelationship = relation; 161 | relation.inverseRelationship = inverse; 162 | 163 | NSMutableArray* properties = [self.assetEntity.properties mutableCopy]; 164 | [properties addObject:inverse]; 165 | self.assetEntity.properties = properties; 166 | } else { 167 | CDAContentType* possibleContentType = [self contentTypeValidationForField:field]; 168 | 169 | if (!possibleContentType) { 170 | fprintf(stderr, "%s\n", [[NSString stringWithFormat:@"Error: field '%@' (content-type %@) is missing content type validations.", field.identifier, contentType.identifier] cStringUsingEncoding:NSUTF8StringEncoding]); 171 | exit(1); 172 | } 173 | 174 | relation.destinationEntity = self.entities[possibleContentType.identifier]; 175 | } 176 | 177 | [properties addObject:relation]; 178 | break; 179 | } 180 | case CDAFieldTypeNone: 181 | continue; 182 | default: { 183 | NSAttributeDescription* attribute = [[self class] attributeWithName:field.identifier type:[[self class] attributeTypeFromFieldType:field.type]]; 184 | 185 | [properties addObject:attribute]; 186 | break; 187 | } 188 | } 189 | } 190 | 191 | [properties addObject:[[self class] attributeWithName:@"identifier" type:NSStringAttributeType]]; 192 | 193 | entity.properties = properties; 194 | } 195 | 196 | -(NSEntityDescription*)generateStandardEntityForAssets { 197 | NSEntityDescription* entity = [[self class] entityWithName:@"Asset"]; 198 | 199 | NSMutableArray* properties = [@[] mutableCopy]; 200 | 201 | NSAttributeDescription* attribute = [[self class] attributeWithName:@"height" type:NSFloatAttributeType]; 202 | [properties addObject:attribute]; 203 | 204 | attribute = [[self class] attributeWithName:@"width" type:NSFloatAttributeType]; 205 | [properties addObject:attribute]; 206 | 207 | for (NSString* attributeName in @[ @"identifier", @"internetMediaType", @"url" ]) { 208 | attribute = [[self class] attributeWithName:attributeName type:NSStringAttributeType]; 209 | [properties addObject:attribute]; 210 | } 211 | 212 | entity.properties = properties; 213 | return entity; 214 | } 215 | 216 | -(NSEntityDescription*)generateStandardEntityForSyncInfo { 217 | NSEntityDescription* entity = [[self class] entityWithName:@"SyncInfo"]; 218 | 219 | NSMutableArray* properties = [@[] mutableCopy]; 220 | 221 | NSAttributeDescription* attribute = [[self class] attributeWithName:@"lastSyncTimestamp" 222 | type:NSDateAttributeType]; 223 | [properties addObject:attribute]; 224 | 225 | attribute = [[self class] attributeWithName:@"syncToken" type:NSStringAttributeType]; 226 | [properties addObject:attribute]; 227 | 228 | entity.properties = properties; 229 | return entity; 230 | } 231 | 232 | -(void)generateModelForContentTypesWithCompletionHandler:(CDAModelGenerationHandler)handler { 233 | NSParameterAssert(handler); 234 | 235 | [self.client fetchSpaceWithIdentifier:self.spaceKey success:^(CDAResponse *response, CMASpace *space) { 236 | [space fetchContentTypesWithSuccess:^(CDAResponse *response, CDAArray *array) { 237 | NSMutableArray* entities = [@[] mutableCopy]; 238 | 239 | NSMutableDictionary* contentTypes = [@{} mutableCopy]; 240 | for (CMAContentType* contentType in array.items) { 241 | if (contentType.isPublished) { 242 | contentTypes[contentType.identifier] = contentType; 243 | } 244 | } 245 | self.contentTypes = contentTypes; 246 | 247 | self.assetEntity = [self generateStandardEntityForAssets]; 248 | [entities addObject:self.assetEntity]; 249 | [entities addObject:[self generateStandardEntityForSyncInfo]]; 250 | 251 | for (CDAContentType* contentType in self.contentTypes.allValues) { 252 | NSEntityDescription* entity = [self generateEntityForContentType:contentType]; 253 | [entities addObject:entity]; 254 | } 255 | 256 | for (CDAContentType* contentType in self.contentTypes.allValues) { 257 | [self handleFieldsForContentType:contentType]; 258 | } 259 | 260 | for (NSEntityDescription* entity in entities) { 261 | for (NSRelationshipDescription* relation in entity.relationshipsByName.allValues) { 262 | if (relation.inverseRelationship) { 263 | continue; 264 | } 265 | 266 | NSEntityDescription* destination = relation.destinationEntity; 267 | NSRelationshipDescription* inverse = nil; 268 | NSString* inverseName = [relation.name stringByAppendingString:@"Inverse"]; 269 | 270 | for (NSRelationshipDescription* r in destination.relationshipsByName.allValues) { 271 | if (r.destinationEntity == entity && r.inverseRelationship == nil) { 272 | inverse = r; 273 | } 274 | 275 | if ([r.name isEqualToString:inverseName]) { 276 | inverseName = [NSString stringWithFormat:@"%@_%@_Inverse", 277 | relation.name, entity.name]; 278 | } 279 | } 280 | 281 | if (!inverse) { 282 | inverse = [NSRelationshipDescription new]; 283 | inverse.name = inverseName; 284 | inverse.optional = YES; 285 | inverse.destinationEntity = entity; 286 | 287 | NSMutableArray* properties = [destination.properties mutableCopy]; 288 | [properties addObject:inverse]; 289 | destination.properties = properties; 290 | } 291 | 292 | inverse.inverseRelationship = relation; 293 | relation.inverseRelationship = inverse; 294 | } 295 | } 296 | 297 | NSManagedObjectModel* model = [NSManagedObjectModel new]; 298 | model.entities = [entities copy]; 299 | handler(model, nil); 300 | } failure:^(CDAResponse *response, NSError *error) { 301 | handler(nil, error); 302 | }]; 303 | } failure:^(CDAResponse *response, NSError *error) { 304 | handler(nil, error); 305 | }]; 306 | } 307 | 308 | @end 309 | -------------------------------------------------------------------------------- /ContentfulPlugin.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6154FD3B483A7E28F3BAE079 /* libPods-ContentfulPlugin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CB8D5FDCA27AB089A758488 /* libPods-ContentfulPlugin.a */; }; 11 | A117BED11A238E4200C53D65 /* ContentfulModelGenerator in Resources */ = {isa = PBXBuildFile; fileRef = A117BED01A238E4200C53D65 /* ContentfulModelGenerator */; }; 12 | A117BED61A23995C00C53D65 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1604DDE1A137085003F916D /* SystemConfiguration.framework */; }; 13 | A13C067E1A26014F00C8F657 /* DJActivityIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A13C06771A26014F00C8F657 /* DJActivityIndicator.m */; }; 14 | A13C067F1A26014F00C8F657 /* DJBezierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = A13C06791A26014F00C8F657 /* DJBezierPath.m */; }; 15 | A13C06801A26014F00C8F657 /* DJProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = A13C067B1A26014F00C8F657 /* DJProgressHUD.m */; }; 16 | A13C06811A26014F00C8F657 /* DJProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A13C067D1A26014F00C8F657 /* DJProgressIndicator.m */; }; 17 | A13C06871A2626A400C8F657 /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = A13C06841A2626A400C8F657 /* SSKeychain.m */; }; 18 | A13C06881A2626A400C8F657 /* SSKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = A13C06861A2626A400C8F657 /* SSKeychainQuery.m */; }; 19 | A1604E1F1A14DC1B003F916D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1604E1E1A14DC1B003F916D /* main.swift */; }; 20 | A1604E3C1A14EF1B003F916D /* ContentfulModelGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = A1DB6A7E1A10DE0E00F6E5C5 /* ContentfulModelGenerator.m */; }; 21 | A1604E481A15027C003F916D /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1604DDE1A137085003F916D /* SystemConfiguration.framework */; }; 22 | A1B77EAB1C2076B000948DE5 /* ArgumentConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EA31C2076B000948DE5 /* ArgumentConvertible.swift */; }; 23 | A1B77EAC1C2076B000948DE5 /* ArgumentDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EA41C2076B000948DE5 /* ArgumentDescription.swift */; }; 24 | A1B77EAD1C2076B000948DE5 /* ArgumentParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EA51C2076B000948DE5 /* ArgumentParser.swift */; }; 25 | A1B77EAE1C2076B000948DE5 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EA61C2076B000948DE5 /* Command.swift */; }; 26 | A1B77EAF1C2076B000948DE5 /* CommandRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EA71C2076B000948DE5 /* CommandRunner.swift */; }; 27 | A1B77EB11C2076B000948DE5 /* CommandType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EA91C2076B000948DE5 /* CommandType.swift */; }; 28 | A1B77EB21C2076B000948DE5 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EAA1C2076B000948DE5 /* Group.swift */; }; 29 | A1B77EB61C20778100948DE5 /* EntitySerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EB31C20778100948DE5 /* EntitySerializer.swift */; }; 30 | A1B77EB71C20778100948DE5 /* ModelSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EB41C20778100948DE5 /* ModelSerializer.swift */; }; 31 | A1B77EB81C20778100948DE5 /* XMLTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EB51C20778100948DE5 /* XMLTools.swift */; }; 32 | A1B77EBD1C20779400948DE5 /* ECoXiS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EB91C20779400948DE5 /* ECoXiS.swift */; }; 33 | A1B77EBE1C20779400948DE5 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EBA1C20779400948DE5 /* Model.swift */; }; 34 | A1B77EBF1C20779400948DE5 /* StringCreation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EBB1C20779400948DE5 /* StringCreation.swift */; }; 35 | A1B77EC01C20779400948DE5 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EBC1C20779400948DE5 /* Utilities.swift */; }; 36 | A1B77EC41C207B7C00948DE5 /* FileHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EC31C207B7C00948DE5 /* FileHandle.swift */; }; 37 | A1B77EC91C207B8C00948DE5 /* Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EC51C207B8C00948DE5 /* Files.swift */; }; 38 | A1B77ECA1C207B8C00948DE5 /* Pipes.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EC61C207B8C00948DE5 /* Pipes.swift */; }; 39 | A1B77ECB1C207B8C00948DE5 /* Stream.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EC71C207B8C00948DE5 /* Stream.swift */; }; 40 | A1B77ECC1C207B8C00948DE5 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B77EC81C207B8C00948DE5 /* String.swift */; }; 41 | A1CD7B6B1A24CE61009CF393 /* XcodeProjectManipulation.m in Sources */ = {isa = PBXBuildFile; fileRef = A1CD7B691A24CE4E009CF393 /* XcodeProjectManipulation.m */; }; 42 | A1DB6A501A10CE9500F6E5C5 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1DB6A4F1A10CE9500F6E5C5 /* AppKit.framework */; }; 43 | A1DB6A521A10CE9500F6E5C5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1DB6A511A10CE9500F6E5C5 /* Foundation.framework */; }; 44 | A1DB6A5A1A10CE9500F6E5C5 /* ContentfulPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = A1DB6A591A10CE9500F6E5C5 /* ContentfulPlugin.m */; }; 45 | A1DB6A6E1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = A1DB6A6C1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.m */; }; 46 | A1DB6A6F1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1DB6A6D1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.xib */; }; 47 | A1EB3C8E1C5FB3D500B4B645 /* libPods-ContentfulModelGenerator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BAF77B4A9BA90550AB215F45 /* libPods-ContentfulModelGenerator.a */; }; 48 | A1FB1CBD1A9647AF00ACE078 /* BBUSegmentTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = A1FB1CBC1A9647AF00ACE078 /* BBUSegmentTracker.m */; }; 49 | DED7C6CF88A65F0ADA2CFF7B /* libPods-ContentfulModelGenerator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BAF77B4A9BA90550AB215F45 /* libPods-ContentfulModelGenerator.a */; }; 50 | /* End PBXBuildFile section */ 51 | 52 | /* Begin PBXCopyFilesBuildPhase section */ 53 | A1604E1A1A14DC1B003F916D /* CopyFiles */ = { 54 | isa = PBXCopyFilesBuildPhase; 55 | buildActionMask = 2147483647; 56 | dstPath = /usr/share/man/man1/; 57 | dstSubfolderSpec = 0; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 1; 61 | }; 62 | /* End PBXCopyFilesBuildPhase section */ 63 | 64 | /* Begin PBXFileReference section */ 65 | 3CB8D5FDCA27AB089A758488 /* libPods-ContentfulPlugin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ContentfulPlugin.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | 5CF20D27CF7AAD1D7E583C79 /* Pods-ContentfulPlugin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ContentfulPlugin.release.xcconfig"; path = "Pods/Target Support Files/Pods-ContentfulPlugin/Pods-ContentfulPlugin.release.xcconfig"; sourceTree = ""; }; 67 | 64D05EB3EB92A288E05E68A0 /* Pods-ContentfulPlugin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ContentfulPlugin.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ContentfulPlugin/Pods-ContentfulPlugin.debug.xcconfig"; sourceTree = ""; }; 68 | A117BED01A238E4200C53D65 /* ContentfulModelGenerator */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = ContentfulModelGenerator; sourceTree = ""; }; 69 | A117BED21A2398D500C53D65 /* ContentfulDeliveryAPI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ContentfulDeliveryAPI.framework; path = Resources/ContentfulDeliveryAPI.framework; sourceTree = ""; }; 70 | A117BED31A2398D500C53D65 /* ContentfulManagementAPI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ContentfulManagementAPI.framework; path = Resources/ContentfulManagementAPI.framework; sourceTree = ""; }; 71 | A13C06761A26014F00C8F657 /* DJActivityIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DJActivityIndicator.h; path = vendor/DJProgressHUD/DJProgressHUD/DJActivityIndicator.h; sourceTree = SOURCE_ROOT; }; 72 | A13C06771A26014F00C8F657 /* DJActivityIndicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DJActivityIndicator.m; path = vendor/DJProgressHUD/DJProgressHUD/DJActivityIndicator.m; sourceTree = SOURCE_ROOT; }; 73 | A13C06781A26014F00C8F657 /* DJBezierPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DJBezierPath.h; path = vendor/DJProgressHUD/DJProgressHUD/DJBezierPath.h; sourceTree = SOURCE_ROOT; }; 74 | A13C06791A26014F00C8F657 /* DJBezierPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DJBezierPath.m; path = vendor/DJProgressHUD/DJProgressHUD/DJBezierPath.m; sourceTree = SOURCE_ROOT; }; 75 | A13C067A1A26014F00C8F657 /* DJProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DJProgressHUD.h; path = vendor/DJProgressHUD/DJProgressHUD/DJProgressHUD.h; sourceTree = SOURCE_ROOT; }; 76 | A13C067B1A26014F00C8F657 /* DJProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DJProgressHUD.m; path = vendor/DJProgressHUD/DJProgressHUD/DJProgressHUD.m; sourceTree = SOURCE_ROOT; }; 77 | A13C067C1A26014F00C8F657 /* DJProgressIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DJProgressIndicator.h; path = vendor/DJProgressHUD/DJProgressHUD/DJProgressIndicator.h; sourceTree = SOURCE_ROOT; }; 78 | A13C067D1A26014F00C8F657 /* DJProgressIndicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DJProgressIndicator.m; path = vendor/DJProgressHUD/DJProgressHUD/DJProgressIndicator.m; sourceTree = SOURCE_ROOT; }; 79 | A13C06831A2626A400C8F657 /* SSKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SSKeychain.h; path = vendor/sskeychain/SSKeychain/SSKeychain.h; sourceTree = SOURCE_ROOT; }; 80 | A13C06841A2626A400C8F657 /* SSKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SSKeychain.m; path = vendor/sskeychain/SSKeychain/SSKeychain.m; sourceTree = SOURCE_ROOT; }; 81 | A13C06851A2626A400C8F657 /* SSKeychainQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SSKeychainQuery.h; path = vendor/sskeychain/SSKeychain/SSKeychainQuery.h; sourceTree = SOURCE_ROOT; }; 82 | A13C06861A2626A400C8F657 /* SSKeychainQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SSKeychainQuery.m; path = vendor/sskeychain/SSKeychain/SSKeychainQuery.m; sourceTree = SOURCE_ROOT; }; 83 | A1604DDE1A137085003F916D /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 84 | A1604E1C1A14DC1B003F916D /* ContentfulModelGenerator */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ContentfulModelGenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 85 | A1604E1E1A14DC1B003F916D /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 86 | A1604E3E1A14FB51003F916D /* ContentfulModelGenerator-Bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ContentfulModelGenerator-Bridge.h"; sourceTree = ""; }; 87 | A1B77EA31C2076B000948DE5 /* ArgumentConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ArgumentConvertible.swift; path = vendor/CLIKit/Sources/ArgumentConvertible.swift; sourceTree = SOURCE_ROOT; }; 88 | A1B77EA41C2076B000948DE5 /* ArgumentDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ArgumentDescription.swift; path = vendor/CLIKit/Sources/ArgumentDescription.swift; sourceTree = SOURCE_ROOT; }; 89 | A1B77EA51C2076B000948DE5 /* ArgumentParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ArgumentParser.swift; path = vendor/CLIKit/Sources/ArgumentParser.swift; sourceTree = SOURCE_ROOT; }; 90 | A1B77EA61C2076B000948DE5 /* Command.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Command.swift; path = vendor/CLIKit/Sources/Command.swift; sourceTree = SOURCE_ROOT; }; 91 | A1B77EA71C2076B000948DE5 /* CommandRunner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CommandRunner.swift; path = vendor/CLIKit/Sources/CommandRunner.swift; sourceTree = SOURCE_ROOT; }; 92 | A1B77EA91C2076B000948DE5 /* CommandType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CommandType.swift; path = vendor/CLIKit/Sources/CommandType.swift; sourceTree = SOURCE_ROOT; }; 93 | A1B77EAA1C2076B000948DE5 /* Group.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Group.swift; path = vendor/CLIKit/Sources/Group.swift; sourceTree = SOURCE_ROOT; }; 94 | A1B77EB31C20778100948DE5 /* EntitySerializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EntitySerializer.swift; path = vendor/ManagedObjectModelSerializer/Code/EntitySerializer.swift; sourceTree = SOURCE_ROOT; }; 95 | A1B77EB41C20778100948DE5 /* ModelSerializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ModelSerializer.swift; path = vendor/ManagedObjectModelSerializer/Code/ModelSerializer.swift; sourceTree = SOURCE_ROOT; }; 96 | A1B77EB51C20778100948DE5 /* XMLTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XMLTools.swift; path = vendor/ManagedObjectModelSerializer/Code/XMLTools.swift; sourceTree = SOURCE_ROOT; }; 97 | A1B77EB91C20779400948DE5 /* ECoXiS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ECoXiS.swift; path = vendor/ManagedObjectModelSerializer/vendor/ECoXiS/ECoXiS/ECoXiS.swift; sourceTree = SOURCE_ROOT; }; 98 | A1B77EBA1C20779400948DE5 /* Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Model.swift; path = vendor/ManagedObjectModelSerializer/vendor/ECoXiS/ECoXiS/Model.swift; sourceTree = SOURCE_ROOT; }; 99 | A1B77EBB1C20779400948DE5 /* StringCreation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StringCreation.swift; path = vendor/ManagedObjectModelSerializer/vendor/ECoXiS/ECoXiS/StringCreation.swift; sourceTree = SOURCE_ROOT; }; 100 | A1B77EBC1C20779400948DE5 /* Utilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Utilities.swift; path = vendor/ManagedObjectModelSerializer/vendor/ECoXiS/ECoXiS/Utilities.swift; sourceTree = SOURCE_ROOT; }; 101 | A1B77EC31C207B7C00948DE5 /* FileHandle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FileHandle.swift; path = vendor/ManagedObjectModelSerializer/vendor/SwiftShell/SwiftShell/FileHandle.swift; sourceTree = SOURCE_ROOT; }; 102 | A1B77EC51C207B8C00948DE5 /* Files.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Files.swift; path = vendor/ManagedObjectModelSerializer/vendor/SwiftShell/SwiftShell/Files.swift; sourceTree = SOURCE_ROOT; }; 103 | A1B77EC61C207B8C00948DE5 /* Pipes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Pipes.swift; path = vendor/ManagedObjectModelSerializer/vendor/SwiftShell/SwiftShell/Pipes.swift; sourceTree = SOURCE_ROOT; }; 104 | A1B77EC71C207B8C00948DE5 /* Stream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Stream.swift; path = vendor/ManagedObjectModelSerializer/vendor/SwiftShell/SwiftShell/Stream.swift; sourceTree = SOURCE_ROOT; }; 105 | A1B77EC81C207B8C00948DE5 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = String.swift; path = vendor/ManagedObjectModelSerializer/vendor/SwiftShell/SwiftShell/String.swift; sourceTree = SOURCE_ROOT; }; 106 | A1CD7B681A24CE4E009CF393 /* XcodeProjectManipulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XcodeProjectManipulation.h; sourceTree = ""; }; 107 | A1CD7B691A24CE4E009CF393 /* XcodeProjectManipulation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XcodeProjectManipulation.m; sourceTree = ""; }; 108 | A1DB6A4C1A10CE9500F6E5C5 /* ContentfulPlugin.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ContentfulPlugin.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 109 | A1DB6A4F1A10CE9500F6E5C5 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 110 | A1DB6A511A10CE9500F6E5C5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 111 | A1DB6A551A10CE9500F6E5C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 112 | A1DB6A581A10CE9500F6E5C5 /* ContentfulPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentfulPlugin.h; sourceTree = ""; }; 113 | A1DB6A591A10CE9500F6E5C5 /* ContentfulPlugin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContentfulPlugin.m; sourceTree = ""; }; 114 | A1DB6A6B1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentTypeSelectionDialog.h; sourceTree = ""; }; 115 | A1DB6A6C1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentTypeSelectionDialog.m; sourceTree = ""; }; 116 | A1DB6A6D1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContentTypeSelectionDialog.xib; sourceTree = ""; }; 117 | A1DB6A7D1A10DE0E00F6E5C5 /* ContentfulModelGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentfulModelGenerator.h; sourceTree = ""; }; 118 | A1DB6A7E1A10DE0E00F6E5C5 /* ContentfulModelGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentfulModelGenerator.m; sourceTree = ""; }; 119 | A1EB3C8C1C5FB3C700B4B645 /* libPods-ContentfulPlugin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-ContentfulPlugin.a"; path = "Pods/../build/Debug/libPods-ContentfulPlugin.a"; sourceTree = ""; }; 120 | A1FB1CBB1A9647AF00ACE078 /* BBUSegmentTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BBUSegmentTracker.h; path = "vendor/segmentio-simple/Pod/Classes/BBUSegmentTracker.h"; sourceTree = SOURCE_ROOT; }; 121 | A1FB1CBC1A9647AF00ACE078 /* BBUSegmentTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BBUSegmentTracker.m; path = "vendor/segmentio-simple/Pod/Classes/BBUSegmentTracker.m"; sourceTree = SOURCE_ROOT; }; 122 | BAF77B4A9BA90550AB215F45 /* libPods-ContentfulModelGenerator.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ContentfulModelGenerator.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 123 | C48FF99824D2B350DD74FB8E /* Pods-ContentfulModelGenerator.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ContentfulModelGenerator.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ContentfulModelGenerator/Pods-ContentfulModelGenerator.debug.xcconfig"; sourceTree = ""; }; 124 | DD57C74B0474C375139CE7F5 /* Pods-ContentfulModelGenerator.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ContentfulModelGenerator.release.xcconfig"; path = "Pods/Target Support Files/Pods-ContentfulModelGenerator/Pods-ContentfulModelGenerator.release.xcconfig"; sourceTree = ""; }; 125 | /* End PBXFileReference section */ 126 | 127 | /* Begin PBXFrameworksBuildPhase section */ 128 | A1604E191A14DC1B003F916D /* Frameworks */ = { 129 | isa = PBXFrameworksBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | A1604E481A15027C003F916D /* SystemConfiguration.framework in Frameworks */, 133 | DED7C6CF88A65F0ADA2CFF7B /* libPods-ContentfulModelGenerator.a in Frameworks */, 134 | ); 135 | runOnlyForDeploymentPostprocessing = 0; 136 | }; 137 | A1DB6A4A1A10CE9500F6E5C5 /* Frameworks */ = { 138 | isa = PBXFrameworksBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | A1EB3C8E1C5FB3D500B4B645 /* libPods-ContentfulModelGenerator.a in Frameworks */, 142 | A117BED61A23995C00C53D65 /* SystemConfiguration.framework in Frameworks */, 143 | A1DB6A501A10CE9500F6E5C5 /* AppKit.framework in Frameworks */, 144 | A1DB6A521A10CE9500F6E5C5 /* Foundation.framework in Frameworks */, 145 | 6154FD3B483A7E28F3BAE079 /* libPods-ContentfulPlugin.a in Frameworks */, 146 | ); 147 | runOnlyForDeploymentPostprocessing = 0; 148 | }; 149 | /* End PBXFrameworksBuildPhase section */ 150 | 151 | /* Begin PBXGroup section */ 152 | 65297FDFBB249D19CC216C1D /* Pods */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | C48FF99824D2B350DD74FB8E /* Pods-ContentfulModelGenerator.debug.xcconfig */, 156 | DD57C74B0474C375139CE7F5 /* Pods-ContentfulModelGenerator.release.xcconfig */, 157 | 64D05EB3EB92A288E05E68A0 /* Pods-ContentfulPlugin.debug.xcconfig */, 158 | 5CF20D27CF7AAD1D7E583C79 /* Pods-ContentfulPlugin.release.xcconfig */, 159 | ); 160 | name = Pods; 161 | sourceTree = ""; 162 | }; 163 | A13C06751A26013200C8F657 /* DJProgressHUD */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | A13C06761A26014F00C8F657 /* DJActivityIndicator.h */, 167 | A13C06771A26014F00C8F657 /* DJActivityIndicator.m */, 168 | A13C06781A26014F00C8F657 /* DJBezierPath.h */, 169 | A13C06791A26014F00C8F657 /* DJBezierPath.m */, 170 | A13C067A1A26014F00C8F657 /* DJProgressHUD.h */, 171 | A13C067B1A26014F00C8F657 /* DJProgressHUD.m */, 172 | A13C067C1A26014F00C8F657 /* DJProgressIndicator.h */, 173 | A13C067D1A26014F00C8F657 /* DJProgressIndicator.m */, 174 | ); 175 | name = DJProgressHUD; 176 | sourceTree = ""; 177 | }; 178 | A13C06821A26268600C8F657 /* SSKeychain */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | A13C06831A2626A400C8F657 /* SSKeychain.h */, 182 | A13C06841A2626A400C8F657 /* SSKeychain.m */, 183 | A13C06851A2626A400C8F657 /* SSKeychainQuery.h */, 184 | A13C06861A2626A400C8F657 /* SSKeychainQuery.m */, 185 | ); 186 | name = SSKeychain; 187 | sourceTree = ""; 188 | }; 189 | A1604E231A14EE1E003F916D /* MOMSerializer */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | A1B77EB91C20779400948DE5 /* ECoXiS.swift */, 193 | A1B77EB31C20778100948DE5 /* EntitySerializer.swift */, 194 | A1B77EC31C207B7C00948DE5 /* FileHandle.swift */, 195 | A1B77EC51C207B8C00948DE5 /* Files.swift */, 196 | A1B77EBA1C20779400948DE5 /* Model.swift */, 197 | A1B77EB41C20778100948DE5 /* ModelSerializer.swift */, 198 | A1B77EC61C207B8C00948DE5 /* Pipes.swift */, 199 | A1B77EC71C207B8C00948DE5 /* Stream.swift */, 200 | A1B77EC81C207B8C00948DE5 /* String.swift */, 201 | A1B77EBB1C20779400948DE5 /* StringCreation.swift */, 202 | A1B77EBC1C20779400948DE5 /* Utilities.swift */, 203 | A1B77EB51C20778100948DE5 /* XMLTools.swift */, 204 | ); 205 | path = MOMSerializer; 206 | sourceTree = ""; 207 | }; 208 | A1604E3F1A14FD0A003F916D /* CLIKit */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | A1B77EA31C2076B000948DE5 /* ArgumentConvertible.swift */, 212 | A1B77EA41C2076B000948DE5 /* ArgumentDescription.swift */, 213 | A1B77EA51C2076B000948DE5 /* ArgumentParser.swift */, 214 | A1B77EA61C2076B000948DE5 /* Command.swift */, 215 | A1B77EA71C2076B000948DE5 /* CommandRunner.swift */, 216 | A1B77EA91C2076B000948DE5 /* CommandType.swift */, 217 | A1B77EAA1C2076B000948DE5 /* Group.swift */, 218 | ); 219 | name = CLIKit; 220 | sourceTree = ""; 221 | }; 222 | A1DB6A431A10CE9500F6E5C5 = { 223 | isa = PBXGroup; 224 | children = ( 225 | A1DB6A531A10CE9500F6E5C5 /* Code */, 226 | A1DB6A4E1A10CE9500F6E5C5 /* Frameworks */, 227 | 65297FDFBB249D19CC216C1D /* Pods */, 228 | A1DB6A4D1A10CE9500F6E5C5 /* Products */, 229 | A1DB6A621A10D87000F6E5C5 /* Resources */, 230 | A1DB6A541A10CE9500F6E5C5 /* Supporting Files */, 231 | ); 232 | sourceTree = ""; 233 | }; 234 | A1DB6A4D1A10CE9500F6E5C5 /* Products */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | A1DB6A4C1A10CE9500F6E5C5 /* ContentfulPlugin.xcplugin */, 238 | A1604E1C1A14DC1B003F916D /* ContentfulModelGenerator */, 239 | ); 240 | name = Products; 241 | sourceTree = ""; 242 | }; 243 | A1DB6A4E1A10CE9500F6E5C5 /* Frameworks */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | A1EB3C8C1C5FB3C700B4B645 /* libPods-ContentfulPlugin.a */, 247 | A1DB6A4F1A10CE9500F6E5C5 /* AppKit.framework */, 248 | A117BED21A2398D500C53D65 /* ContentfulDeliveryAPI.framework */, 249 | A117BED31A2398D500C53D65 /* ContentfulManagementAPI.framework */, 250 | A1DB6A511A10CE9500F6E5C5 /* Foundation.framework */, 251 | A1604DDE1A137085003F916D /* SystemConfiguration.framework */, 252 | BAF77B4A9BA90550AB215F45 /* libPods-ContentfulModelGenerator.a */, 253 | 3CB8D5FDCA27AB089A758488 /* libPods-ContentfulPlugin.a */, 254 | ); 255 | name = Frameworks; 256 | sourceTree = ""; 257 | }; 258 | A1DB6A531A10CE9500F6E5C5 /* Code */ = { 259 | isa = PBXGroup; 260 | children = ( 261 | A1604E3F1A14FD0A003F916D /* CLIKit */, 262 | A13C06751A26013200C8F657 /* DJProgressHUD */, 263 | A1604E231A14EE1E003F916D /* MOMSerializer */, 264 | A1FB1CBA1A96479200ACE078 /* SegmentIO */, 265 | A13C06821A26268600C8F657 /* SSKeychain */, 266 | A1604E3E1A14FB51003F916D /* ContentfulModelGenerator-Bridge.h */, 267 | A1DB6A7D1A10DE0E00F6E5C5 /* ContentfulModelGenerator.h */, 268 | A1DB6A7E1A10DE0E00F6E5C5 /* ContentfulModelGenerator.m */, 269 | A1DB6A581A10CE9500F6E5C5 /* ContentfulPlugin.h */, 270 | A1DB6A591A10CE9500F6E5C5 /* ContentfulPlugin.m */, 271 | A1DB6A6B1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.h */, 272 | A1DB6A6C1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.m */, 273 | A1604E1E1A14DC1B003F916D /* main.swift */, 274 | A1CD7B681A24CE4E009CF393 /* XcodeProjectManipulation.h */, 275 | A1CD7B691A24CE4E009CF393 /* XcodeProjectManipulation.m */, 276 | ); 277 | path = Code; 278 | sourceTree = ""; 279 | }; 280 | A1DB6A541A10CE9500F6E5C5 /* Supporting Files */ = { 281 | isa = PBXGroup; 282 | children = ( 283 | A1DB6A551A10CE9500F6E5C5 /* Info.plist */, 284 | ); 285 | path = "Supporting Files"; 286 | sourceTree = ""; 287 | }; 288 | A1DB6A621A10D87000F6E5C5 /* Resources */ = { 289 | isa = PBXGroup; 290 | children = ( 291 | A117BED01A238E4200C53D65 /* ContentfulModelGenerator */, 292 | A1DB6A6D1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.xib */, 293 | ); 294 | path = Resources; 295 | sourceTree = ""; 296 | }; 297 | A1FB1CBA1A96479200ACE078 /* SegmentIO */ = { 298 | isa = PBXGroup; 299 | children = ( 300 | A1FB1CBB1A9647AF00ACE078 /* BBUSegmentTracker.h */, 301 | A1FB1CBC1A9647AF00ACE078 /* BBUSegmentTracker.m */, 302 | ); 303 | name = SegmentIO; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXGroup section */ 307 | 308 | /* Begin PBXNativeTarget section */ 309 | A1604E1B1A14DC1B003F916D /* ContentfulModelGenerator */ = { 310 | isa = PBXNativeTarget; 311 | buildConfigurationList = A1604E221A14DC1B003F916D /* Build configuration list for PBXNativeTarget "ContentfulModelGenerator" */; 312 | buildPhases = ( 313 | F10FD8B23F40C05FDA50EFF9 /* [CP] Check Pods Manifest.lock */, 314 | A1604E181A14DC1B003F916D /* Sources */, 315 | A1604E191A14DC1B003F916D /* Frameworks */, 316 | A1604E1A1A14DC1B003F916D /* CopyFiles */, 317 | 5055E2B6320CC2AD8B46BE3B /* [CP] Copy Pods Resources */, 318 | ); 319 | buildRules = ( 320 | ); 321 | dependencies = ( 322 | ); 323 | name = ContentfulModelGenerator; 324 | productName = ContentfulModelGenerator; 325 | productReference = A1604E1C1A14DC1B003F916D /* ContentfulModelGenerator */; 326 | productType = "com.apple.product-type.tool"; 327 | }; 328 | A1DB6A4B1A10CE9500F6E5C5 /* ContentfulPlugin */ = { 329 | isa = PBXNativeTarget; 330 | buildConfigurationList = A1DB6A5D1A10CE9500F6E5C5 /* Build configuration list for PBXNativeTarget "ContentfulPlugin" */; 331 | buildPhases = ( 332 | 220D6A4F6AF6A0CA193819EC /* [CP] Check Pods Manifest.lock */, 333 | A1DB6A481A10CE9500F6E5C5 /* Sources */, 334 | A1DB6A491A10CE9500F6E5C5 /* Resources */, 335 | A1DB6A4A1A10CE9500F6E5C5 /* Frameworks */, 336 | DD207DAFB79E2E89C47446B6 /* [CP] Copy Pods Resources */, 337 | ); 338 | buildRules = ( 339 | ); 340 | dependencies = ( 341 | ); 342 | name = ContentfulPlugin; 343 | productName = ContentfulPlugin; 344 | productReference = A1DB6A4C1A10CE9500F6E5C5 /* ContentfulPlugin.xcplugin */; 345 | productType = "com.apple.product-type.bundle"; 346 | }; 347 | /* End PBXNativeTarget section */ 348 | 349 | /* Begin PBXProject section */ 350 | A1DB6A441A10CE9500F6E5C5 /* Project object */ = { 351 | isa = PBXProject; 352 | attributes = { 353 | LastSwiftUpdateCheck = 0700; 354 | LastUpgradeCheck = 0800; 355 | ORGANIZATIONNAME = "Contentful GmbH"; 356 | TargetAttributes = { 357 | A1604E1B1A14DC1B003F916D = { 358 | CreatedOnToolsVersion = 6.1; 359 | }; 360 | A1DB6A4B1A10CE9500F6E5C5 = { 361 | CreatedOnToolsVersion = 6.1; 362 | }; 363 | }; 364 | }; 365 | buildConfigurationList = A1DB6A471A10CE9500F6E5C5 /* Build configuration list for PBXProject "ContentfulPlugin" */; 366 | compatibilityVersion = "Xcode 3.2"; 367 | developmentRegion = English; 368 | hasScannedForEncodings = 0; 369 | knownRegions = ( 370 | en, 371 | ); 372 | mainGroup = A1DB6A431A10CE9500F6E5C5; 373 | productRefGroup = A1DB6A4D1A10CE9500F6E5C5 /* Products */; 374 | projectDirPath = ""; 375 | projectRoot = ""; 376 | targets = ( 377 | A1604E1B1A14DC1B003F916D /* ContentfulModelGenerator */, 378 | A1DB6A4B1A10CE9500F6E5C5 /* ContentfulPlugin */, 379 | ); 380 | }; 381 | /* End PBXProject section */ 382 | 383 | /* Begin PBXResourcesBuildPhase section */ 384 | A1DB6A491A10CE9500F6E5C5 /* Resources */ = { 385 | isa = PBXResourcesBuildPhase; 386 | buildActionMask = 2147483647; 387 | files = ( 388 | A117BED11A238E4200C53D65 /* ContentfulModelGenerator in Resources */, 389 | A1DB6A6F1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.xib in Resources */, 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | /* End PBXResourcesBuildPhase section */ 394 | 395 | /* Begin PBXShellScriptBuildPhase section */ 396 | 220D6A4F6AF6A0CA193819EC /* [CP] Check Pods Manifest.lock */ = { 397 | isa = PBXShellScriptBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | ); 401 | inputPaths = ( 402 | ); 403 | name = "[CP] Check Pods Manifest.lock"; 404 | outputPaths = ( 405 | ); 406 | runOnlyForDeploymentPostprocessing = 0; 407 | shellPath = /bin/sh; 408 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 409 | showEnvVarsInLog = 0; 410 | }; 411 | 5055E2B6320CC2AD8B46BE3B /* [CP] Copy Pods Resources */ = { 412 | isa = PBXShellScriptBuildPhase; 413 | buildActionMask = 2147483647; 414 | files = ( 415 | ); 416 | inputPaths = ( 417 | ); 418 | name = "[CP] Copy Pods Resources"; 419 | outputPaths = ( 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | shellPath = /bin/sh; 423 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ContentfulModelGenerator/Pods-ContentfulModelGenerator-resources.sh\"\n"; 424 | showEnvVarsInLog = 0; 425 | }; 426 | DD207DAFB79E2E89C47446B6 /* [CP] Copy Pods Resources */ = { 427 | isa = PBXShellScriptBuildPhase; 428 | buildActionMask = 2147483647; 429 | files = ( 430 | ); 431 | inputPaths = ( 432 | ); 433 | name = "[CP] Copy Pods Resources"; 434 | outputPaths = ( 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | shellPath = /bin/sh; 438 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ContentfulPlugin/Pods-ContentfulPlugin-resources.sh\"\n"; 439 | showEnvVarsInLog = 0; 440 | }; 441 | F10FD8B23F40C05FDA50EFF9 /* [CP] Check Pods Manifest.lock */ = { 442 | isa = PBXShellScriptBuildPhase; 443 | buildActionMask = 2147483647; 444 | files = ( 445 | ); 446 | inputPaths = ( 447 | ); 448 | name = "[CP] Check Pods Manifest.lock"; 449 | outputPaths = ( 450 | ); 451 | runOnlyForDeploymentPostprocessing = 0; 452 | shellPath = /bin/sh; 453 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 454 | showEnvVarsInLog = 0; 455 | }; 456 | /* End PBXShellScriptBuildPhase section */ 457 | 458 | /* Begin PBXSourcesBuildPhase section */ 459 | A1604E181A14DC1B003F916D /* Sources */ = { 460 | isa = PBXSourcesBuildPhase; 461 | buildActionMask = 2147483647; 462 | files = ( 463 | A1B77EBE1C20779400948DE5 /* Model.swift in Sources */, 464 | A1B77EB11C2076B000948DE5 /* CommandType.swift in Sources */, 465 | A1604E1F1A14DC1B003F916D /* main.swift in Sources */, 466 | A1B77EB71C20778100948DE5 /* ModelSerializer.swift in Sources */, 467 | A1B77EAE1C2076B000948DE5 /* Command.swift in Sources */, 468 | A1604E3C1A14EF1B003F916D /* ContentfulModelGenerator.m in Sources */, 469 | A1B77EAF1C2076B000948DE5 /* CommandRunner.swift in Sources */, 470 | A1B77EB81C20778100948DE5 /* XMLTools.swift in Sources */, 471 | A1B77EB21C2076B000948DE5 /* Group.swift in Sources */, 472 | A1B77EC01C20779400948DE5 /* Utilities.swift in Sources */, 473 | A1B77EAB1C2076B000948DE5 /* ArgumentConvertible.swift in Sources */, 474 | A1B77EC91C207B8C00948DE5 /* Files.swift in Sources */, 475 | A1B77EBF1C20779400948DE5 /* StringCreation.swift in Sources */, 476 | A1B77EBD1C20779400948DE5 /* ECoXiS.swift in Sources */, 477 | A1B77EAC1C2076B000948DE5 /* ArgumentDescription.swift in Sources */, 478 | A1B77ECA1C207B8C00948DE5 /* Pipes.swift in Sources */, 479 | A1B77EC41C207B7C00948DE5 /* FileHandle.swift in Sources */, 480 | A1B77EB61C20778100948DE5 /* EntitySerializer.swift in Sources */, 481 | A1B77ECC1C207B8C00948DE5 /* String.swift in Sources */, 482 | A1B77EAD1C2076B000948DE5 /* ArgumentParser.swift in Sources */, 483 | A1B77ECB1C207B8C00948DE5 /* Stream.swift in Sources */, 484 | ); 485 | runOnlyForDeploymentPostprocessing = 0; 486 | }; 487 | A1DB6A481A10CE9500F6E5C5 /* Sources */ = { 488 | isa = PBXSourcesBuildPhase; 489 | buildActionMask = 2147483647; 490 | files = ( 491 | A13C067F1A26014F00C8F657 /* DJBezierPath.m in Sources */, 492 | A13C06881A2626A400C8F657 /* SSKeychainQuery.m in Sources */, 493 | A13C06871A2626A400C8F657 /* SSKeychain.m in Sources */, 494 | A13C06811A26014F00C8F657 /* DJProgressIndicator.m in Sources */, 495 | A1FB1CBD1A9647AF00ACE078 /* BBUSegmentTracker.m in Sources */, 496 | A13C067E1A26014F00C8F657 /* DJActivityIndicator.m in Sources */, 497 | A1DB6A6E1A10DAF100F6E5C5 /* ContentTypeSelectionDialog.m in Sources */, 498 | A1CD7B6B1A24CE61009CF393 /* XcodeProjectManipulation.m in Sources */, 499 | A13C06801A26014F00C8F657 /* DJProgressHUD.m in Sources */, 500 | A1DB6A5A1A10CE9500F6E5C5 /* ContentfulPlugin.m in Sources */, 501 | ); 502 | runOnlyForDeploymentPostprocessing = 0; 503 | }; 504 | /* End PBXSourcesBuildPhase section */ 505 | 506 | /* Begin XCBuildConfiguration section */ 507 | A1604E201A14DC1B003F916D /* Debug */ = { 508 | isa = XCBuildConfiguration; 509 | baseConfigurationReference = C48FF99824D2B350DD74FB8E /* Pods-ContentfulModelGenerator.debug.xcconfig */; 510 | buildSettings = { 511 | FRAMEWORK_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "$(PROJECT_DIR)", 514 | ); 515 | GCC_PREPROCESSOR_DEFINITIONS = ( 516 | "DEBUG=1", 517 | "$(inherited)", 518 | ); 519 | MACOSX_DEPLOYMENT_TARGET = 10.9; 520 | PRODUCT_NAME = "$(TARGET_NAME)"; 521 | SDKROOT = macosx; 522 | SWIFT_OBJC_BRIDGING_HEADER = "Code/ContentfulModelGenerator-Bridge.h"; 523 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 524 | SWIFT_VERSION = 2.3; 525 | }; 526 | name = Debug; 527 | }; 528 | A1604E211A14DC1B003F916D /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | baseConfigurationReference = DD57C74B0474C375139CE7F5 /* Pods-ContentfulModelGenerator.release.xcconfig */; 531 | buildSettings = { 532 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 533 | FRAMEWORK_SEARCH_PATHS = ( 534 | "$(inherited)", 535 | "$(PROJECT_DIR)", 536 | ); 537 | MACOSX_DEPLOYMENT_TARGET = 10.9; 538 | PRODUCT_NAME = "$(TARGET_NAME)"; 539 | SDKROOT = macosx; 540 | SWIFT_OBJC_BRIDGING_HEADER = "Code/ContentfulModelGenerator-Bridge.h"; 541 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 542 | SWIFT_VERSION = 2.3; 543 | }; 544 | name = Release; 545 | }; 546 | A1DB6A5B1A10CE9500F6E5C5 /* Debug */ = { 547 | isa = XCBuildConfiguration; 548 | buildSettings = { 549 | ALWAYS_SEARCH_USER_PATHS = NO; 550 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 551 | CLANG_CXX_LIBRARY = "libc++"; 552 | CLANG_ENABLE_MODULES = YES; 553 | CLANG_ENABLE_OBJC_ARC = YES; 554 | CLANG_WARN_BOOL_CONVERSION = YES; 555 | CLANG_WARN_CONSTANT_CONVERSION = YES; 556 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 557 | CLANG_WARN_EMPTY_BODY = YES; 558 | CLANG_WARN_ENUM_CONVERSION = YES; 559 | CLANG_WARN_INT_CONVERSION = YES; 560 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 561 | CLANG_WARN_UNREACHABLE_CODE = YES; 562 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 563 | COPY_PHASE_STRIP = NO; 564 | ENABLE_STRICT_OBJC_MSGSEND = YES; 565 | ENABLE_TESTABILITY = YES; 566 | GCC_C_LANGUAGE_STANDARD = gnu99; 567 | GCC_DYNAMIC_NO_PIC = NO; 568 | GCC_NO_COMMON_BLOCKS = YES; 569 | GCC_OPTIMIZATION_LEVEL = 0; 570 | GCC_PREPROCESSOR_DEFINITIONS = ( 571 | "DEBUG=1", 572 | "$(inherited)", 573 | ); 574 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 575 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 576 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 577 | GCC_WARN_UNDECLARED_SELECTOR = YES; 578 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 579 | GCC_WARN_UNUSED_FUNCTION = YES; 580 | GCC_WARN_UNUSED_VARIABLE = YES; 581 | MACOSX_DEPLOYMENT_TARGET = 10.9; 582 | MTL_ENABLE_DEBUG_INFO = YES; 583 | ONLY_ACTIVE_ARCH = YES; 584 | }; 585 | name = Debug; 586 | }; 587 | A1DB6A5C1A10CE9500F6E5C5 /* Release */ = { 588 | isa = XCBuildConfiguration; 589 | buildSettings = { 590 | ALWAYS_SEARCH_USER_PATHS = NO; 591 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 592 | CLANG_CXX_LIBRARY = "libc++"; 593 | CLANG_ENABLE_MODULES = YES; 594 | CLANG_ENABLE_OBJC_ARC = YES; 595 | CLANG_WARN_BOOL_CONVERSION = YES; 596 | CLANG_WARN_CONSTANT_CONVERSION = YES; 597 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 598 | CLANG_WARN_EMPTY_BODY = YES; 599 | CLANG_WARN_ENUM_CONVERSION = YES; 600 | CLANG_WARN_INT_CONVERSION = YES; 601 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 602 | CLANG_WARN_UNREACHABLE_CODE = YES; 603 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 604 | COPY_PHASE_STRIP = YES; 605 | ENABLE_NS_ASSERTIONS = NO; 606 | ENABLE_STRICT_OBJC_MSGSEND = YES; 607 | GCC_C_LANGUAGE_STANDARD = gnu99; 608 | GCC_NO_COMMON_BLOCKS = YES; 609 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 610 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 611 | GCC_WARN_UNDECLARED_SELECTOR = YES; 612 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 613 | GCC_WARN_UNUSED_FUNCTION = YES; 614 | GCC_WARN_UNUSED_VARIABLE = YES; 615 | MACOSX_DEPLOYMENT_TARGET = 10.9; 616 | MTL_ENABLE_DEBUG_INFO = NO; 617 | }; 618 | name = Release; 619 | }; 620 | A1DB6A5E1A10CE9500F6E5C5 /* Debug */ = { 621 | isa = XCBuildConfiguration; 622 | baseConfigurationReference = 64D05EB3EB92A288E05E68A0 /* Pods-ContentfulPlugin.debug.xcconfig */; 623 | buildSettings = { 624 | COMBINE_HIDPI_IMAGES = YES; 625 | DEPLOYMENT_LOCATION = YES; 626 | DSTROOT = "$(HOME)"; 627 | FRAMEWORK_SEARCH_PATHS = ( 628 | "$(inherited)", 629 | "$(PROJECT_DIR)", 630 | "$(PROJECT_DIR)/Resources", 631 | ); 632 | HEADER_SEARCH_PATHS = ( 633 | "$(inherited)", 634 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 635 | "$(SRCROOT)/vendor/xcproj/", 636 | ); 637 | INFOPLIST_FILE = "Supporting Files/Info.plist"; 638 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 639 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 640 | MACOSX_DEPLOYMENT_TARGET = 10.9; 641 | PRODUCT_BUNDLE_IDENTIFIER = "com.contentful.$(PRODUCT_NAME:rfc1034identifier)"; 642 | PRODUCT_NAME = "$(TARGET_NAME)"; 643 | WARNING_CFLAGS = "-Wno-undeclared-selector"; 644 | WRAPPER_EXTENSION = xcplugin; 645 | }; 646 | name = Debug; 647 | }; 648 | A1DB6A5F1A10CE9500F6E5C5 /* Release */ = { 649 | isa = XCBuildConfiguration; 650 | baseConfigurationReference = 5CF20D27CF7AAD1D7E583C79 /* Pods-ContentfulPlugin.release.xcconfig */; 651 | buildSettings = { 652 | COMBINE_HIDPI_IMAGES = YES; 653 | DEPLOYMENT_LOCATION = YES; 654 | DSTROOT = "$(HOME)"; 655 | FRAMEWORK_SEARCH_PATHS = ( 656 | "$(inherited)", 657 | "$(PROJECT_DIR)", 658 | "$(PROJECT_DIR)/Resources", 659 | ); 660 | HEADER_SEARCH_PATHS = ( 661 | "$(inherited)", 662 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 663 | "$(SRCROOT)/vendor/xcproj/", 664 | ); 665 | INFOPLIST_FILE = "Supporting Files/Info.plist"; 666 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 667 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 668 | MACOSX_DEPLOYMENT_TARGET = 10.9; 669 | PRODUCT_BUNDLE_IDENTIFIER = "com.contentful.$(PRODUCT_NAME:rfc1034identifier)"; 670 | PRODUCT_NAME = "$(TARGET_NAME)"; 671 | WARNING_CFLAGS = "-Wno-undeclared-selector"; 672 | WRAPPER_EXTENSION = xcplugin; 673 | }; 674 | name = Release; 675 | }; 676 | /* End XCBuildConfiguration section */ 677 | 678 | /* Begin XCConfigurationList section */ 679 | A1604E221A14DC1B003F916D /* Build configuration list for PBXNativeTarget "ContentfulModelGenerator" */ = { 680 | isa = XCConfigurationList; 681 | buildConfigurations = ( 682 | A1604E201A14DC1B003F916D /* Debug */, 683 | A1604E211A14DC1B003F916D /* Release */, 684 | ); 685 | defaultConfigurationIsVisible = 0; 686 | defaultConfigurationName = Release; 687 | }; 688 | A1DB6A471A10CE9500F6E5C5 /* Build configuration list for PBXProject "ContentfulPlugin" */ = { 689 | isa = XCConfigurationList; 690 | buildConfigurations = ( 691 | A1DB6A5B1A10CE9500F6E5C5 /* Debug */, 692 | A1DB6A5C1A10CE9500F6E5C5 /* Release */, 693 | ); 694 | defaultConfigurationIsVisible = 0; 695 | defaultConfigurationName = Release; 696 | }; 697 | A1DB6A5D1A10CE9500F6E5C5 /* Build configuration list for PBXNativeTarget "ContentfulPlugin" */ = { 698 | isa = XCConfigurationList; 699 | buildConfigurations = ( 700 | A1DB6A5E1A10CE9500F6E5C5 /* Debug */, 701 | A1DB6A5F1A10CE9500F6E5C5 /* Release */, 702 | ); 703 | defaultConfigurationIsVisible = 0; 704 | defaultConfigurationName = Release; 705 | }; 706 | /* End XCConfigurationList section */ 707 | }; 708 | rootObject = A1DB6A441A10CE9500F6E5C5 /* Project object */; 709 | } 710 | --------------------------------------------------------------------------------