├── Screens
├── main.png
├── demo_map.gif
├── demo_address.gif
└── demo_workspace.gif
├── XLocation
├── Resources
│ └── Icon.png
├── XLWindow.h
├── XLocation-Prefix.pch
├── XLWindow.m
├── Xcode-Private-Classes
│ ├── DVTDualProxyWindow.h
│ ├── DVTSourceTextView.h
│ ├── IDEWorkspaceWindow.h
│ ├── IDEIndexCollection.h
│ ├── IDEEditorDocument.h
│ ├── DVTFilePath.h
│ ├── IDEWorkspace.h
│ └── IDEIndex.h
├── XLMapView.h
├── NSObject_Extension.h
├── Categories
│ ├── NSString+Gpx.h
│ └── NSString+Gpx.m
├── XLocation.h
├── Classes
│ ├── XLWorkspace.h
│ ├── XLAnnotation.h
│ ├── XLAnnotation.m
│ └── XLWorkspace.m
├── NSObject_Extension.m
├── XLWorkspaceView.h
├── Views
│ ├── RMBlurredView.h
│ └── RMBlurredView.m
├── XLMapView.m
├── Info.plist
├── XLWorkspaceView.m
└── XLWindow.xib
├── Dependencies
├── OCLogTemplate
│ ├── README
│ └── OCLogTemplate.h
└── XcodeEditor
│ ├── XcodeEditor.h
│ ├── XcodeGroupMember.h
│ ├── XCAbstractDefinition.m
│ ├── Utils
│ ├── XCKeyBuilder.h
│ └── XCKeyBuilder.m
│ ├── XCFrameworkDefinition.h
│ ├── XCXibDefinition.h
│ ├── XcodeMemberType.h
│ ├── XCSourceFileDefinition.h
│ ├── XCBuildConfiguration.h
│ ├── XcodeSourceFileType.h
│ ├── XCFileOperationQueue.h
│ ├── XCProject+SubProject.h
│ ├── XCAbstractDefinition.h
│ ├── XCClassDefinition.h
│ ├── XCFrameworkDefinition.m
│ ├── XCSubProjectDefinition.h
│ ├── XCXibDefinition.m
│ ├── XCSourceFile.h
│ ├── XCSourceFileDefinition.m
│ ├── XCTarget.h
│ ├── XcodeSourceFileType.m
│ ├── XCClassDefinition.m
│ ├── XcodeMemberType.m
│ ├── XCProject.h
│ ├── XCGroup.h
│ ├── XCFileOperationQueue.m
│ ├── XCSubProjectDefinition.m
│ ├── XCSourceFile.m
│ ├── XCBuildConfiguration.m
│ ├── XCProject.m
│ ├── XCTarget.m
│ ├── XCProject+SubProject.m
│ └── XCGroup.m
├── XLocation.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ └── XLocation.xcscheme
├── .gitignore
├── LICENSE
└── README.md
/Screens/main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StefanLage/XLocation/HEAD/Screens/main.png
--------------------------------------------------------------------------------
/Screens/demo_map.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StefanLage/XLocation/HEAD/Screens/demo_map.gif
--------------------------------------------------------------------------------
/Screens/demo_address.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StefanLage/XLocation/HEAD/Screens/demo_address.gif
--------------------------------------------------------------------------------
/Screens/demo_workspace.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StefanLage/XLocation/HEAD/Screens/demo_workspace.gif
--------------------------------------------------------------------------------
/XLocation/Resources/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StefanLage/XLocation/HEAD/XLocation/Resources/Icon.png
--------------------------------------------------------------------------------
/Dependencies/OCLogTemplate/README:
--------------------------------------------------------------------------------
1 | A logging framework for Objective-C projects.
2 |
3 | Based on Brenwill workshop's Flexible iOS Logging Framework: http://brenwill.com/2010/flexible-ios-logging/
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/XLocation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/XLocation/XLWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // LWindow.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XLWindow : NSWindow
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/XLocation/XLocation-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // XLocation-PRefix.pch
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/09/15.
6 | // Copyright (c) 2015 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #ifdef __OBJC__
10 | #import
11 | #endif
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | */build/*
3 | *.pbxuser
4 | !default.pbxuser
5 | *.mode1v3
6 | !default.mode1v3
7 | *.mode2v3
8 | !default.mode2v3
9 | *.perspectivev3
10 | !default.perspectivev3
11 | xcuserdata
12 | *.moved-aside
13 | DerivedData
14 | .idea/
15 | *.hmap
16 | *.xccheckout
17 |
--------------------------------------------------------------------------------
/XLocation/XLWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // LWindow.m
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import "XLWindow.h"
10 |
11 | @implementation XLWindow
12 |
13 | - (BOOL)canBecomeKeyWindow {
14 | return YES;
15 | }
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/DVTDualProxyWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // DVTDualProxyWindow.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DVTDualProxyWindow : NSWindow
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/DVTSourceTextView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DVTSourceTextView.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DVTSourceTextView : NSTextView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/IDEWorkspaceWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // IDEWorkspaceWindow.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import "DVTDualProxyWindow.h"
10 |
11 | @interface IDEWorkspaceWindow : DVTDualProxyWindow
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/XLocation/XLMapView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LMapView.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/05/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XLMapView : MKMapView
12 |
13 | @property (nonatomic) BOOL isEnable;
14 | -(void)resetRegion;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/IDEIndexCollection.h:
--------------------------------------------------------------------------------
1 | //
2 | // IDEIndexCollection.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IDEIndexCollection : NSObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/XLocation/NSObject_Extension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject_Extension.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/09/15.
6 | // Copyright (c) 2015 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSObject (Xcode_Plugin_Template_Extension)
12 |
13 | + (void)pluginDidLoad:(NSBundle *)plugin;
14 |
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/IDEEditorDocument.h:
--------------------------------------------------------------------------------
1 | //
2 | // IDEEditorDocument.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class DVTFilePath;
12 |
13 | @interface IDEEditorDocument : NSDocument
14 |
15 | @property (retain) DVTFilePath *filePath;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/DVTFilePath.h:
--------------------------------------------------------------------------------
1 | //
2 | // DVTFilePath.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DVTFilePath : NSObject
12 |
13 | @property (readonly) NSString *fileName;
14 | @property (readonly) NSURL *fileURL;
15 | @property (readonly) NSArray *pathComponents;
16 | @property (readonly) NSString *pathString;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/XLocation/Categories/NSString+Gpx.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Gpx.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (Gpx)
12 |
13 | + (NSString *)generateGpxWithFilename:(NSString*) filename latitude:(NSNumber *)lat longitude:(NSNumber *)lng address:(NSString*)address city:(NSString*)city country:(NSString*)country zip:(NSString*)zipCode;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/IDEWorkspace.h:
--------------------------------------------------------------------------------
1 | //
2 | // IDEWorkspace.h
3 | // LXLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class IDEIndex;
12 | @class DVTFilePath;
13 |
14 | @interface IDEWorkspace : NSObject
15 |
16 | @property (retain) IDEIndex *index;
17 | @property (readonly) DVTFilePath *representingFilePath;
18 |
19 | - (void)_updateIndexableFiles:(id)arg1;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/XLocation/Xcode-Private-Classes/IDEIndex.h:
--------------------------------------------------------------------------------
1 | //
2 | // IDEIndex.h
3 | // Lin
4 | //
5 | // Created by Tanaka Katsuma on 2013/08/23.
6 | // Copyright (c) 2013年 Tanaka Katsuma. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class DVTFilePath;
12 |
13 | @interface IDEIndex : NSObject
14 |
15 | @property (readonly, nonatomic) DVTFilePath *workspaceFile;
16 | @property (readonly, nonatomic) NSString *workspaceName;
17 |
18 | - (void)close;
19 | - (id)filesContaining:(id)arg1 anchorStart:(BOOL)arg2 anchorEnd:(BOOL)arg3 subsequence:(BOOL)arg4 ignoreCase:(BOOL)arg5 cancelWhen:(id)arg6;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/XLocation/XLocation.h:
--------------------------------------------------------------------------------
1 | //
2 | // XLocation.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/09/15.
6 | // Copyright (c) 2015 Stefan Lage. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "XLWorkspaceView.h"
11 |
12 | @class XLocation;
13 |
14 | static XLocation *sharedPlugin;
15 |
16 | @interface XLocation : NSObject
17 |
18 | @property (nonatomic, strong, readonly) NSBundle* bundle;
19 |
20 | + (instancetype)sharedPlugin;
21 | - (id)initWithBundle:(NSBundle *)plugin;
22 | - (IBAction)cancel:(id)sender;
23 | - (IBAction)generateFromMap:(id)sender;
24 | - (IBAction)generateFromAddress:(id)sender;
25 |
26 | @end
--------------------------------------------------------------------------------
/XLocation/Classes/XLWorkspace.h:
--------------------------------------------------------------------------------
1 | //
2 | // LWorkspace.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 10/06/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XLWorkspace : NSObject
12 |
13 | // Get all projects contains in a workspace
14 | //
15 | // Dictionnary :
16 | // name: projectName
17 | // filename: filename.extension
18 | // location : path to the project
19 | //
20 | @property (strong, nonatomic) NSMutableArray *projects;
21 | @property (strong, nonatomic) NSString *currentWorkspacePath;
22 |
23 | -(id)initWithUrl:(NSString*)url currentPath:(NSString*)path;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/XLocation/NSObject_Extension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject_Extension.m
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/09/15.
6 | // Copyright (c) 2015 Stefan Lage. All rights reserved.
7 | //
8 |
9 |
10 | #import "NSObject_Extension.h"
11 | #import "XLocation.h"
12 |
13 | @implementation NSObject (Xcode_Plugin_Template_Extension)
14 |
15 | + (void)pluginDidLoad:(NSBundle *)plugin
16 | {
17 | static dispatch_once_t onceToken;
18 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
19 | if ([currentApplicationName isEqual:@"Xcode"]) {
20 | dispatch_once(&onceToken, ^{
21 | sharedPlugin = [[XLocation alloc] initWithBundle:plugin];
22 | });
23 | }
24 | }
25 | @end
26 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XcodeEditor.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import "XCAbstractDefinition.h"
14 | #import "XCGroup.h"
15 | #import "XCClassDefinition.h"
16 | #import "XCFileOperationQueue.h"
17 | #import "XCFrameworkDefinition.h"
18 | #import "XCProject.h"
19 | #import "XCSourceFile.h"
20 | #import "XCSourceFileDefinition.h"
21 | #import "XCSubProjectDefinition.h"
22 | #import "XCTarget.h"
23 | #import "XCXibDefinition.h"
24 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XcodeGroupMember.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XcodeMemberType.h"
15 |
16 | @protocol XcodeGroupMember
17 |
18 | - (NSString*)key;
19 |
20 | - (NSString*)displayName;
21 |
22 | - (NSString*)pathRelativeToProjectRoot;
23 |
24 | /**
25 | * Group members can either be other groups (PBXGroup) or source files (PBXFileReference).
26 | */
27 | - (XcodeMemberType)groupMemberType;
28 | @end
--------------------------------------------------------------------------------
/XLocation/Classes/XLAnnotation.h:
--------------------------------------------------------------------------------
1 | //
2 | // LAnnotation.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/05/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface XLAnnotation : NSObject
13 |
14 | @property (nonatomic, strong) NSString * city;
15 | @property (nonatomic, strong) NSString * country;
16 | @property (nonatomic, strong) NSString * address;
17 | @property (nonatomic, strong) NSString * zipCode;
18 | @property (nonatomic, strong) MKPointAnnotation * annotation;
19 |
20 | // Custom constructor
21 | -(id)initWithCity:(NSString*)ci country:(NSString*)co address:(NSString*)ad zipCode:(NSString*)zip location:(CLLocationCoordinate2D)loc;
22 | -(NSString*)concatAddress;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/XLocation/XLWorkspaceView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LWorskpaceController.h
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 10/06/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "XLWorkspace.h"
11 | #import "RMBlurredView.h"
12 |
13 |
14 | @class XLWorkspaceView;
15 |
16 | @protocol XLWorskpaceViewDelegate
17 |
18 | -(void)goBack:(XLWorkspaceView *)view;
19 | -(void)projectSelected:(XLWorkspaceView *)view index:(NSInteger)index;
20 |
21 | @end
22 |
23 | @interface XLWorkspaceView : RMBlurredView
24 |
25 | @property (nonatomic, weak) id delegate;
26 | @property (nonatomic, strong) XLWorkspace *currentWorkspace;
27 | @property (nonatomic, strong) NSButton *continueBtn;
28 |
29 | - (id)initWithFrame:(NSRect)frame workspace:(XLWorkspace*)workspace;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCAbstractDefinition.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import "XCAbstractDefinition.h"
14 |
15 |
16 | @implementation XCAbstractDefinition
17 |
18 | @synthesize fileOperationType = _fileOperationType;
19 |
20 |
21 | /* ====================================================================================================================================== */
22 | #pragma mark - Initialization & Destruction
23 |
24 | - (id)init
25 | {
26 | self = [super init];
27 | if (self)
28 | {
29 | _fileOperationType = XCFileOperationTypeOverwrite;
30 | }
31 | return self;
32 | }
33 |
34 |
35 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/Utils/XCKeyBuilder.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import
14 | #import
15 |
16 | #define HASH_VALUE_STORAGE_SIZE 48
17 |
18 | typedef struct
19 | {
20 | char value[CC_MD5_DIGEST_LENGTH];
21 | } HashValueMD5Hash;
22 |
23 |
24 | @interface XCKeyBuilder : NSObject
25 | {
26 | unsigned char _value[HASH_VALUE_STORAGE_SIZE];
27 | }
28 |
29 | + (XCKeyBuilder*)forItemNamed:(NSString*)name;
30 |
31 | + (XCKeyBuilder*)createUnique;
32 |
33 | - (id)initHashValueMD5HashWithBytes:(const void*)bytes length:(NSUInteger)length;
34 |
35 | - (NSString*)build;
36 |
37 | @end
38 |
39 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCFrameworkDefinition.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import
15 | #import "XCAbstractDefinition.h"
16 |
17 |
18 | @interface XCFrameworkDefinition : XCAbstractDefinition
19 | {
20 | NSString* _filePath;
21 | BOOL _copyToDestination;
22 | }
23 |
24 | @property(nonatomic, strong, readonly) NSString* filePath;
25 | @property(nonatomic, readonly) BOOL copyToDestination;
26 |
27 | + (XCFrameworkDefinition*)frameworkDefinitionWithFilePath:(NSString*)filePath copyToDestination:(BOOL)copyToDestination;
28 |
29 | - (id)initWithFilePath:(NSString*)filePath copyToDestination:(BOOL)copyToDestination;
30 |
31 | - (NSString*)name;
32 |
33 |
34 | @end
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Stefan Lage
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 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCXibDefinition.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import
15 | #import "XCAbstractDefinition.h"
16 |
17 |
18 | @interface XCXibDefinition : XCAbstractDefinition
19 | {
20 | NSString* _name;
21 | NSString* _content;
22 | }
23 | @property(nonatomic, strong, readonly) NSString* name;
24 | @property(nonatomic, strong) NSString* content;
25 |
26 | + (XCXibDefinition*)xibDefinitionWithName:(NSString*)name;
27 |
28 | + (XCXibDefinition*)xibDefinitionWithName:(NSString*)name content:(NSString*)content;
29 |
30 | - (id)initWithName:(NSString*)name;
31 |
32 | - (id)initWithName:(NSString*)name content:(NSString*)content;
33 |
34 | - (NSString*)xibFileName;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XcodeMemberType.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | typedef enum
15 | {
16 | PBXNilType,
17 | PBXBuildFileType,
18 | PBXContainerItemProxyType,
19 | PBXCopyFilesBuildPhaseType,
20 | PBXFileReferenceType,
21 | PBXFrameworksBuildPhaseType,
22 | PBXGroupType,
23 | PBXNativeTargetType,
24 | PBXProjectType,
25 | PBXReferenceProxyType,
26 | PBXResourcesBuildPhaseType,
27 | PBXSourcesBuildPhaseType,
28 | PBXTargetDependencyType,
29 | PBXVariantGroupType,
30 | XCBuildConfigurationType,
31 | XCConfigurationListType
32 | } XcodeMemberType;
33 |
34 | @interface NSString (XcodeMemberTypeExtensions)
35 |
36 | + (NSString*)stringFromMemberType:(XcodeMemberType)nodeType;
37 |
38 | - (XcodeMemberType)asMemberType;
39 |
40 | @end
41 |
42 |
43 |
--------------------------------------------------------------------------------
/XLocation/Views/RMBlurredView.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMBlurredView.h
3 | //
4 | // Created by Raffael Hannemann on 08.10.13.
5 | // Copyright (c) 2013 Raffael Hannemann. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | // Make sure to import QuartzCore and add it to your Linked Libraries of your target
11 | #import
12 |
13 | @interface RMBlurredView : NSView {
14 | // Keep a reference to the filters for later modification
15 | CIFilter *_blurFilter, *_saturationFilter;
16 | CALayer *_hostedLayer;
17 | }
18 |
19 | /** The layer will be tinted using the tint color. By default it is a 70% White Color */
20 | @property (strong,nonatomic) NSColor *tintColor;
21 |
22 | /** To get more vibrant colors, a filter to increase the saturation of the colors can be applied. The default value is 2.5. */
23 | @property (assign,nonatomic) float saturationFactor;
24 |
25 | /** The blur radius defines the strength of the Gaussian Blur filter. The default value is 20.0. */
26 | @property (assign,nonatomic) float blurRadius;
27 |
28 | /** Use the following property names in the User Defined Runtime Attributes in Interface Builder to set up your RMBlurredView on the fly. Note: The color can be set up, too, using 'tintColor'. */
29 | @property (strong,nonatomic) NSNumber *saturationFactorNumber;
30 | @property (strong,nonatomic) NSNumber *blurRadiusNumber;
31 |
32 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCSourceFileDefinition.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import
15 | #import "XCAbstractDefinition.h"
16 | #import "XcodeSourceFileType.h"
17 |
18 | @interface XCSourceFileDefinition : XCAbstractDefinition
19 | {
20 |
21 | NSString* _sourceFileName;
22 | XcodeSourceFileType _type;
23 | NSData* _data;
24 |
25 | }
26 |
27 | @property(nonatomic, strong, readonly) NSString* sourceFileName;
28 | @property(nonatomic, strong, readonly) NSData* data;
29 | @property(nonatomic, readonly) XcodeSourceFileType type;
30 |
31 | + (XCSourceFileDefinition*)sourceDefinitionWithName:(NSString*)name text:(NSString*)text type:(XcodeSourceFileType)type;
32 |
33 | + (XCSourceFileDefinition*)sourceDefinitionWithName:(NSString*)name data:(NSData*)data type:(XcodeSourceFileType)type;
34 |
35 | - (id)initWithName:(NSString*)name text:(NSString*)text type:(XcodeSourceFileType)type;
36 |
37 | - (id)initWithName:(NSString*)name data:(NSData*)data type:(XcodeSourceFileType)type;
38 |
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCBuildConfiguration.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | @class XCProject;
15 |
16 | @interface XCBuildConfiguration : NSObject
17 | {
18 | @private
19 | __weak XCProject* _project;
20 | NSString* _key;
21 |
22 | NSMutableDictionary* _buildSettings;
23 | NSMutableDictionary* _xcconfigSettings;
24 | }
25 |
26 | @property(nonatomic, readonly) NSDictionary* specifiedBuildSettings;
27 |
28 | + (NSDictionary*)buildConfigurationsFromArray:(NSArray*)array inProject:(XCProject*)project;
29 |
30 | - (instancetype)initWithProject:(XCProject*)project key:(NSString*)key;
31 |
32 | - (void)addBuildSettings:(NSDictionary*)buildSettings;
33 |
34 | - (void)addOrReplaceSetting:(id )setting forKey:(NSString*)key;
35 |
36 | - (id )valueForKey:(NSString*)key;
37 |
38 | + (NSString*)duplicatedBuildConfigurationListWithKey:(NSString*)buildConfigurationListKey inProject:(XCProject*)project
39 | withBuildConfigurationVisitor:(void (^)(NSMutableDictionary*))buildConfigurationVisitor;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XcodeSourceFileType.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | typedef enum
15 | {
16 | FileTypeNil, // Unknown filetype
17 | Framework, // .framework
18 | PropertyList, // .plist
19 | SourceCodeHeader, // .h
20 | SourceCodeObjC, // .m
21 | SourceCodeObjCPlusPlus, // .mm
22 | SourceCodeCPlusPlus, // .cpp
23 | XibFile, // .xib
24 | ImageResourcePNG, // .png
25 | Bundle, // .bundle .octet
26 | Archive, // .a files
27 | HTML, // HTML file
28 | TEXT, // Some text file
29 | GPX, // GPX file
30 | XcodeProject // .xcodeproj
31 | } XcodeSourceFileType;
32 |
33 | NSString* NSStringFromXCSourceFileType(XcodeSourceFileType type);
34 |
35 | XcodeSourceFileType XCSourceFileTypeFromStringRepresentation(NSString* string);
36 |
37 | XcodeSourceFileType XCSourceFileTypeFromFileName(NSString* fileName);
38 |
39 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCFileOperationQueue.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import
14 |
15 |
16 | @interface XCFileOperationQueue : NSObject
17 | {
18 |
19 | @private
20 | NSString* _baseDirectory;
21 | NSMutableDictionary* _filesToWrite;
22 | NSMutableDictionary* _frameworksToCopy;
23 | NSMutableArray* _filesToDelete;
24 | NSMutableArray* _directoriesToCreate;
25 | }
26 |
27 |
28 | - (id)initWithBaseDirectory:(NSString*)baseDirectory;
29 |
30 | - (BOOL)fileWithName:(NSString*)name existsInProjectDirectory:(NSString*)directory;
31 |
32 | - (void)queueTextFile:(NSString*)fileName inDirectory:(NSString*)directory withContents:(NSString*)contents;
33 |
34 | - (void)queueDataFile:(NSString*)fileName inDirectory:(NSString*)directory withContents:(NSData*)contents;
35 |
36 | - (void)queueFrameworkWithFilePath:(NSString*)filePath inDirectory:(NSString*)directory;
37 |
38 | - (void)queueDeletion:(NSString*)filePath;
39 |
40 | - (void)queueDirectory:(NSString*)withName inDirectory:(NSString*)parentDirectory;
41 |
42 | - (void)commitFileOperations;
43 |
44 | @end
45 |
46 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCProject+SubProject.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import
15 | #import "XCProject.h"
16 |
17 | @interface XCProject (SubProject)
18 |
19 |
20 | - (NSString*)referenceProxyKeyForName:(NSString*)name;
21 |
22 | - (NSArray*)buildProductsForTargets:(NSString*)xcodeprojKey;
23 |
24 | - (void)addAsTargetDependency:(XCSubProjectDefinition*)xcodeprojDefinition toTargets:(NSArray*)targets;
25 |
26 | - (NSArray*)keysForProjectObjectsOfType:(XcodeMemberType)memberType withIdentifier:(NSString*)identifier singleton:(BOOL)singleton
27 | required:(BOOL)required;
28 |
29 | - (NSMutableDictionary*)PBXProjectDict;
30 |
31 | - (void)removeProxies:(NSString*)xcodeprojKey;
32 |
33 | - (void)addProxies:(XCSubProjectDefinition*)xcodeproj;
34 |
35 | - (void)removeFromProjectReferences:(NSString*)key forProductsGroup:(NSString*)productsGroupKey;
36 |
37 | - (void)removeTargetDependencies:(NSString*)name;
38 |
39 | - (NSString*)containerItemProxyKeyForName:(NSString*)name proxyType:(NSString*)proxyType;
40 |
41 | - (NSString*)productsGroupKeyForKey:(NSString*)key;
42 |
43 | @end
--------------------------------------------------------------------------------
/XLocation/XLMapView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LMapView.m
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/05/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import "XLMapView.h"
10 |
11 | @interface XLMapView ()
12 |
13 | @property (nonatomic) MKCoordinateRegion bkRegion;
14 |
15 | @end
16 |
17 | @implementation XLMapView
18 |
19 | -(id)initWithCoder:(NSCoder *)aDecoder{
20 | self = [super initWithCoder:aDecoder];
21 | if(self){
22 | _bkRegion = self.region;
23 | _isEnable = YES;
24 | }
25 | return self;
26 | }
27 |
28 | /*
29 | * Handle right click on the map
30 | */
31 | - (void) rightMouseDown:(NSEvent*) event{
32 | // Get point in the current main Window
33 | NSPoint selfPoint = [self convertPoint:event.locationInWindow fromView:nil];
34 | // Adapt it to the mapView
35 | CLLocationCoordinate2D locCoord = [self convertPoint:selfPoint toCoordinateFromView:self];
36 | CLLocation *loc = [[CLLocation alloc] initWithLatitude:locCoord.latitude longitude:locCoord.longitude];
37 | // Broadcast the location to find
38 | [[NSNotificationCenter defaultCenter] postNotificationName:@"findLocationFromPointNotification"
39 | object:loc];
40 | }
41 |
42 | -(void)resetRegion{
43 | self.region = self.bkRegion;
44 | }
45 |
46 | -(NSView*)hitTest:(NSPoint)aPoint{
47 | if(self.isEnable)
48 | return [super hitTest:aPoint];
49 | else
50 | return nil;
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCAbstractDefinition.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import
14 |
15 | typedef enum
16 | {
17 |
18 | /**
19 | * Creates the reference in the project and writes the contents to disk. If a file already exists at the specified
20 | * location, its contents will be updated.
21 | */
22 | XCFileOperationTypeOverwrite,
23 |
24 | /**
25 | * Creates the reference in the project. If a file already exists at the specified location, the contents will not
26 | * be updated.
27 | */
28 | XCFileOperationTypeAcceptExisting,
29 |
30 | /**
31 | * Creates the reference in the project, but does not write to disk. The filesystem is expected to be updated
32 | * through some other means.
33 | */
34 | XCFileOperationTypeReferenceOnly
35 | } XCFileOperationType;
36 |
37 | /**
38 | * Holds properties to all types of resource that can be added to an Xcode project.
39 | */
40 | @interface XCAbstractDefinition : NSObject
41 | {
42 | XCFileOperationType _fileOperationType;
43 | }
44 |
45 | @property(nonatomic) XCFileOperationType fileOperationType;
46 |
47 |
48 | @end
--------------------------------------------------------------------------------
/XLocation/Classes/XLAnnotation.m:
--------------------------------------------------------------------------------
1 | //
2 | // LAnnotation.m
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 17/05/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import "XLAnnotation.h"
10 |
11 | @implementation XLAnnotation
12 |
13 | -(id)initWithCity:(NSString*)ci country:(NSString*)co address:(NSString*)ad zipCode:(NSString*)zip location:(CLLocationCoordinate2D)loc{
14 | self = [super init];
15 | if(self){
16 | _city = ci;
17 | _country = co;
18 | _address = ad;
19 | _zipCode = zip;
20 | _annotation = [[MKPointAnnotation alloc] init];
21 | _annotation.coordinate = loc;
22 | _annotation.title = [NSString stringWithFormat:@"%@\n%@", _city, _country];
23 | }
24 | return self;
25 | }
26 |
27 | /*
28 | * Concat all properties to get a complete address
29 | */
30 | -(NSString*)concatAddress{
31 | NSMutableString *result = [[NSMutableString alloc] init];
32 | if(![self.address isEqualToString:@""])
33 | [result appendString:[NSString stringWithFormat:@"%@, ", self.address]];
34 | if(![self.zipCode isEqualToString:@""])
35 | [result appendString:[NSString stringWithFormat:@"%@, ", self.zipCode]];
36 | if(![self.city isEqualToString:@""])
37 | [result appendString:[NSString stringWithFormat:@"%@, ", self.city]];
38 | if(![self.country isEqualToString:@""])
39 | [result appendString:[NSString stringWithFormat:@"%@", self.country]];
40 | return result;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCClassDefinition.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import
14 | #import "XCAbstractDefinition.h"
15 |
16 | typedef enum
17 | {
18 | ObjectiveC,
19 | ObjectiveCPlusPlus,
20 | CPlusPlus,
21 | } ClassDefinitionLanguage;
22 |
23 | @interface XCClassDefinition : XCAbstractDefinition
24 | {
25 |
26 | NSString* _className;
27 | NSString* _header;
28 | NSString* _source;
29 |
30 | @private
31 | ClassDefinitionLanguage _language;
32 | }
33 |
34 | @property(strong, nonatomic, readonly) NSString* className;
35 | @property(nonatomic, strong) NSString* header;
36 | @property(nonatomic, strong) NSString* source;
37 |
38 | + (XCClassDefinition*)classDefinitionWithName:(NSString*)fileName;
39 |
40 | + (XCClassDefinition*)classDefinitionWithName:(NSString*)className language:(ClassDefinitionLanguage)language;
41 |
42 | /**
43 | * Initializes a new objective-c class definition.
44 | */
45 | - (id)initWithName:(NSString*)fileName;
46 |
47 | /**
48 | * Initializes a new class definition with the specified language.
49 | */
50 | - (id)initWithName:(NSString*)className language:(ClassDefinitionLanguage)language;
51 |
52 | - (BOOL)isObjectiveC;
53 |
54 | - (BOOL)isObjectiveCPlusPlus;
55 |
56 | - (BOOL)isCPlusPlus;
57 |
58 | - (NSString*)headerFileName;
59 |
60 | - (NSString*)sourceFileName;
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCFrameworkDefinition.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCFrameworkDefinition.h"
15 |
16 | @implementation XCFrameworkDefinition
17 |
18 | @synthesize filePath = _filePath;
19 | @synthesize copyToDestination = _copyToDestination;
20 |
21 | /* ====================================================================================================================================== */
22 | #pragma mark - Class Methods
23 |
24 | + (XCFrameworkDefinition*)frameworkDefinitionWithFilePath:(NSString*)filePath copyToDestination:(BOOL)copyToDestination
25 | {
26 |
27 | return [[XCFrameworkDefinition alloc] initWithFilePath:filePath copyToDestination:copyToDestination];
28 | }
29 |
30 | /* ====================================================================================================================================== */
31 | #pragma mark - Initialization & Destruction
32 |
33 | - (id)initWithFilePath:(NSString*)filePath copyToDestination:(BOOL)copyToDestination
34 | {
35 | self = [super init];
36 | if (self)
37 | {
38 | _filePath = [filePath copy];
39 | _copyToDestination = copyToDestination;
40 | }
41 | return self;
42 | }
43 |
44 | /* ====================================================================================================================================== */
45 | #pragma mark - Interface Methods
46 |
47 | - (NSString*)name
48 | {
49 | return [_filePath lastPathComponent];
50 | }
51 |
52 |
53 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCSubProjectDefinition.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import
15 | #import "XCAbstractDefinition.h"
16 | #import "XcodeSourceFileType.h"
17 |
18 | @class XCProject;
19 |
20 |
21 | @interface XCSubProjectDefinition : XCAbstractDefinition
22 | {
23 |
24 | NSString* _name;
25 | NSString* _path;
26 | XcodeSourceFileType _type;
27 | XCProject* _subProject;
28 | XCProject* _parentProject;
29 | NSString* _key;
30 | NSString* _fullProjectPath;
31 | NSString* _relativePath;
32 | }
33 |
34 |
35 | @property(nonatomic, strong, readonly) NSString* name;
36 | @property(nonatomic, strong, readonly) NSString* path;
37 | @property(nonatomic, readonly) XcodeSourceFileType type;
38 | @property(nonatomic, strong, readonly) XCProject* subProject;
39 | @property(nonatomic, strong, readonly) XCProject* parentProject;
40 | @property(nonatomic, strong, readonly) NSString* key;
41 | @property(nonatomic, strong, readwrite) NSString* fullProjectPath;
42 |
43 | + (XCSubProjectDefinition*)withName:(NSString*)name path:(NSString*)path parentProject:(XCProject*)parentProject;
44 |
45 | - (id)initWithName:(NSString*)name path:(NSString*)path parentProject:(XCProject*)parentProject;
46 |
47 | - (NSString*)projectFileName;
48 |
49 | - (NSString*)fullPathName;
50 |
51 | - (NSArray*)buildProductNames;
52 |
53 | - (NSString*)projectKey;
54 |
55 | - (NSString*)pathRelativeToProjectRoot;
56 |
57 | - (NSString*)description;
58 |
59 | - (void)initFullProjectPath:(NSString*)fullProjectPath groupPath:(NSString*)groupPath;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCXibDefinition.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import "XCXibDefinition.h"
14 |
15 | @implementation XCXibDefinition
16 |
17 | @synthesize name = _name;
18 | @synthesize content = _content;
19 |
20 | /* ====================================================================================================================================== */
21 | #pragma mark - Class Methods
22 |
23 | + (XCXibDefinition*)xibDefinitionWithName:(NSString*)name
24 | {
25 | return [[XCXibDefinition alloc] initWithName:name];
26 | }
27 |
28 | + (XCXibDefinition*)xibDefinitionWithName:(NSString*)name content:(NSString*)content
29 | {
30 | return [[XCXibDefinition alloc] initWithName:name content:content];
31 | }
32 |
33 |
34 | /* ====================================================================================================================================== */
35 | #pragma mark - Initialization & Destruction
36 |
37 | - (id)initWithName:(NSString*)name
38 | {
39 | return [self initWithName:name content:nil];
40 | }
41 |
42 |
43 | - (id)initWithName:(NSString*)name content:(NSString*)content
44 | {
45 | self = [super init];
46 | if (self)
47 | {
48 | _name = [name copy];
49 | _content = [content copy];
50 | }
51 | return self;
52 | }
53 |
54 |
55 | /* ====================================================================================================================================== */
56 | #pragma mark - Interface Methods
57 |
58 | - (NSString*)xibFileName
59 | {
60 | return [_name stringByAppendingString:@".xib"];
61 | }
62 |
63 | @end
--------------------------------------------------------------------------------
/XLocation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | StefanLage.$(PRODUCT_NAME:rfc1034identifier)
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 | C4A681B0-4A26-480E-93EC-1218098B9AA0
28 | AD68E85B-441B-4301-B564-A45E4919A6AD
29 | A16FF353-8441-459E-A50C-B071F53F51B7
30 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7
31 | E969541F-E6F9-4D25-8158-72DC3545A6C6
32 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90
33 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13
34 | CC0D0F4F-05B3-431A-8F33-F84AFCB2C651
35 | 7265231C-39B4-402C-89E1-16167C4CC990
36 | 9AFF134A-08DC-4096-8CEE-62A4BB123046
37 | F41BD31E-2683-44B8-AE7F-5F09E919790E
38 | E71C2CFE-BFD8-4044-8F06-00AE685A406C
39 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C
40 |
41 | LSMinimumSystemVersion
42 | $(MACOSX_DEPLOYMENT_TARGET)
43 | NSPrincipalClass
44 | XLocation
45 | XC4Compatible
46 |
47 | XCPluginHasUI
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/XLocation/Categories/NSString+Gpx.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Gpx.m
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 16/05/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import "NSString+Gpx.h"
10 |
11 | @implementation NSString (Gpx)
12 |
13 | +(NSString *)generateGpxWithFilename:(NSString*) filename latitude:(NSNumber *)lat longitude:(NSNumber *)lng address:(NSString *)address city:(NSString *)city country:(NSString *)country zip:(NSString *)zipCode{
14 | return [NSString stringWithFormat:@"\n\
15 | \n\
24 | \n\
25 | \n\
26 | %@\n\
27 | \n\
28 | \n\
29 | \n\
30 | %@\n\
31 | %@\n\
32 | %@\n\
33 | %@\n\
34 | \n\
35 | \n\
36 | \n\
37 | \n\
38 | ", lat, lng, [NSDate new], filename, address, city, country, zipCode];
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCSourceFile.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import
15 | #import "XcodeGroupMember.h"
16 | #import "XcodeSourceFileType.h"
17 |
18 | @class XCProject;
19 |
20 | /**
21 | * Represents a file resource in an xcode project.
22 | */
23 | @interface XCSourceFile : NSObject
24 | {
25 |
26 | @private
27 | XCProject* _project;
28 |
29 | NSNumber* _isBuildFile;
30 | NSString* _buildFileKey;
31 | NSString* _name;
32 | NSString* _sourceTree;
33 | NSString* _key;
34 | NSString* _path;
35 | XcodeSourceFileType _type;
36 | }
37 |
38 | @property(nonatomic, readonly) XcodeSourceFileType type;
39 | @property(nonatomic, strong, readonly) NSString* key;
40 | @property(nonatomic, strong) NSString* name;
41 | @property(nonatomic, strong, readonly) NSString* sourceTree;
42 | @property(nonatomic, strong) NSString* path;
43 |
44 | + (XCSourceFile*)sourceFileWithProject:(XCProject*)project key:(NSString*)key type:(XcodeSourceFileType)type name:(NSString*)name
45 | sourceTree:(NSString*)tree path:(NSString*)path;
46 |
47 | - (id)initWithProject:(XCProject*)project key:(NSString*)key type:(XcodeSourceFileType)type name:(NSString*)name sourceTree:(NSString*)tree
48 | path:(NSString*)path;
49 |
50 | /**
51 | * If yes, indicates the file is able to be included for compilation in an `XCTarget`.
52 | */
53 | - (BOOL)isBuildFile;
54 |
55 | - (BOOL)canBecomeBuildFile;
56 |
57 | - (XcodeMemberType)buildPhase;
58 |
59 | - (NSString*)buildFileKey;
60 |
61 | /**
62 | * Adds this file to the project as an `xcode_BuildFile`, ready to be included in targets.
63 | */
64 | - (void)becomeBuildFile;
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/Utils/XCKeyBuilder.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 | #import "XCKeyBuilder.h"
13 |
14 | @implementation XCKeyBuilder
15 |
16 | /* ================================================= Class Methods ================================================== */
17 | + (XCKeyBuilder*)forItemNamed:(NSString*)name
18 | {
19 | NSData* data = [name dataUsingEncoding:NSUTF8StringEncoding];
20 | return [[XCKeyBuilder alloc] initHashValueMD5HashWithBytes:[data bytes] length:[data length]];
21 |
22 | }
23 |
24 | + (XCKeyBuilder*)createUnique
25 | {
26 | CFUUIDRef theUUID = CFUUIDCreate(NULL);
27 | CFUUIDBytes bytes = CFUUIDGetUUIDBytes(theUUID);
28 | CFRelease(theUUID);
29 |
30 | return [[XCKeyBuilder alloc] initHashValueMD5HashWithBytes:&bytes length:sizeof(bytes)];
31 | }
32 |
33 | /* ================================================== Initializers ================================================== */
34 | - (id)initHashValueMD5HashWithBytes:(const void*)bytes length:(NSUInteger)length
35 | {
36 | self = [super init];
37 | if (self != nil)
38 | {
39 | CC_MD5(bytes, (int) length, _value);
40 | }
41 | return self;
42 | }
43 |
44 | /* ================================================ Interface Methods =============================================== */
45 | - (NSString*)build
46 | {
47 | NSInteger byteLength = sizeof(HashValueMD5Hash);
48 | NSMutableString* stringValue = [NSMutableString stringWithCapacity:byteLength * 2];
49 | NSInteger i;
50 | for (i = 0; i < byteLength; i++)
51 | {
52 | [stringValue appendFormat:@"%02x", _value[i]];
53 | }
54 | return [[stringValue substringToIndex:24] uppercaseString];
55 | }
56 |
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCSourceFileDefinition.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCSourceFileDefinition.h"
15 |
16 | @implementation XCSourceFileDefinition
17 |
18 | @synthesize sourceFileName = _sourceFileName;
19 | @synthesize type = _type;
20 | @synthesize data = _data;
21 |
22 | /* ====================================================================================================================================== */
23 | #pragma mark - Class Methods
24 |
25 | + (XCSourceFileDefinition*)sourceDefinitionWithName:(NSString*)name text:(NSString*)text type:(XcodeSourceFileType)type
26 | {
27 |
28 | return [[XCSourceFileDefinition alloc] initWithName:name text:text type:type];
29 | }
30 |
31 | + (XCSourceFileDefinition*)sourceDefinitionWithName:(NSString*)name data:(NSData*)data type:(XcodeSourceFileType)type
32 | {
33 |
34 | return [[XCSourceFileDefinition alloc] initWithName:name data:data type:type];
35 | }
36 |
37 |
38 | /* ====================================================================================================================================== */
39 | #pragma mark - Initialization & Destruction
40 |
41 | - (id)initWithName:(NSString*)name text:(NSString*)text type:(XcodeSourceFileType)type
42 | {
43 | self = [super init];
44 | if (self)
45 | {
46 | _sourceFileName = [name copy];
47 | _data = [[text dataUsingEncoding:NSUTF8StringEncoding] copy];
48 | _type = type;
49 | }
50 | return self;
51 | }
52 |
53 | - (id)initWithName:(NSString*)name data:(NSData*)data type:(XcodeSourceFileType)type
54 | {
55 | self = [super init];
56 | if (self)
57 | {
58 | _sourceFileName = [name copy];
59 | _data = [data copy];
60 | _type = type;
61 | }
62 | return self;
63 |
64 | }
65 |
66 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCTarget.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import
14 |
15 | @class XCProject;
16 | @class XCSourceFile;
17 | @class XCBuildConfiguration;
18 |
19 | /**
20 | * Represents a target in an xcode project.
21 | */
22 | @interface XCTarget : NSObject
23 | {
24 |
25 | XCProject* _project;
26 | NSString* _key;
27 | NSString* _name;
28 | NSString* _productName;
29 | NSString* _productReference;
30 | NSString* _defaultConfigurationName;
31 |
32 | @private
33 | NSMutableArray* _members;
34 | NSMutableArray* _resources;
35 | NSMutableDictionary* _configurations;
36 | }
37 |
38 | @property(nonatomic, strong, readonly) NSString* key;
39 | @property(nonatomic, strong) NSString* name;
40 | @property(nonatomic, strong) NSString* productName;
41 | @property(nonatomic, strong, readonly) NSString* productReference;
42 |
43 | + (XCTarget*)targetWithProject:(XCProject*)project key:(NSString*)key name:(NSString*)name productName:(NSString*)productName
44 | productReference:(NSString*)productReference;
45 |
46 | - (id)initWithProject:(XCProject*)project key:(NSString*)key name:(NSString*)name productName:(NSString*)productName
47 | productReference:(NSString*)productReference;
48 |
49 | - (NSArray*)resources;
50 |
51 | - (NSArray*)members;
52 |
53 | - (NSDictionary*)configurations;
54 |
55 | - (XCBuildConfiguration*)configurationWithName:(NSString*)name;
56 |
57 | - (XCBuildConfiguration*)defaultConfiguration;
58 |
59 | - (void)addMember:(XCSourceFile*)member;
60 |
61 | - (void)removeMemberWithKey:(NSString*)key;
62 |
63 | - (void)removeMembersWithKeys:(NSArray*)keys;
64 |
65 | - (void)addDependency:(NSString*)key;
66 |
67 | - (instancetype)duplicateWithTargetName:(NSString*)targetName productName:(NSString*)productName;
68 |
69 | @end
70 |
71 |
--------------------------------------------------------------------------------
/XLocation/Classes/XLWorkspace.m:
--------------------------------------------------------------------------------
1 | //
2 | // LWorkspace.m
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 10/06/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import "XLWorkspace.h"
10 |
11 | static NSString * const workspaceContent = @"contents.xcworkspacedata";
12 | static NSString * const fileRefElement = @"FileRef";
13 | static NSString * const locationKey = @"location";
14 | static NSString * const locationNoise = @"group:";
15 |
16 | @implementation XLWorkspace
17 |
18 | -(id)initWithUrl:(NSString*)url currentPath:(NSString*)path{
19 | self = [super init];
20 | if(self){
21 | _currentWorkspacePath = path;
22 | NSString *worskpacePath = [NSString stringWithFormat:@"%@/%@", url, workspaceContent];
23 | NSData *xmlData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:worskpacePath]];
24 | if(xmlData == nil)
25 | // Can't read the file -> return nil
26 | return nil;
27 | NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithData:xmlData];
28 | xmlParser.delegate = self;
29 | [xmlParser parse];
30 | }
31 | return self;
32 | }
33 |
34 | // Check if the path has the right format : /Users/....
35 | -(NSString*)checkPath:(NSString*)path{
36 | NSMutableString *newpath = [[NSMutableString alloc] initWithString:path];
37 | if([newpath characterAtIndex:0] != '/')
38 | [newpath insertString:self.currentWorkspacePath
39 | atIndex:0];
40 | return newpath;
41 | }
42 |
43 | #pragma mark - NSXMLParser
44 |
45 | - (void)parserDidStartDocument:(NSXMLParser *)parser
46 | {
47 | self.projects = [NSMutableArray new];
48 | }
49 |
50 | -(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
51 | // Project found ?
52 | if([elementName isEqualToString:fileRefElement])
53 | {
54 | NSString *location = [[attributeDict objectForKey:locationKey] stringByReplacingOccurrencesOfString:locationNoise
55 | withString:@""];
56 | // correct the path if needed
57 | location = [self checkPath:location];
58 | NSString* projectName = [[location lastPathComponent] stringByDeletingPathExtension];
59 | NSDictionary *dic = @{
60 | @"name": projectName,
61 | @"filename": [location lastPathComponent],
62 | @"location": location
63 | };
64 | // Add project infos
65 | [self.projects addObject:dic];
66 | }
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XcodeSourceFileType.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XcodeSourceFileType.h"
15 |
16 | NSDictionary* NSDictionaryWithXCFileReferenceTypes()
17 | {
18 | static NSDictionary* dictionary;
19 | static dispatch_once_t onceToken;
20 | dispatch_once(&onceToken, ^
21 | {
22 | dictionary = @{
23 | @"sourcecode.c.h" : @(SourceCodeHeader),
24 | @"sourcecode.c.objc" : @(SourceCodeObjC),
25 | @"wrapper.framework" : @(Framework),
26 | @"text.plist.strings" : @(PropertyList),
27 | @"sourcecode.cpp.objcpp" : @(SourceCodeObjCPlusPlus),
28 | @"sourcecode.cpp.cpp" : @(SourceCodeCPlusPlus),
29 | @"file.xib" : @(XibFile),
30 | @"image.png" : @(ImageResourcePNG),
31 | @"wrapper.cfbundle" : @(Bundle),
32 | @"archive.ar" : @(Archive),
33 | @"text.html" : @(HTML),
34 | @"text" : @(TEXT),
35 | @"gpx" : @(GPX),
36 | @"wrapper.pb-project" : @(XcodeProject)
37 | };
38 | });
39 |
40 | return dictionary;
41 | }
42 |
43 | NSString* NSStringFromXCSourceFileType(XcodeSourceFileType type)
44 | {
45 | return [[NSDictionaryWithXCFileReferenceTypes() allKeysForObject:@(type)] objectAtIndex:0];
46 | }
47 |
48 | XcodeSourceFileType XCSourceFileTypeFromStringRepresentation(NSString* string)
49 | {
50 | NSDictionary* typeStrings = NSDictionaryWithXCFileReferenceTypes();
51 |
52 | if ([typeStrings objectForKey:string])
53 | {
54 | return (XcodeSourceFileType) [[typeStrings objectForKey:string] intValue];
55 | }
56 | else
57 | {
58 | return FileTypeNil;
59 | }
60 | }
61 |
62 |
63 | XcodeSourceFileType XCSourceFileTypeFromFileName(NSString* fileName)
64 | {
65 | if ([fileName hasSuffix:@".h"] || [fileName hasSuffix:@".hh"] || [fileName hasSuffix:@".hpp"] || [fileName hasSuffix:@".hxx"])
66 | {
67 | return SourceCodeHeader;
68 | }
69 | if ([fileName hasSuffix:@".c"] || [fileName hasSuffix:@".m"])
70 | {
71 | return SourceCodeObjC;
72 | }
73 | if ([fileName hasSuffix:@".mm"])
74 | {
75 | return SourceCodeObjCPlusPlus;
76 | }
77 | if ([fileName hasSuffix:@".cpp"])
78 | {
79 | return SourceCodeCPlusPlus;
80 | }
81 | return FileTypeNil;
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XLocation
2 |
3 | **XLocation** is an open source **XCode** plugin.
4 |
5 | It lets you add a new location from an address known to your current xcode project. **NEW**, now it works in a **Workspace** too.
6 |
7 |
8 | 
9 |
10 | ##Features
11 |
12 | The process is very easy, you just need to enter an address (at least a city and its country), then the plug-in while get the coordinates corresponding to this address and generate the GPX file.
13 |
14 | ###Using a Map
15 |
16 | You get a location from the map view.
17 |
18 | Just need to do a `right click` on the map everywhere you want, then the plugin will get the corresponding address.
19 |
20 | 
21 |
22 | ###Using your `Own` address
23 |
24 | You can create a new GPX file informing the following fields:
25 |
26 | ```` objective-c
27 | @Required
28 | ````
29 |
30 | - City
31 | - Country
32 |
33 | ```` objective-c
34 | @Optional
35 | ````
36 |
37 | - Address (Default value: `Downtown`)
38 | - Zip Code
39 | - The filename
40 |
41 | 
42 |
43 | ##Workspace
44 |
45 | If you are using a workspace with severals projects, you will have to select in which project you would like to add the GPX file.
46 |
47 |
48 | 
49 |
50 | ##Install
51 |
52 | ###Via Alcatraz
53 |
54 | XLocation plugin is available through the [Alcatraz](http://alcatraz.io/).
55 |
56 | ###From Source
57 |
58 | Download the project and build it, then relaunch Xcode.
59 |
60 | A new item named `Add new Location` should appear in the menu item `Debug`.
61 |
62 | XLocation will be installed in `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins` automatically.
63 |
64 | If you want to uninstall XLocation, remove XLocation in Plug-ins directory.
65 |
66 | ##Dependency
67 |
68 | [`XcodeEditor`](https://github.com/jasperblues/XcodeEditor) to manipulate Xcode project files, made by [`AppsQuick.ly`](https://github.com/appsquickly).
69 |
70 |
71 | ##License
72 |
73 | Copyright (c) 2014 Stefan Lage
74 |
75 | Permission is hereby granted, free of charge, to any person obtaining
76 | a copy of this software and associated documentation files (the
77 | "Software"), to deal in the Software without restriction, including
78 | without limitation the rights to use, copy, modify, merge, publish,
79 | distribute, sublicense, and/or sell copies of the Software, and to
80 | permit persons to whom the Software is furnished to do so, subject to
81 | the following conditions:
82 |
83 | The above copyright notice and this permission notice shall be
84 | included in all copies or substantial portions of the Software.
85 |
86 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
89 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
90 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
91 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
92 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
93 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCClassDefinition.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 |
15 |
16 | #import "XCClassDefinition.h"
17 |
18 | @implementation XCClassDefinition
19 |
20 |
21 | @synthesize className = _className;
22 | @synthesize header = _header;
23 | @synthesize source = _source;
24 |
25 | /* ====================================================================================================================================== */
26 | #pragma mark - Class Methods
27 |
28 | + (XCClassDefinition*)classDefinitionWithName:(NSString*)fileName
29 | {
30 | return [[XCClassDefinition alloc] initWithName:fileName];
31 | }
32 |
33 | + (XCClassDefinition*)classDefinitionWithName:(NSString*)className language:(ClassDefinitionLanguage)language
34 | {
35 | return [[XCClassDefinition alloc] initWithName:className language:language];
36 | }
37 |
38 | /* ====================================================================================================================================== */
39 | #pragma mark - Initialization & Destruction
40 |
41 | - (id)initWithName:(NSString*)className
42 | {
43 | return [self initWithName:className language:ObjectiveC];
44 | }
45 |
46 | - (id)initWithName:(NSString*)className language:(ClassDefinitionLanguage)language
47 | {
48 | self = [super init];
49 | if (self)
50 | {
51 | _className = [className copy];
52 | if (!(language == ObjectiveC || language == ObjectiveCPlusPlus || language == CPlusPlus))
53 | {
54 | [NSException raise:NSInvalidArgumentException format:@"Language must be one of ObjectiveC, ObjectiveCPlusPlus"];
55 | }
56 | _language = language;
57 | }
58 | return self;
59 | }
60 |
61 |
62 | /* ====================================================================================================================================== */
63 | #pragma mark - Interface Methods
64 |
65 | - (BOOL)isObjectiveC
66 | {
67 | return _language == ObjectiveC;
68 | }
69 |
70 | - (BOOL)isObjectiveCPlusPlus
71 | {
72 | return _language == ObjectiveCPlusPlus;
73 | }
74 |
75 | - (BOOL)isCPlusPlus
76 | {
77 | return _language == CPlusPlus;
78 | }
79 |
80 | - (NSString*)headerFileName
81 | {
82 | return [_className stringByAppendingString:@".h"];
83 |
84 | }
85 |
86 | - (NSString*)sourceFileName
87 | {
88 | NSString* sourceFileName = nil;
89 | if ([self isObjectiveC])
90 | {
91 | sourceFileName = [_className stringByAppendingString:@".m"];
92 | }
93 | else if ([self isObjectiveCPlusPlus])
94 | {
95 | sourceFileName = [_className stringByAppendingString:@".mm"];
96 | }
97 | else if ([self isCPlusPlus])
98 | {
99 | sourceFileName = [_className stringByAppendingString:@".cpp"];
100 | }
101 | return sourceFileName;
102 | }
103 |
104 |
105 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XcodeMemberType.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 |
15 | #import "XcodeMemberType.h"
16 |
17 |
18 | @implementation NSDictionary (XcodeMemberType)
19 |
20 |
21 | + (NSDictionary*)dictionaryWithProjectNodeTypesAsStrings
22 | {
23 | // This is the most vital operation on adding 500+ files
24 | // So, we caching this dictionary
25 | static NSDictionary* _projectNodeTypesAsStrings;
26 | static dispatch_once_t onceToken;
27 | dispatch_once(&onceToken, ^
28 | {
29 | _projectNodeTypesAsStrings =
30 | [[NSDictionary alloc] initWithObjectsAndKeys:@(PBXNilType), @"PBXNilType",
31 | @(PBXBuildFileType), @"PBXBuildFile",
32 | @(PBXContainerItemProxyType), @"PBXContainerItemProxy",
33 | @(PBXCopyFilesBuildPhaseType), @"PBXCopyFilesBuildPhase",
34 | @(PBXFileReferenceType), @"PBXFileReference",
35 | @(PBXFrameworksBuildPhaseType), @"PBXFrameworksBuildPhase",
36 | @(PBXGroupType), @"PBXGroup",
37 | @(PBXNativeTargetType), @"PBXNativeTarget",
38 | @(PBXProjectType), @"PBXProject",
39 | @(PBXReferenceProxyType), @"PBXReferenceProxy",
40 | @(PBXResourcesBuildPhaseType), @"PBXResourcesBuildPhase",
41 | @(PBXSourcesBuildPhaseType), @"PBXSourcesBuildPhase",
42 | @(PBXTargetDependencyType), @"PBXTargetDependency",
43 | @(PBXVariantGroupType), @"PBXVariantGroup",
44 | @(XCBuildConfigurationType), @"XCBuildConfiguration",
45 | @(XCConfigurationListType), @"XCConfigurationList", nil];
46 | });
47 | return _projectNodeTypesAsStrings;
48 | }
49 |
50 | @end
51 |
52 | @implementation NSString (XcodeMemberTypeExtensions)
53 |
54 | + (NSString*)stringFromMemberType:(XcodeMemberType)nodeType
55 | {
56 | NSDictionary* nodeTypesToString = [NSDictionary dictionaryWithProjectNodeTypesAsStrings];
57 | return [[nodeTypesToString allKeysForObject:@(nodeType)] objectAtIndex:0];
58 | }
59 |
60 |
61 | - (XcodeMemberType)asMemberType
62 | {
63 | NSDictionary* nodeTypesToString = [NSDictionary dictionaryWithProjectNodeTypesAsStrings];
64 | return (XcodeMemberType) [[nodeTypesToString objectForKey:self] intValue];
65 | }
66 |
67 |
68 | @end
--------------------------------------------------------------------------------
/XLocation.xcodeproj/xcshareddata/xcschemes/XLocation.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
58 |
60 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/XLocation/Views/RMBlurredView.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMBlurredView.m
3 | //
4 | // Created by Raffael Hannemann on 08.10.13.
5 | // Copyright (c) 2013 Raffael Hannemann. All rights reserved.
6 | //
7 |
8 | #import "RMBlurredView.h"
9 |
10 | #define kRMBlurredViewDefaultTintColor [NSColor colorWithCalibratedWhite:1.0 alpha:0.7]
11 | #define kRMBlurredViewDefaultSaturationFactor 2.0
12 | #define kRMBlurredViewDefaultBlurRadius 20.0
13 |
14 | @implementation RMBlurredView
15 |
16 | - (id)initWithFrame:(NSRect)frame
17 | {
18 | self = [super initWithFrame:frame];
19 | if (self) {
20 | [self setUp];
21 | }
22 | return self;
23 | }
24 |
25 | - (id)initWithCoder:(NSCoder *)coder
26 | {
27 | self = [super initWithCoder:coder];
28 | if (self) {
29 | [self setUp];
30 | }
31 | return self;
32 | }
33 |
34 | - (void) setTintColor:(NSColor *)tintColor {
35 | _tintColor = tintColor;
36 |
37 | // Since we need a CGColor reference, store it for the drawing of the layer.
38 | if (_tintColor) {
39 | [self.layer setBackgroundColor:_tintColor.CGColor];
40 | }
41 |
42 | // Trigger a re-drawing of the layer
43 | [self.layer setNeedsDisplay];
44 | }
45 |
46 | - (void) setBlurRadius:(float)blurRadius {
47 | // Setting the blur radius requires a resetting of the filters
48 | _blurRadius = blurRadius;
49 | [self resetFilters];
50 | }
51 |
52 | - (void) setBlurRadiusNumber:(NSNumber *)blurRadiusNumber {
53 | [self setBlurRadius:blurRadiusNumber.floatValue];
54 | }
55 |
56 | - (void) setSaturationFactor:(float)saturationFactor {
57 | // Setting the saturation factor also requires a resetting of the filters
58 | _saturationFactor = saturationFactor;
59 | [self resetFilters];
60 | }
61 |
62 | - (void) setSaturationFactorNumber:(NSNumber *)saturationFactorNumber {
63 | [self setSaturationFactor:saturationFactorNumber.floatValue];
64 | }
65 |
66 | - (void) setUp {
67 | // Instantiate a new CALayer and set it as the NSView's layer (layer-hosting)
68 | _hostedLayer = [CALayer layer];
69 | [self setWantsLayer:YES];
70 | [self setLayer:_hostedLayer];
71 |
72 | // Set up the default parameters
73 | _blurRadius = kRMBlurredViewDefaultBlurRadius;
74 | _saturationFactor = kRMBlurredViewDefaultSaturationFactor;
75 | [self setTintColor:kRMBlurredViewDefaultTintColor];
76 |
77 | // It's important to set the layer to mask to its bounds, otherwise the whole parent view might get blurred
78 | [self.layer setMasksToBounds:YES];
79 |
80 | // To apply CIFilters on OS X 10.9, we need to set the property accordingly:
81 | if ([self respondsToSelector:@selector(setLayerUsesCoreImageFilters:)]) {
82 | BOOL flag = YES;
83 | NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(setLayerUsesCoreImageFilters:)]];
84 | [inv setSelector:@selector(setLayerUsesCoreImageFilters:)];
85 | [inv setArgument:&flag atIndex:2];
86 | [inv invokeWithTarget:self];
87 | }
88 |
89 | // Set the layer to redraw itself once it's size is changed
90 | [self.layer setNeedsDisplayOnBoundsChange:YES];
91 |
92 | // Initially create the filter instances
93 | [self resetFilters];
94 | }
95 |
96 | - (void) resetFilters {
97 | // To get a higher color saturation, we create a ColorControls filter
98 | _saturationFilter = [CIFilter filterWithName:@"CIColorControls"];
99 | [_saturationFilter setDefaults];
100 | [_saturationFilter setValue:[NSNumber numberWithFloat:_saturationFactor] forKey:@"inputSaturation"];
101 |
102 | // Next, we create the blur filter
103 | _blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
104 | [_blurFilter setDefaults];
105 | [_blurFilter setValue:[NSNumber numberWithFloat:_blurRadius] forKey:@"inputRadius"];
106 |
107 | // Now we apply the two filters as the layer's background filters
108 | [self.layer setBackgroundFilters:@[_saturationFilter, _blurFilter]];
109 |
110 | // ... and trigger a refresh
111 | [self.layer setNeedsDisplay];
112 | }
113 |
114 | @end
--------------------------------------------------------------------------------
/XLocation/XLWorkspaceView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LWorskpaceController.m
3 | // XLocation
4 | //
5 | // Created by Stefan Lage on 10/06/14.
6 | // Copyright (c) 2014 StefanLage. All rights reserved.
7 | //
8 |
9 | #import "XLWorkspaceView.h"
10 |
11 | static NSString * const defaultMessage = @"It seems you're using a Workspace.\nPlease select in which project you'd like to add the GPX:";
12 | static NSString * const goBackTitle = @"Go Back";
13 | static NSString * const continueTitle = @"Continue";
14 |
15 | @interface XLWorkspaceView ()
16 |
17 | @property (nonatomic, strong) NSButton *back;
18 | @property (nonatomic, strong) NSMatrix *projectsMatrix;
19 |
20 | @end
21 |
22 | @implementation XLWorkspaceView
23 |
24 | - (id)initWithFrame:(NSRect)frame workspace:(XLWorkspace*)workspace
25 | {
26 | self = [super initWithFrame:frame];
27 | if(self){
28 | _currentWorkspace = workspace;
29 | // Get the mid point of this view
30 | float x = frame.size.width / 2;
31 | float y = frame.size.height / 2;
32 | NSPoint midPoint = NSMakePoint(x, y);
33 |
34 | NSTextField *txtField = [[NSTextField alloc] initWithFrame:NSMakeRect((x - 340/2), y + 60, 340, 60)];
35 | [txtField setStringValue:defaultMessage];
36 | [txtField setEditable:NO];
37 | [txtField setBordered:NO];
38 | [txtField setBackgroundColor:[NSColor clearColor]];
39 | [self addSubview:txtField];
40 |
41 | [self setButtons:midPoint];
42 | [self setMatrix:midPoint];
43 | }
44 | return self;
45 | }
46 |
47 | -(void)setButtons:(NSPoint)midPoint{
48 |
49 | float x = midPoint.x - 115;
50 | float y = midPoint.y - 125.0;
51 | _back = [[NSButton alloc] initWithFrame:NSMakeRect(x, y, 115, 32)];
52 | [_back setTitle:goBackTitle];
53 | [_back setTarget:self];
54 | [_back setAction:@selector(back:)];
55 | [_back setButtonType:NSMomentaryLightButton];
56 | [_back setBezelStyle:NSRoundedBezelStyle];
57 | // Set escpace key as shortcut
58 | [_back setKeyEquivalent:@"\033"];
59 |
60 | _continueBtn = [[NSButton alloc] initWithFrame:NSMakeRect(x+125, y, 115, 32)];
61 | [_continueBtn setTitle:continueTitle];
62 | [_continueBtn setTarget:self];
63 | [_continueBtn setAction:@selector(projectSelected:)];
64 | [_continueBtn setButtonType:NSMomentaryLightButton];
65 | [_continueBtn setBezelStyle:NSRoundedBezelStyle];
66 | // Set enter/return key as shortcut
67 | [_continueBtn setKeyEquivalent:@"\r"];
68 |
69 | [self addSubview:_back];
70 | [self addSubview:_continueBtn];
71 | }
72 |
73 | // Create a matrix containing all projects name
74 | -(void) setMatrix:(NSPoint)midPoint{
75 | // Create a long title sample to be sure it could be contain a long name
76 | NSMutableString *title = [[NSMutableString alloc] initWithString:@" "];
77 | for (int i = 0; i < 200; i++)
78 | [title appendString:@" "];
79 | // Set a prototype of radio button
80 | NSButtonCell *prototype = [[NSButtonCell alloc] init];
81 | [prototype setTitle:title];
82 | [prototype setButtonType:NSRadioButton];
83 |
84 | float x = midPoint.x - 125.0/2;
85 | float y = midPoint.y - 125.0/2;
86 | NSRect matrixRect = NSMakeRect(x, y, 200.0, 125.0);
87 | NSInteger rows = self.currentWorkspace.projects.count;
88 | self.projectsMatrix = [[NSMatrix alloc] initWithFrame:matrixRect
89 | mode:NSRadioModeMatrix
90 | prototype:(NSCell *)prototype
91 | numberOfRows:rows
92 | numberOfColumns:1];
93 |
94 | [self addSubview:self.projectsMatrix];
95 | NSArray *cellArray = [self.projectsMatrix cells];
96 | for(int i = 0; i < rows ; i++){
97 | NSDictionary *project = [self.currentWorkspace.projects objectAtIndex:i];
98 | [[cellArray objectAtIndex:i] setTitle:[project objectForKey:@"name"]];
99 | }
100 | }
101 |
102 | #pragma mark - Handlers
103 |
104 | -(void)back:(id)sender{
105 | if([self.delegate respondsToSelector:@selector(goBack:)])
106 | [self.delegate goBack:self];
107 | }
108 |
109 | -(void)projectSelected:(id)sender{
110 | if([self.delegate respondsToSelector:@selector(projectSelected:index:)])
111 | [self.delegate projectSelected:self index:[self.projectsMatrix selectedRow]];
112 | }
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCProject.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 | #import
13 | #import "XcodeMemberType.h"
14 | #import "XcodeSourceFileType.h"
15 |
16 | @class XCClassDefinition;
17 | @class XCGroup;
18 | @class XCFileOperationQueue;
19 | @class XCSourceFile;
20 | @class XCTarget;
21 | @class XCSubProjectDefinition;
22 | @class XCBuildConfiguration;
23 |
24 | static NSString* const XCProjectNotFoundException;
25 |
26 | @interface XCProject : NSObject
27 | {
28 | @protected
29 | XCFileOperationQueue* _fileOperationQueue;
30 |
31 | NSString* _filePath;
32 | NSMutableDictionary* _dataStore;
33 | NSMutableArray* _targets;
34 |
35 | NSMutableDictionary* _groups;
36 | NSMutableDictionary* _configurations;
37 |
38 | NSString* _defaultConfigurationName;
39 | NSString* _rootObjectKey;
40 | }
41 |
42 | @property(nonatomic, strong, readonly) XCFileOperationQueue* fileOperationQueue;
43 |
44 | /* ============================================================ Initializers ============================================================ */
45 |
46 | + (XCProject*)projectWithFilePath:(NSString*)filePath;
47 |
48 | /**
49 | * Creates a new project editor instance with the specified Project.xcodeproj file.
50 | */
51 | - (id)initWithFilePath:(NSString*)filePath;
52 |
53 | /* ====================================================================================================================================== */
54 |
55 | #pragma mark Files
56 | /**
57 | * Returns all file resources in the project, as an array of `XCSourceFile` objects.
58 | */
59 | - (NSArray*)files;
60 |
61 | /**
62 | * Returns the project file with the specified key, or nil.
63 | */
64 | - (XCSourceFile*)fileWithKey:(NSString*)key;
65 |
66 | /**
67 | * Returns the project file with the specified name, or nil. If more than one project file matches the specified name,
68 | * which one is returned is undefined.
69 | */
70 | - (XCSourceFile*)fileWithName:(NSString*)name;
71 |
72 | /**
73 | * Returns all header files in the project, as an array of `XCSourceFile` objects.
74 | */
75 | - (NSArray*)headerFiles;
76 |
77 | /**
78 | * Returns all implementation obj-c implementation files in the project, as an array of `XCSourceFile` objects.
79 | */
80 | - (NSArray*)objectiveCFiles;
81 |
82 | /**
83 | * Returns all implementation obj-c++ implementation files in the project, as an array of `XCSourceFile` objects.
84 | */
85 | - (NSArray*)objectiveCPlusPlusFiles;
86 |
87 | /**
88 | * Returns all the xib files in the project, as an array of `XCSourceFile` objects.
89 | */
90 | - (NSArray*)xibFiles;
91 |
92 | - (NSArray*)imagePNGFiles;
93 |
94 | - (NSString*)filePath;
95 |
96 |
97 | /* ====================================================================================================================================== */
98 | #pragma mark Groups
99 | /**
100 | * Lists the groups in an xcode project, returning an array of `XCGroup` objects.
101 | */
102 | - (NSArray*)groups;
103 |
104 | /**
105 | * Returns the root (top-level) group.
106 | */
107 | - (XCGroup*)rootGroup;
108 |
109 | /**
110 | * Returns the root (top-level) groups, if there are multiple. An array of rootGroup if there is only one.
111 | */
112 | - (NSArray*)rootGroups;
113 |
114 | /**
115 | * Returns the group with the given key, or nil.
116 | */
117 | - (XCGroup*)groupWithKey:(NSString*)key;
118 |
119 | /**
120 | * Returns the group with the specified display name path - the directory relative to the root group. Eg Source/Main
121 | */
122 | - (XCGroup*)groupWithPathFromRoot:(NSString*)path;
123 |
124 | /**
125 | * Returns the parent group for the group or file with the given key;
126 | */
127 | - (XCGroup*)groupForGroupMemberWithKey:(NSString*)key;
128 |
129 | /**
130 | * Returns the parent group for the group or file with the source file
131 | */
132 | - (XCGroup*)groupWithSourceFile:(XCSourceFile*)sourceFile;
133 |
134 | /* ====================================================================================================================================== */
135 | #pragma mark Targets
136 | /**
137 | * Lists the targets in an xcode project, returning an array of `XCTarget` objects.
138 | */
139 | - (NSArray*)targets;
140 |
141 | /**
142 | * Returns the target with the specified name, or nil.
143 | */
144 | - (XCTarget*)targetWithName:(NSString*)name;
145 |
146 | #pragma mark Configurations
147 |
148 | /**
149 | * Returns the target with the specified name, or nil.
150 | */
151 | - (NSDictionary*)configurations;
152 |
153 | - (NSDictionary*)configurationWithName:(NSString*)name;
154 |
155 | - (XCBuildConfiguration*)defaultConfiguration;
156 |
157 | /* ====================================================================================================================================== */
158 | #pragma mark Saving
159 | /**
160 | * Saves a project after editing.
161 | */
162 | - (void)save;
163 |
164 |
165 | /* ====================================================================================================================================== */
166 | /**
167 | * Raw project data.
168 | */
169 | - (NSMutableDictionary*)objects;
170 |
171 | - (NSMutableDictionary*)dataStore;
172 |
173 | - (void)dropCache;
174 |
175 | @end
176 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCGroup.h:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import
14 | #import "XcodeGroupMember.h"
15 |
16 | @class XCProject;
17 | @class XCClassDefinition;
18 | @class XCSourceFile;
19 | @class XCXibDefinition;
20 | @class XCFileOperationQueue;
21 | @class XCFrameworkDefinition;
22 | @class XCSourceFileDefinition;
23 | @class XCSubProjectDefinition;
24 |
25 |
26 | /**
27 | * Represents a group container in an Xcode project. A group can contain members of type `XCSourceFile` or other
28 | * groups.
29 | */
30 | @interface XCGroup : NSObject
31 | {
32 |
33 | NSString* _pathRelativeToParent;
34 | NSString* _key;
35 | NSString* _alias;
36 |
37 |
38 | @private
39 | NSString* _pathRelativeToProjectRoot;
40 | NSMutableArray* _children;
41 | NSMutableArray* _members;
42 |
43 | XCFileOperationQueue* _fileOperationQueue; // weak
44 | XCProject* _project;
45 |
46 | }
47 |
48 |
49 | /**
50 | * The alias of the group, which can be used to give the group a name other than the last path component.
51 | *
52 | * See: [XcodeGroupMember displayName]
53 | */
54 | @property(nonatomic, strong, readonly) NSString* alias;
55 |
56 | /**
57 | * The path of the group relative to the group's parent.
58 | *
59 | * See: [XcodeGroupMember displayName]
60 | */
61 | @property(nonatomic, strong, readonly) NSString* pathRelativeToParent;
62 |
63 | /**
64 | * The group's unique key.
65 | */
66 | @property(nonatomic, strong, readonly) NSString* key;
67 |
68 | /**
69 | * An array containing the groups members as `XcodeGroupMember` types.
70 | */
71 | @property(nonatomic, strong, readonly) NSMutableArray* children;
72 |
73 |
74 | #pragma mark Initializers
75 |
76 | + (XCGroup*)groupWithProject:(XCProject*)project key:(NSString*)key alias:(NSString*)alias path:(NSString*)path children:(NSArray*)children;
77 |
78 | - (id)initWithProject:(XCProject*)project key:(NSString*)key alias:(NSString*)alias path:(NSString*)path children:(NSArray*)children;
79 |
80 | #pragma mark Parent group
81 |
82 | - (void)removeFromParentGroup;
83 |
84 | - (void)removeFromParentDeletingChildren:(BOOL)deleteChildren;
85 |
86 | - (XCGroup*)parentGroup;
87 |
88 | - (BOOL)isRootGroup;
89 |
90 | #pragma mark Adding children
91 | /**
92 | * Adds a class to the group, as specified by the ClassDefinition. If the group already contains a class by the same
93 | * name, the contents will be updated.
94 | */
95 | - (void)addClass:(XCClassDefinition*)classDefinition;
96 |
97 | /**
98 | * Adds a class to the group, making it a member of the specified [targets](XCTarget).
99 | */
100 | - (void)addClass:(XCClassDefinition*)classDefinition toTargets:(NSArray*)targets;
101 |
102 | /**
103 | * Adds a framework to the group. If the group already contains the framework, the contents will be updated if the
104 | * framework definition's copyToDestination flag is yes, otherwise it will be ignored.
105 | */
106 | - (void)addFramework:(XCFrameworkDefinition*)frameworkDefinition;
107 |
108 | /**
109 | * Adds a group with a path relative to this group.
110 | */
111 | - (XCGroup*)addGroupWithPath:(NSString*)path;
112 |
113 | /**
114 | * Adds a framework to the group, making it a member of the specified targets.
115 | */
116 | - (void)addFramework:(XCFrameworkDefinition*)framework toTargets:(NSArray*)targets;
117 |
118 | /**
119 | * Adds a source file of arbitrary type - image resource, header, etc.
120 | */
121 | - (void)addSourceFile:(XCSourceFileDefinition*)sourceFileDefinition;
122 |
123 |
124 | /**
125 | * Adds a xib file to the group. If the group already contains a class by the same name, the contents will be updated.
126 | */
127 | - (void)addXib:(XCXibDefinition*)xibDefinition;
128 |
129 | /**
130 | * Adds a xib to the group, making it a member of the specified [targets](XCTarget).
131 | */
132 | - (void)addXib:(XCXibDefinition*)xibDefinition toTargets:(NSArray*)targets;
133 |
134 | /**
135 | * Adds a sub-project to the group. If the group already contains a sub-project by the same name, the contents will be
136 | * updated.
137 | * Returns boolean success/fail; if method fails, caller should assume that project file is corrupt (or file format has
138 | * changed).
139 | */
140 | - (void)addSubProject:(XCSubProjectDefinition*)projectDefinition;
141 |
142 | /**
143 | * Adds a sub-project to the group, making it a member of the specified [targets](XCTarget).
144 | */
145 | - (void)addSubProject:(XCSubProjectDefinition*)projectDefinition toTargets:(NSArray*)targets;
146 |
147 | - (void)removeSubProject:(XCSubProjectDefinition*)projectDefinition;
148 |
149 | - (void)removeSubProject:(XCSubProjectDefinition*)projectDefinition fromTargets:(NSArray*)targets;
150 |
151 |
152 | #pragma mark Locating children
153 | /**
154 | * Instances of `XCSourceFile` and `XCGroup` returned as the type `XcodeGroupMember`.
155 | */
156 | - (NSArray*)members;
157 |
158 | /**
159 | * Instances of `XCSourceFile` from this group and any child groups.
160 | */
161 | - (NSArray*)recursiveMembers;
162 |
163 |
164 | - (NSArray*)buildFileKeys;
165 |
166 | /**
167 | * Returns the child with the specified key, or nil.
168 | */
169 | - (id )memberWithKey:(NSString*)key;
170 |
171 | /**
172 | * Returns the child with the specified name, or nil.
173 | */
174 | - (id )memberWithDisplayName:(NSString*)name;
175 |
176 |
177 | @end
178 |
--------------------------------------------------------------------------------
/Dependencies/OCLogTemplate/OCLogTemplate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * For Objective-C code, this library adds flexible, non-intrusive logging capabilities
3 | * that can be efficiently enabled or disabled via compile switches.
4 | *
5 | * There are four levels of logging: Trace, Info, Error and Debug, and each can be enabled
6 | * independently via the LOGGING_LEVEL_TRACE, LOGGING_LEVEL_INFO, LOGGING_LEVEL_ERROR and
7 | * LOGGING_LEVEL_DEBUG switches, respectively.
8 | *
9 | * In addition, ALL logging can be enabled or disabled via the LOGGING_ENABLED switch.
10 | *
11 | * Logging functions are implemented here via macros. Disabling logging, either entirely, or
12 | * at a specific level, completely removes the corresponding log invocations from the compiled
13 | * code, thus eliminating both the memory and CPU overhead that the logging calls would add.
14 | * You might choose, for example, to completely remove all logging from production release code,
15 | * by setting LOGGING_ENABLED off in your production builds settings. Or, as another example,
16 | * you might choose to include Error logging in your production builds by turning only
17 | * LOGGING_ENABLED and LOGGING_LEVEL_ERROR on, and turning the others off.
18 | *
19 | * To perform logging, use any of the following function calls in your code:
20 | *
21 | * LogTrace(fmt, ...) - recommended for detailed tracing of program flow
22 | * - will print if LOGGING_LEVEL_TRACE is set on.
23 | *
24 | * LogInfo(fmt, ...) - recommended for general, infrequent, information messages
25 | * - will print if LOGGING_LEVEL_INFO is set on.
26 | *
27 | * LogError(fmt, ...) - recommended for use only when there is an error to be logged
28 | * - will print if LOGGING_LEVEL_ERROR is set on.
29 | *
30 | * LogDebug(fmt, ...) - recommended for temporary use during debugging
31 | * - will print if LOGGING_LEVEL_DEBUG is set on.
32 | *
33 | * In each case, the functions follow the general NSLog/printf template, where the first argument
34 | * "fmt" is an NSString that optionally includes embedded Format Specifiers, and subsequent optional
35 | * arguments indicate data to be formatted and inserted into the string. As with NSLog, the number
36 | * of optional arguments must match the number of embedded Format Specifiers. For more info, see the
37 | * core documentation for NSLog and String Format Specifiers.
38 | *
39 | * You can choose to have each logging entry automatically include class, method and line information
40 | * by enabling the LOGGING_INCLUDE_CODE_LOCATION switch.
41 | *
42 | * Although you can directly edit this file to turn on or off the switches below, the preferred
43 | * technique is to set these switches via the compiler build setting GCC_PREPROCESSOR_DEFINITIONS
44 | * in your build configuration.
45 | */
46 |
47 | /**
48 | * Set this switch to enable or disable logging capabilities.
49 | * This can be set either here or via the compiler build setting GCC_PREPROCESSOR_DEFINITIONS
50 | * in your build configuration. Using the compiler build setting is preferred for this to
51 | * ensure that logging is not accidentally left enabled by accident in release builds.
52 | */
53 | #ifndef LOGGING_ENABLED
54 | # define LOGGING_ENABLED 1
55 | #endif
56 |
57 | /**
58 | * Set any or all of these switches to enable or disable logging at specific levels.
59 | * These can be set either here or as a compiler build settings.
60 | * For these settings to be effective, LOGGING_ENABLED must also be defined and non-zero.
61 | */
62 | #ifndef LOGGING_LEVEL_TRACE
63 | # define LOGGING_LEVEL_TRACE 0
64 | #endif
65 | #ifndef LOGGING_LEVEL_INFO
66 | # define LOGGING_LEVEL_INFO 1
67 | #endif
68 | #ifndef LOGGING_LEVEL_ERROR
69 | # define LOGGING_LEVEL_ERROR 1
70 | #endif
71 | #ifndef LOGGING_LEVEL_DEBUG
72 | # define LOGGING_LEVEL_DEBUG 1
73 | #endif
74 |
75 | /**
76 | * Set this switch to indicate whether or not to include class, method and line information
77 | * in the log entries. This can be set either here or as a compiler build setting.
78 | */
79 | #ifndef LOGGING_INCLUDE_CODE_LOCATION
80 | #define LOGGING_INCLUDE_CODE_LOCATION 1
81 | #endif
82 |
83 | // *********** END OF USER SETTINGS - Do not change anything below this line ***********
84 |
85 |
86 | #if !(defined(LOGGING_ENABLED) && LOGGING_ENABLED)
87 | #undef LOGGING_LEVEL_TRACE
88 | #undef LOGGING_LEVEL_INFO
89 | #undef LOGGING_LEVEL_ERROR
90 | #undef LOGGING_LEVEL_DEBUG
91 | #endif
92 |
93 | // Logging format
94 | #define LOG_FORMAT_NO_LOCATION(fmt, lvl, ...) NSLog((@"[%@] " fmt), lvl, ##__VA_ARGS__)
95 | #define LOG_FORMAT_WITH_LOCATION(fmt, lvl, ...) NSLog((@"%s[Line %d] [%@] " fmt), __PRETTY_FUNCTION__, __LINE__, lvl, ##__VA_ARGS__)
96 |
97 | #if defined(LOGGING_INCLUDE_CODE_LOCATION) && LOGGING_INCLUDE_CODE_LOCATION
98 | #define LOG_FORMAT(fmt, lvl, ...) LOG_FORMAT_WITH_LOCATION(fmt, lvl, ##__VA_ARGS__)
99 | #else
100 | #define LOG_FORMAT(fmt, lvl, ...) LOG_FORMAT_NO_LOCATION(fmt, lvl, ##__VA_ARGS__)
101 | #endif
102 |
103 | // Trace logging - for detailed tracing
104 | #if defined(LOGGING_LEVEL_TRACE) && LOGGING_LEVEL_TRACE
105 | #define LogTrace(fmt, ...) LOG_FORMAT(fmt, @"trace", ##__VA_ARGS__)
106 | #else
107 | #define LogTrace(...)
108 | #endif
109 |
110 | // Info logging - for general, non-performance affecting information messages
111 | #if defined(LOGGING_LEVEL_INFO) && LOGGING_LEVEL_INFO
112 | #define LogInfo(fmt, ...) LOG_FORMAT(fmt, @"info", ##__VA_ARGS__)
113 | #else
114 | #define LogInfo(...)
115 | #endif
116 |
117 | // Error logging - only when there is an error to be logged
118 | #if defined(LOGGING_LEVEL_ERROR) && LOGGING_LEVEL_ERROR
119 | #define LogError(fmt, ...) LOG_FORMAT(fmt, @"***ERROR***", ##__VA_ARGS__)
120 | #else
121 | #define LogError(...)
122 | #endif
123 |
124 | // Debug logging - use only temporarily for highlighting and tracking down problems
125 | #if defined(LOGGING_LEVEL_DEBUG) && LOGGING_LEVEL_DEBUG
126 | #define LogDebug(fmt, ...) LOG_FORMAT(fmt, @"DEBUG", ##__VA_ARGS__)
127 | #else
128 | #define LogDebug(...)
129 | #endif
130 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCFileOperationQueue.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCFileOperationQueue.h"
15 |
16 | @interface XCFileOperationQueue ()
17 |
18 | - (NSString*)destinationPathFor:(NSString*)fileName inProjectDirectory:(NSString*)directory;
19 |
20 | - (void)performFileWrites;
21 |
22 | - (void)performCopyFrameworks;
23 |
24 | - (void)performFileDeletions;
25 |
26 | - (void)performCreateDirectories;
27 |
28 | @end
29 |
30 |
31 | @implementation XCFileOperationQueue
32 |
33 | /* ====================================================================================================================================== */
34 | #pragma mark - Initialization & Destruction
35 |
36 | - (id)initWithBaseDirectory:(NSString*)baseDirectory
37 | {
38 | self = [super init];
39 | if (self)
40 | {
41 | _baseDirectory = [baseDirectory copy];
42 | _filesToWrite = [[NSMutableDictionary alloc] init];
43 | _frameworksToCopy = [[NSMutableDictionary alloc] init];
44 | _filesToDelete = [[NSMutableArray alloc] init];
45 | _directoriesToCreate = [[NSMutableArray alloc] init];
46 | }
47 | return self;
48 | }
49 |
50 | /* ====================================================================================================================================== */
51 | #pragma mark - Interface Methods
52 |
53 | - (BOOL)fileWithName:(NSString*)name existsInProjectDirectory:(NSString*)directory
54 | {
55 | NSString* filePath = [self destinationPathFor:name inProjectDirectory:directory];
56 | return [[NSFileManager defaultManager] fileExistsAtPath:filePath];
57 | }
58 |
59 |
60 | - (void)queueTextFile:(NSString*)fileName inDirectory:(NSString*)directory withContents:(NSString*)contents
61 | {
62 | [_filesToWrite setObject:[contents dataUsingEncoding:NSUTF8StringEncoding]
63 | forKey:[self destinationPathFor:fileName inProjectDirectory:directory]];
64 | }
65 |
66 | - (void)queueDataFile:(NSString*)fileName inDirectory:(NSString*)directory withContents:(NSData*)contents
67 | {
68 | [_filesToWrite setObject:contents forKey:[self destinationPathFor:fileName inProjectDirectory:directory]];
69 | }
70 |
71 |
72 | - (void)queueFrameworkWithFilePath:(NSString*)filePath inDirectory:(NSString*)directory
73 | {
74 |
75 | NSURL* sourceUrl = [NSURL fileURLWithPath:filePath isDirectory:YES];
76 | NSString* destinationPath =
77 | [[_baseDirectory stringByAppendingPathComponent:directory] stringByAppendingPathComponent:[filePath lastPathComponent]];
78 | NSURL* destinationUrl = [NSURL fileURLWithPath:destinationPath isDirectory:YES];
79 | [_frameworksToCopy setObject:sourceUrl forKey:destinationUrl];
80 | }
81 |
82 | - (void)queueDeletion:(NSString*)filePath
83 | {
84 | NSLog(@"Queue deletion at: %@", filePath);
85 | [_filesToDelete addObject:filePath];
86 | }
87 |
88 | - (void)queueDirectory:(NSString*)withName inDirectory:(NSString*)parentDirectory
89 | {
90 | [_directoriesToCreate addObject:[self destinationPathFor:withName inProjectDirectory:parentDirectory]];
91 | }
92 |
93 | - (void)commitFileOperations
94 | {
95 | [self performFileWrites];
96 | [self performCopyFrameworks];
97 | [self performFileDeletions];
98 | [self performCreateDirectories];
99 | }
100 |
101 |
102 | /* ====================================================================================================================================== */
103 | #pragma mark - Private Methods
104 |
105 | - (NSString*)destinationPathFor:(NSString*)fileName inProjectDirectory:(NSString*)directory
106 | {
107 | return [[_baseDirectory stringByAppendingPathComponent:directory] stringByAppendingPathComponent:fileName];
108 | }
109 |
110 | - (void)performFileWrites
111 | {
112 | [_filesToWrite enumerateKeysAndObjectsUsingBlock:^(NSString* filePath, NSData* data, BOOL* stop)
113 | {
114 | NSError* error = nil;
115 | if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error])
116 | {
117 | [NSException raise:NSInternalInconsistencyException format:@"Error writing file at filePath: %@, error: %@", filePath, error];
118 | }
119 | }];
120 | [_filesToWrite removeAllObjects];
121 | }
122 |
123 | - (void)performCopyFrameworks
124 | {
125 | [_frameworksToCopy enumerateKeysAndObjectsUsingBlock:^(NSURL* destinationUrl, NSURL* frameworkPath, BOOL* stop)
126 | {
127 |
128 | NSFileManager* fileManager = [NSFileManager defaultManager];
129 |
130 | if ([fileManager fileExistsAtPath:[destinationUrl path]])
131 | {
132 | [fileManager removeItemAtURL:destinationUrl error:nil];
133 | }
134 | NSError* error = nil;
135 | if (![fileManager copyItemAtURL:frameworkPath toURL:destinationUrl error:&error])
136 | {
137 | [NSException raise:NSInternalInconsistencyException format:@"Error writing file at filePath: %@",
138 | [frameworkPath absoluteString]];
139 | }
140 | }];
141 | [_frameworksToCopy removeAllObjects];
142 | }
143 |
144 | - (void)performFileDeletions
145 | {
146 | for (NSString* filePath in [_filesToDelete reverseObjectEnumerator])
147 | {
148 | NSString* fullPath = [_baseDirectory stringByAppendingPathComponent:filePath];
149 | NSError* error = nil;
150 |
151 | if (![[NSFileManager defaultManager] removeItemAtPath:fullPath error:&error])
152 | {
153 | NSLog(@"failed to remove item at path; error == %@", error);
154 | [NSException raise:NSInternalInconsistencyException format:@"Error deleting file at filePath: %@", filePath];
155 | }
156 | else
157 | {
158 | NSLog(@"Deleted: %@", fullPath);
159 | }
160 | }
161 | [_filesToDelete removeAllObjects];
162 | }
163 |
164 | - (void)performCreateDirectories
165 | {
166 | for (NSString* filePath in _directoriesToCreate)
167 | {
168 | NSFileManager* fileManager = [NSFileManager defaultManager];
169 | if (![fileManager fileExistsAtPath:filePath])
170 | {
171 | if (![fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil])
172 | {
173 | [NSException raise:NSInvalidArgumentException format:@"Error: Create folder failed %@", filePath];
174 | }
175 | }
176 | }
177 | }
178 |
179 |
180 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCSubProjectDefinition.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCProject.h"
15 | #import "XCProject+SubProject.h"
16 | #import "XCSubProjectDefinition.h"
17 |
18 | @interface XCSubProjectDefinition ()
19 | @property(nonatomic, strong, readwrite) NSString* relativePath;
20 | @end
21 |
22 | @implementation XCSubProjectDefinition
23 |
24 | @synthesize name = _name;
25 | @synthesize path = _path;
26 | @synthesize type = _type;
27 | @synthesize parentProject = _parentProject;
28 | @synthesize subProject = _subProject;
29 | @synthesize relativePath = _relativePath;
30 | @synthesize key = _key;
31 | @synthesize fullProjectPath = _fullProjectPath;
32 |
33 | /* ====================================================================================================================================== */
34 | #pragma mark - Class Methods
35 |
36 | + (XCSubProjectDefinition*)withName:(NSString*)name path:(NSString*)path parentProject:(XCProject*)parentProject
37 | {
38 |
39 | return [[XCSubProjectDefinition alloc] initWithName:name path:path parentProject:parentProject];
40 | }
41 |
42 | /* ====================================================================================================================================== */
43 | #pragma mark - Initialization & Destruction
44 |
45 | // Note - _path is most often going to be an absolute path. The method pathRelativeToProjectRoot below should be
46 | // used to get the form that's stored in the main project file.
47 | - (id)initWithName:(NSString*)name path:(NSString*)path parentProject:(XCProject*)parentProject
48 | {
49 | self = [super init];
50 | if (self)
51 | {
52 | _name = [name copy];
53 | _path = [path copy];
54 | _type = XcodeProject;
55 | _parentProject = parentProject;
56 | _subProject = [[XCProject alloc] initWithFilePath:[NSString stringWithFormat:@"%@/%@.xcodeproj", path, name]];
57 | }
58 | return self;
59 | }
60 |
61 | /* ====================================================================================================================================== */
62 | #pragma mark - Interface Methods
63 |
64 | - (NSString*)projectFileName
65 | {
66 | return [_name stringByAppendingString:@".xcodeproj"];
67 | }
68 |
69 | - (NSString*)fullPathName
70 | {
71 | return [NSString stringWithFormat:@"%@/%@", _path, [_name stringByAppendingString:@".xcodeproj"]];
72 | }
73 |
74 | // returns an array of names of the build products of this project
75 | - (NSArray*)buildProductNames
76 | {
77 | NSMutableArray* results = [NSMutableArray array];
78 | NSDictionary* objects = [_subProject objects];
79 | [objects enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
80 | {
81 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXProjectType)
82 | {
83 | NSString* productRefGroupKey = [obj valueForKey:@"productRefGroup"];
84 | NSDictionary* products = [objects valueForKey:productRefGroupKey];
85 | NSArray* children = [products valueForKey:@"children"];
86 | for (NSString* childKey in children)
87 | {
88 | NSDictionary* child = [objects valueForKey:childKey];
89 | [results addObject:[child valueForKey:@"path"]];
90 | }
91 | }
92 | }];
93 | return results;
94 | }
95 |
96 | // returns the key of the PBXFileReference of the xcodeproj file
97 | - (NSString*)projectKey
98 | {
99 | if (_key == nil)
100 | {
101 | NSArray* xcodeprojKeys =
102 | [_parentProject keysForProjectObjectsOfType:PBXFileReferenceType withIdentifier:[self pathRelativeToProjectRoot] singleton:YES
103 | required:YES];
104 | _key = [[xcodeprojKeys objectAtIndex:0] copy];
105 | }
106 | return [_key copy];
107 | }
108 |
109 | - (void)initFullProjectPath:(NSString*)fullProjectPath groupPath:(NSString*)groupPath
110 | {
111 | if (groupPath != nil)
112 | {
113 | NSMutableArray* fullPathComponents = [[fullProjectPath pathComponents] mutableCopy];
114 | [fullPathComponents removeLastObject];
115 | fullProjectPath = [[NSString pathWithComponents:fullPathComponents] stringByAppendingFormat:@"/%@", groupPath];
116 | }
117 | _fullProjectPath = [fullProjectPath copy];
118 |
119 | }
120 |
121 | // compares the given path to the filePath of the project, and returns a relative version. _fullProjectPath, which has
122 | // to hve been previously set, is the full path to the project *plus* the path to the xcodeproj's group, if any.
123 | - (NSString*)pathRelativeToProjectRoot
124 | {
125 | if (_relativePath == nil)
126 | {
127 | if (_fullProjectPath == nil)
128 | {
129 | [NSException raise:NSInvalidArgumentException format:@"fullProjectPath has not been set"];
130 | }
131 | NSMutableArray* projectPathComponents = [[_fullProjectPath pathComponents] mutableCopy];
132 | NSArray* objectPathComponents = [[self fullPathName] pathComponents];
133 | NSString* convertedPath = @"";
134 |
135 | // skip over path components from root that are equal
136 | NSInteger limit =
137 | ([projectPathComponents count] < [objectPathComponents count]) ? [projectPathComponents count] : [objectPathComponents count];
138 | NSInteger index1 = 0;
139 | for (; index1 < limit; index1++)
140 | {
141 | if ([[projectPathComponents objectAtIndex:index1] isEqualToString:[objectPathComponents objectAtIndex:index1]])
142 | {
143 | continue;
144 | }
145 | else
146 | {
147 | break;
148 | }
149 | }
150 | // insert "../" for each remaining path component in project's xcodeproj path
151 | for (NSInteger index2 = 0; index2 < ([projectPathComponents count] - index1); index2++)
152 | {
153 | convertedPath = [convertedPath stringByAppendingString:@"../"];
154 | }
155 | // tack on the unique part of the object's path
156 | for (NSInteger index3 = index1; index3 < [objectPathComponents count] - 1; index3++)
157 | {
158 | convertedPath = [convertedPath stringByAppendingFormat:@"%@/", [objectPathComponents objectAtIndex:index3]];
159 | }
160 | _relativePath = [[convertedPath stringByAppendingString:[objectPathComponents lastObject]] copy];
161 | }
162 | return [_relativePath copy];
163 | }
164 |
165 |
166 | /* ====================================================================================================================================== */
167 | #pragma mark - Utility Methods
168 |
169 | - (NSString*)description
170 | {
171 | return [NSString stringWithFormat:@"XcodeprojDefinition: sourceFileName = %@, path=%@, type=%d", _name, _path, _type];
172 | }
173 |
174 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCSourceFile.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCSourceFile.h"
15 | #import "XCProject.h"
16 | #import "Utils/XCKeyBuilder.h"
17 | #import "XCGroup.h"
18 |
19 | @implementation XCSourceFile
20 |
21 | @synthesize type = _type;
22 | @synthesize key = _key;
23 | @synthesize sourceTree = _sourceTree;
24 |
25 | /* ====================================================================================================================================== */
26 | #pragma mark - Class Methods
27 |
28 | + (XCSourceFile*)sourceFileWithProject:(XCProject*)project key:(NSString*)key type:(XcodeSourceFileType)type name:(NSString*)name
29 | sourceTree:(NSString*)_tree path:(NSString*)path
30 | {
31 | return [[XCSourceFile alloc] initWithProject:project key:key type:type name:name sourceTree:_tree path:path];
32 | }
33 |
34 |
35 | /* ====================================================================================================================================== */
36 | #pragma mark - Initialization & Destruction
37 |
38 | - (id)initWithProject:(XCProject*)project key:(NSString*)key type:(XcodeSourceFileType)type name:(NSString*)name sourceTree:(NSString*)tree
39 | path:(NSString*)path
40 | {
41 |
42 | self = [super init];
43 | if (self)
44 | {
45 | _project = project;
46 | _key = [key copy];
47 | _type = type;
48 | _name = [name copy];
49 | _sourceTree = [tree copy];
50 | _path = [path copy];
51 | }
52 | return self;
53 | }
54 |
55 |
56 | /* ====================================================================================================================================== */
57 | #pragma mark - Interface Methods
58 |
59 | // Goes to the entry for this object in the project and sets a value for one of the keys, such as name, path, etc.
60 | - (void)setValue:(id)val forProjectItemPropertyWithKey:(NSString*)key
61 | {
62 | NSMutableDictionary* obj = [[[_project objects] objectForKey:_key] mutableCopy];
63 | if (nil == obj)
64 | {
65 | [NSException raise:@"Project item not found" format:@"Project item with key %@ not found.", _key];
66 | }
67 | [obj setValue:val forKey:key];
68 | [[_project objects] setValue:obj forKey:_key];
69 | }
70 |
71 |
72 | - (NSString*)name
73 | {
74 | return _name;
75 | }
76 |
77 | - (void)setName:(NSString*)name
78 | {
79 | id old = _name;
80 | _name = [name copy];
81 |
82 | [self setValue:name forProjectItemPropertyWithKey:@"name"];
83 | }
84 |
85 |
86 | - (NSString*)path
87 | {
88 | return _path;
89 | }
90 |
91 | - (void)setPath:(NSString*)path
92 | {
93 | id old = _path;
94 | _path = [path copy];
95 |
96 | [self setValue:path forProjectItemPropertyWithKey:@"path"];
97 | }
98 |
99 | - (BOOL)isBuildFile
100 | {
101 | if ([self canBecomeBuildFile] && _isBuildFile == nil)
102 | {
103 | id old = _isBuildFile;
104 | _isBuildFile = [[NSNumber numberWithBool:NO] copy];
105 | [[_project objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
106 | {
107 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXBuildFileType)
108 | {
109 | if ([[obj valueForKey:@"fileRef"] isEqualToString:_key])
110 | {
111 | _isBuildFile = nil;
112 |
113 | _isBuildFile = [[NSNumber numberWithBool:YES] copy];
114 | }
115 | }
116 | }];
117 | }
118 | return [_isBuildFile boolValue];
119 | }
120 |
121 | - (BOOL)canBecomeBuildFile
122 | {
123 | return _type == SourceCodeObjC || _type == SourceCodeObjCPlusPlus || _type == SourceCodeCPlusPlus || _type == XibFile || _type ==
124 | Framework || _type == ImageResourcePNG || _type == HTML || _type == Bundle || _type == Archive;
125 | }
126 |
127 |
128 | - (XcodeMemberType)buildPhase
129 | {
130 | if (_type == SourceCodeObjC || _type == SourceCodeObjCPlusPlus || _type == SourceCodeCPlusPlus || _type == XibFile)
131 | {
132 | return PBXSourcesBuildPhaseType;
133 | }
134 | else if (_type == Framework)
135 | {
136 | return PBXFrameworksBuildPhaseType;
137 | }
138 | else if (_type == ImageResourcePNG || _type == HTML || _type == Bundle)
139 | {
140 | return PBXResourcesBuildPhaseType;
141 | }
142 | else if (_type == Archive)
143 | {
144 | return PBXFrameworksBuildPhaseType;
145 | }
146 | return PBXNilType;
147 | }
148 |
149 | - (NSString*)buildFileKey
150 | {
151 | if (_buildFileKey == nil)
152 | {
153 | [[_project objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
154 | {
155 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXBuildFileType)
156 | {
157 | if ([[obj valueForKey:@"fileRef"] isEqualToString:_key])
158 | {
159 | _buildFileKey = [key copy];
160 | }
161 | }
162 | }];
163 | }
164 | return [_buildFileKey copy];
165 |
166 | }
167 |
168 |
169 | - (void)becomeBuildFile
170 | {
171 | if (![self isBuildFile])
172 | {
173 | if ([self canBecomeBuildFile])
174 | {
175 | NSMutableDictionary* sourceBuildFile = [NSMutableDictionary dictionary];
176 | [sourceBuildFile setObject:[NSString stringFromMemberType:PBXBuildFileType] forKey:@"isa"];
177 | [sourceBuildFile setObject:_key forKey:@"fileRef"];
178 | NSString* buildFileKey = [[XCKeyBuilder forItemNamed:[_name stringByAppendingString:@".buildFile"]] build];
179 | [[_project objects] setObject:sourceBuildFile forKey:buildFileKey];
180 | }
181 | else if (_type == Framework)
182 | {
183 | [NSException raise:NSInvalidArgumentException format:@"Add framework to target not implemented yet."];
184 | }
185 | else
186 | {
187 | [NSException raise:NSInvalidArgumentException format:@"Project file of type %@ can't become a build file.",
188 | NSStringFromXCSourceFileType(_type)];
189 | }
190 |
191 | }
192 | }
193 |
194 | /* ====================================================================================================================================== */
195 | #pragma mark - Protocol Methods
196 |
197 | - (XcodeMemberType)groupMemberType
198 | {
199 | return PBXFileReferenceType;
200 | }
201 |
202 | - (NSString*)displayName
203 | {
204 | return _name;
205 | }
206 |
207 | - (NSString*)pathRelativeToProjectRoot
208 | {
209 | NSString* parentPath = [[_project groupForGroupMemberWithKey:_key] pathRelativeToProjectRoot];
210 | NSString* result = [parentPath stringByAppendingPathComponent:_name];
211 | return result;
212 | }
213 |
214 | /* ====================================================================================================================================== */
215 | #pragma mark - Utility Methods
216 |
217 | - (NSString*)description
218 | {
219 | return [NSString stringWithFormat:@"Project file: key=%@, name=%@, fullPath=%@", _key, _name, [self pathRelativeToProjectRoot]];
220 | }
221 |
222 |
223 | @end
224 |
225 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCBuildConfiguration.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCBuildConfiguration.h"
15 | #import "XCGroup.h"
16 | #import "XCKeyBuilder.h"
17 | #import "XCProject.h"
18 | #import "XCSourceFile.h"
19 | #import "OCLogTemplate.h"
20 |
21 | @implementation XCBuildConfiguration
22 |
23 | /* ====================================================================================================================================== */
24 | #pragma mark - Class Methods
25 |
26 | + (NSDictionary*)buildConfigurationsFromArray:(NSArray*)array inProject:(XCProject*)project
27 | {
28 | NSMutableDictionary* configurations = [NSMutableDictionary dictionary];
29 |
30 | for (NSString* buildConfigurationKey in array)
31 | {
32 | NSDictionary* buildConfiguration = [[project objects] objectForKey:buildConfigurationKey];
33 |
34 | if ([[buildConfiguration valueForKey:@"isa"] asMemberType] == XCBuildConfigurationType)
35 | {
36 | XCBuildConfiguration* configuration = [configurations objectForKey:[buildConfiguration objectForKey:@"name"]];
37 | if (!configuration)
38 | {
39 | configuration = [[XCBuildConfiguration alloc] initWithProject:project key:buildConfigurationKey];
40 |
41 | [configurations setObject:configuration forKey:[buildConfiguration objectForKey:@"name"]];
42 | }
43 |
44 |
45 | XCSourceFile* configurationFile = [project fileWithKey:[buildConfiguration objectForKey:@"baseConfigurationReference"]];
46 | if (configurationFile)
47 | {
48 | NSString* path = configurationFile.path;
49 |
50 | if (![[NSFileManager defaultManager] fileExistsAtPath:path])
51 | {
52 | XCGroup* group = [project groupWithSourceFile:configurationFile];
53 | path = [[group pathRelativeToParent] stringByAppendingPathComponent:path];
54 | }
55 |
56 | if (![[NSFileManager defaultManager] fileExistsAtPath:path])
57 | {
58 | path = [[[project filePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:path];
59 | }
60 |
61 | if (![[NSFileManager defaultManager] fileExistsAtPath:path])
62 | {
63 | path = [[[project filePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:configurationFile.path];
64 | }
65 |
66 | if (![[NSFileManager defaultManager] fileExistsAtPath:path])
67 | {
68 | [NSException raise:@"XCConfig not found" format:@"Unable to find XCConfig file at %@", path];
69 | }
70 |
71 | }
72 |
73 | [configuration addBuildSettings:[buildConfiguration objectForKey:@"buildSettings"]];
74 | }
75 | }
76 |
77 | return configurations;
78 | }
79 |
80 | + (NSString*)duplicatedBuildConfigurationListWithKey:(NSString*)buildConfigurationListKey inProject:(XCProject*)project
81 | withBuildConfigurationVisitor:(void (^)(NSMutableDictionary*))buildConfigurationVisitor
82 | {
83 |
84 | NSDictionary* buildConfigurationList = project.objects[buildConfigurationListKey];
85 | NSMutableDictionary* dupBuildConfigurationList = [buildConfigurationList mutableCopy];
86 |
87 | NSMutableArray* dupBuildConfigurations = [NSMutableArray array];
88 |
89 | for (NSString* buildConfigurationKey in buildConfigurationList[@"buildConfigurations"])
90 | {
91 | [dupBuildConfigurations addObject:[self duplicatedBuildConfigurationWithKey:buildConfigurationKey inProject:project
92 | withBuildConfigurationVisitor:buildConfigurationVisitor]];
93 | }
94 |
95 | dupBuildConfigurationList[@"buildConfigurations"] = dupBuildConfigurations;
96 |
97 | NSString* dupBuildConfigurationListKey = [[XCKeyBuilder createUnique] build];
98 |
99 | project.objects[dupBuildConfigurationListKey] = dupBuildConfigurationList;
100 |
101 | return dupBuildConfigurationListKey;
102 | }
103 |
104 | /* ====================================================================================================================================== */
105 | #pragma mark - Initialization & Destruction
106 |
107 | - (instancetype)initWithProject:(XCProject*)project key:(NSString*)key
108 | {
109 | self = [super init];
110 | if (self)
111 | {
112 | _project = project;
113 | _key = [key copy];
114 |
115 | _buildSettings = [[NSMutableDictionary alloc] init];
116 | _xcconfigSettings = [[NSMutableDictionary alloc] init];
117 | }
118 | return self;
119 | }
120 |
121 | - (id)init
122 | {
123 | return [self initWithProject:nil key:nil];
124 | }
125 |
126 |
127 | /* ====================================================================================================================================== */
128 | #pragma mark - Interface Methods
129 |
130 | - (NSDictionary*)specifiedBuildSettings
131 | {
132 | return [_buildSettings copy];
133 | }
134 |
135 | - (void)addBuildSettings:(NSDictionary*)buildSettings
136 | {
137 | [_xcconfigSettings removeObjectsForKeys:[buildSettings allKeys]];
138 | [_buildSettings addEntriesFromDictionary:buildSettings];
139 | }
140 |
141 | - (void)addOrReplaceSetting:(id )setting forKey:(NSString*)key
142 | {
143 | NSDictionary* settings = [NSDictionary dictionaryWithObject:setting forKey:key];
144 | [self addBuildSettings:settings];
145 |
146 | LogDebug(@"$$$$$$$$$$$ before: %@", [_project.objects objectForKey:_key]);
147 |
148 | NSMutableDictionary* dict = [[[_project objects] objectForKey:_key] mutableCopy];
149 | [dict setValue:_buildSettings forKey:@"buildSettings"];
150 | [_project.objects setValue:dict forKey:_key];
151 |
152 | LogDebug(@"The settings: %@", [_project.objects objectForKey:_key]);
153 |
154 | }
155 |
156 |
157 | - (id )valueForKey:(NSString*)key
158 | {
159 | id value = [_buildSettings objectForKey:key];
160 | if (!value)
161 | {
162 | value = [_xcconfigSettings objectForKey:key];
163 | }
164 | return value;
165 | }
166 |
167 | /* ====================================================================================================================================== */
168 | #pragma mark - Utility Methods
169 |
170 | - (NSString*)description
171 | {
172 | NSMutableString* description = [[super description] mutableCopy];
173 |
174 | [description appendFormat:@"build settings: %@, inherited: %@", _buildSettings, _xcconfigSettings];
175 |
176 | return description;
177 | }
178 |
179 |
180 | /* ====================================================================================================================================== */
181 | #pragma mark - Private Methods
182 |
183 | + (NSString*)duplicatedBuildConfigurationWithKey:(NSString*)buildConfigurationKey inProject:(XCProject*)project
184 | withBuildConfigurationVisitor:(void (^)(NSMutableDictionary*))buildConfigurationVisitor
185 | {
186 | NSDictionary* buildConfiguration = project.objects[buildConfigurationKey];
187 | NSMutableDictionary* dupBuildConfiguration = [buildConfiguration mutableCopy];
188 |
189 | buildConfigurationVisitor(dupBuildConfiguration);
190 |
191 | NSString* dupBuildConfigurationKey = [[XCKeyBuilder createUnique] build];
192 |
193 | project.objects[dupBuildConfigurationKey] = dupBuildConfiguration;
194 |
195 | return dupBuildConfigurationKey;
196 | }
197 |
198 | @end
199 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCProject.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 - 2013 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 | #import "XCProject.h"
14 | #import "XCGroup.h"
15 | #import "XCSourceFile.h"
16 | #import "XCTarget.h"
17 | #import "XCFileOperationQueue.h"
18 | #import "XCBuildConfiguration.h"
19 |
20 |
21 | @implementation XCProject
22 |
23 |
24 | @synthesize fileOperationQueue = _fileOperationQueue;
25 |
26 | /* ====================================================================================================================================== */
27 | #pragma mark - Class Methods
28 |
29 | + (XCProject*)projectWithFilePath:(NSString*)filePath
30 | {
31 | return [[XCProject alloc] initWithFilePath:filePath];
32 | }
33 |
34 |
35 | /* ====================================================================================================================================== */
36 | #pragma mark - Initialization & Destruction
37 |
38 | - (id)initWithFilePath:(NSString*)filePath
39 | {
40 | if ((self = [super init]))
41 | {
42 | _filePath = [filePath copy];
43 | _dataStore = [[NSMutableDictionary alloc] initWithContentsOfFile:[_filePath stringByAppendingPathComponent:@"project.pbxproj"]];
44 |
45 | if (!_dataStore)
46 | {
47 | [NSException raise:XCProjectNotFoundException format:@"Project file not found at file path %@", _filePath];
48 | }
49 |
50 | _fileOperationQueue = [[XCFileOperationQueue alloc] initWithBaseDirectory:[_filePath stringByDeletingLastPathComponent]];
51 |
52 | }
53 | return self;
54 | }
55 |
56 | /* ====================================================================================================================================== */
57 | #pragma mark - Interface Methods
58 |
59 | #pragma mark Files
60 |
61 | - (NSArray*)files
62 | {
63 | NSMutableArray* results = [NSMutableArray array];
64 | [[self objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
65 | {
66 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXFileReferenceType)
67 | {
68 | XcodeSourceFileType fileType = XCSourceFileTypeFromStringRepresentation([obj valueForKey:@"lastKnownFileType"]);
69 | NSString* path = [obj valueForKey:@"path"];
70 | NSString* sourceTree = [obj valueForKey:@"sourceTree"];
71 | [results addObject:[XCSourceFile sourceFileWithProject:self key:key type:fileType name:path
72 | sourceTree:(sourceTree ? sourceTree : @"") path:nil]];
73 | }
74 | }];
75 | return results;
76 | }
77 |
78 | - (XCSourceFile*)fileWithKey:(NSString*)key
79 | {
80 | NSDictionary* obj = [[self objects] valueForKey:key];
81 | if (obj && ([[obj valueForKey:@"isa"] asMemberType] == PBXFileReferenceType || [[obj valueForKey:@"isa"] asMemberType] ==
82 | PBXReferenceProxyType))
83 | {
84 | XcodeSourceFileType fileType = XCSourceFileTypeFromStringRepresentation([obj valueForKey:@"lastKnownFileType"]);
85 |
86 | NSString* name = [obj valueForKey:@"name"];
87 | NSString* sourceTree = [obj valueForKey:@"sourceTree"];
88 |
89 | if (name == nil)
90 | {
91 | name = [obj valueForKey:@"path"];
92 | }
93 | return [XCSourceFile sourceFileWithProject:self key:key type:fileType name:name sourceTree:(sourceTree ? sourceTree : @"")
94 | path:[obj valueForKey:@"path"]];
95 | }
96 | return nil;
97 | }
98 |
99 | - (XCSourceFile*)fileWithName:(NSString*)name
100 | {
101 | for (XCSourceFile* projectFile in [self files])
102 | {
103 | if ([[projectFile name] isEqualToString:name])
104 | {
105 | return projectFile;
106 | }
107 | }
108 | return nil;
109 | }
110 |
111 |
112 | - (NSArray*)headerFiles
113 | {
114 | return [self projectFilesOfType:SourceCodeHeader];
115 | }
116 |
117 | - (NSArray*)objectiveCFiles
118 | {
119 | return [self projectFilesOfType:SourceCodeObjC];
120 | }
121 |
122 | - (NSArray*)objectiveCPlusPlusFiles
123 | {
124 | return [self projectFilesOfType:SourceCodeObjCPlusPlus];
125 | }
126 |
127 |
128 | - (NSArray*)xibFiles
129 | {
130 | return [self projectFilesOfType:XibFile];
131 | }
132 |
133 | - (NSArray*)imagePNGFiles
134 | {
135 | return [self projectFilesOfType:ImageResourcePNG];
136 | }
137 |
138 | // need this value to construct relative path in XcodeprojDefinition
139 | - (NSString*)filePath
140 | {
141 | return _filePath;
142 | }
143 |
144 | /* ====================================================================================================================================== */
145 | #pragma mark Groups
146 |
147 | - (NSArray*)groups
148 | {
149 |
150 | NSMutableArray* results = [[NSMutableArray alloc] init];
151 | [[_dataStore objectForKey:@"objects"] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
152 | {
153 |
154 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXGroupType || [[obj valueForKeyPath:@"isa"] asMemberType] == PBXVariantGroupType)
155 | {
156 | [results addObject:[self groupWithKey:key]];
157 | }
158 | }];
159 | return results;
160 | }
161 |
162 | //TODO: Optimize this implementation.
163 | - (XCGroup*)rootGroup
164 | {
165 | for (XCGroup* group in [self groups])
166 | {
167 | if ([group isRootGroup])
168 | {
169 | return group;
170 | }
171 | }
172 | return nil;
173 | }
174 |
175 | - (NSArray*)rootGroups
176 | {
177 | XCGroup* group = [self rootGroup];
178 | if (group)
179 | {
180 | return [NSArray arrayWithObject:group];
181 | }
182 |
183 | NSMutableArray* results = [NSMutableArray array];
184 | for (XCGroup* group in [self groups])
185 | {
186 | if ([group parentGroup] == nil)
187 | {
188 | [results addObject:group];
189 | }
190 | }
191 |
192 | return [results copy];
193 | }
194 |
195 | - (XCGroup*)groupWithKey:(NSString*)key
196 | {
197 | XCGroup* group = [_groups objectForKey:key];
198 | if (group)
199 | {
200 | return group;
201 | }
202 |
203 | NSDictionary* obj = [[self objects] objectForKey:key];
204 | if (obj && ([[obj valueForKey:@"isa"] asMemberType] == PBXGroupType || [[obj valueForKey:@"isa"] asMemberType] == PBXVariantGroupType))
205 | {
206 |
207 | NSString* name = [obj valueForKey:@"name"];
208 | NSString* path = [obj valueForKey:@"path"];
209 | NSArray* children = [obj valueForKey:@"children"];
210 | XCGroup* group = [XCGroup groupWithProject:self key:key alias:name path:path children:children];
211 |
212 | [_groups setObject:group forKey:key];
213 |
214 | return group;
215 | }
216 | return nil;
217 | }
218 |
219 | - (XCGroup*)groupForGroupMemberWithKey:(NSString*)key
220 | {
221 | for (XCGroup* group in [self groups])
222 | {
223 | if ([group memberWithKey:key])
224 | {
225 | return group;
226 | }
227 | }
228 | return nil;
229 | }
230 |
231 | - (XCGroup*)groupWithSourceFile:(XCSourceFile*)sourceFile
232 | {
233 | for (XCGroup* group in [self groups])
234 | {
235 | for (id member in [group members])
236 | {
237 | if ([member isKindOfClass:[XCSourceFile class]] && [[sourceFile key] isEqualToString:[member key]])
238 | {
239 | return group;
240 | }
241 | }
242 | }
243 | return nil;
244 | }
245 |
246 | //TODO: This could fail if the path attribute on a given group is more than one directory. Start with candidates and
247 | //TODO: search backwards.
248 | - (XCGroup*)groupWithPathFromRoot:(NSString*)path
249 | {
250 | NSArray* pathItems = [path componentsSeparatedByString:@"/"];
251 | XCGroup* currentGroup = [self rootGroup];
252 | for (NSString* pathItem in pathItems)
253 | {
254 | id group = [currentGroup memberWithDisplayName:pathItem];
255 | if ([group isKindOfClass:[XCGroup class]])
256 | {
257 | currentGroup = group;
258 | }
259 | else
260 | {
261 | return nil;
262 | }
263 | }
264 | return currentGroup;
265 | }
266 |
267 |
268 | /* ====================================================================================================================================== */
269 | #pragma mark targets
270 |
271 | - (NSArray*)targets
272 | {
273 | if (_targets == nil)
274 | {
275 | _targets = [[NSMutableArray alloc] init];
276 | [[self objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
277 | {
278 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXNativeTargetType)
279 | {
280 | XCTarget* target =
281 | [XCTarget targetWithProject:self key:key name:[obj valueForKey:@"name"] productName:[obj valueForKey:@"productName"]
282 | productReference:[obj valueForKey:@"productReference"]];
283 | [_targets addObject:target];
284 | }
285 | }];
286 | }
287 | return _targets;
288 | }
289 |
290 | - (XCTarget*)targetWithName:(NSString*)name
291 | {
292 | for (XCTarget* target in [self targets])
293 | {
294 | if ([[target name] isEqualToString:name])
295 | {
296 | return target;
297 | }
298 | }
299 | return nil;
300 | }
301 |
302 | - (void)save
303 | {
304 | [_fileOperationQueue commitFileOperations];
305 | [_dataStore writeToFile:[_filePath stringByAppendingPathComponent:@"project.pbxproj"] atomically:YES];
306 |
307 | NSLog(@"Saved project");
308 | }
309 |
310 | - (NSMutableDictionary*)objects
311 | {
312 | return [_dataStore objectForKey:@"objects"];
313 | }
314 |
315 | - (NSMutableDictionary*)dataStore
316 | {
317 | return _dataStore;
318 | }
319 |
320 | - (void)dropCache
321 | {
322 | _targets = nil;
323 | _configurations = nil;
324 | _rootObjectKey = nil;
325 | }
326 |
327 |
328 | - (NSDictionary*)configurations
329 | {
330 | if (_configurations == nil)
331 | {
332 | NSString* buildConfigurationRootSectionKey =
333 | [[[self objects] objectForKey:[self rootObjectKey]] objectForKey:@"buildConfigurationList"];
334 | NSDictionary* buildConfigurationDictionary = [[self objects] objectForKey:buildConfigurationRootSectionKey];
335 | _configurations =
336 | [[XCBuildConfiguration buildConfigurationsFromArray:[buildConfigurationDictionary objectForKey:@"buildConfigurations"]
337 | inProject:self] mutableCopy];
338 | _defaultConfigurationName = [[buildConfigurationDictionary objectForKey:@"defaultConfigurationName"] copy];
339 | }
340 |
341 | return [_configurations copy];
342 | }
343 |
344 | - (NSDictionary*)configurationWithName:(NSString*)name
345 | {
346 | return [[self configurations] objectForKey:name];
347 | }
348 |
349 | - (XCBuildConfiguration*)defaultConfiguration
350 | {
351 | return [[self configurations] objectForKey:_defaultConfigurationName];
352 | }
353 |
354 | /* ====================================================================================================================================== */
355 | #pragma mark Private
356 |
357 | - (NSString*)rootObjectKey
358 | {
359 | if (_rootObjectKey == nil)
360 | {
361 | _rootObjectKey = [[_dataStore objectForKey:@"rootObject"] copy];;
362 | }
363 |
364 | return _rootObjectKey;
365 | }
366 |
367 | - (NSArray*)projectFilesOfType:(XcodeSourceFileType)projectFileType
368 | {
369 | NSMutableArray* results = [NSMutableArray array];
370 | for (XCSourceFile* file in [self files])
371 | {
372 | if ([file type] == projectFileType)
373 | {
374 | [results addObject:file];
375 | }
376 | }
377 | return results;
378 | }
379 |
380 | @end
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCTarget.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 | #import "XCGroup.h"
13 | #import "XCKeyBuilder.h"
14 | #import "XCTarget.h"
15 | #import "XCSourceFile.h"
16 | #import "XCProject.h"
17 | #import "XCBuildConfiguration.h"
18 |
19 | @implementation XCTarget
20 |
21 | /* ====================================================================================================================================== */
22 | #pragma mark - Class Methods
23 |
24 | + (XCTarget*)targetWithProject:(XCProject*)project key:(NSString*)key name:(NSString*)name productName:(NSString*)productName
25 | productReference:(NSString*)productReference
26 | {
27 | return [[XCTarget alloc] initWithProject:project key:key name:name productName:productName productReference:productReference];
28 | }
29 |
30 |
31 | /* ====================================================================================================================================== */
32 | #pragma mark - Initialization & Destruction
33 |
34 | - (id)initWithProject:(XCProject*)project key:(NSString*)key name:(NSString*)name productName:(NSString*)productName
35 | productReference:(NSString*)productReference
36 | {
37 | self = [super init];
38 | if (self)
39 | {
40 | _project = project;
41 | _key = [key copy];
42 | _name = [name copy];
43 | _productName = [productName copy];
44 | _productReference = [productReference copy];
45 | }
46 | return self;
47 | }
48 |
49 | /* ====================================================================================================================================== */
50 | #pragma mark - Interface Methods
51 |
52 | - (NSArray*)resources
53 | {
54 | if (_resources == nil)
55 | {
56 | _resources = [[NSMutableArray alloc] init];
57 | for (NSString* buildPhaseKey in [[[_project objects] objectForKey:_key] objectForKey:@"buildPhases"])
58 | {
59 | NSDictionary* buildPhase = [[_project objects] objectForKey:buildPhaseKey];
60 | if ([[buildPhase valueForKey:@"isa"] asMemberType] == PBXResourcesBuildPhaseType)
61 | {
62 | for (NSString* buildFileKey in [buildPhase objectForKey:@"files"])
63 | {
64 | XCSourceFile* targetMember = [self buildFileWithKey:buildFileKey];
65 | if (targetMember)
66 | {
67 | [_resources addObject:[self buildFileWithKey:buildFileKey]];
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
74 | return _resources;
75 | }
76 |
77 | - (NSDictionary*)configurations
78 | {
79 | if (_configurations == nil)
80 | {
81 | NSString* buildConfigurationRootSectionKey = [[[_project objects] objectForKey:_key] objectForKey:@"buildConfigurationList"];
82 | NSDictionary* buildConfigurationDictionary = [[_project objects] objectForKey:buildConfigurationRootSectionKey];
83 | _configurations =
84 | [[XCBuildConfiguration buildConfigurationsFromArray:[buildConfigurationDictionary objectForKey:@"buildConfigurations"]
85 | inProject:_project] mutableCopy];
86 | _defaultConfigurationName = [[buildConfigurationDictionary objectForKey:@"defaultConfigurationName"] copy];
87 | }
88 |
89 | return _configurations;
90 | }
91 |
92 | - (XCBuildConfiguration*)defaultConfiguration
93 | {
94 | return [[self configurations] objectForKey:_defaultConfigurationName];
95 | }
96 |
97 | - (XCBuildConfiguration*)configurationWithName:(NSString*)name
98 | {
99 | return [[self configurations] objectForKey:name];
100 | }
101 |
102 | - (NSArray*)members
103 | {
104 | if (_members == nil)
105 | {
106 | _members = [[NSMutableArray alloc] init];
107 | for (NSString* buildPhaseKey in [[[_project objects] objectForKey:_key] objectForKey:@"buildPhases"])
108 | {
109 | NSDictionary* buildPhase = [[_project objects] objectForKey:buildPhaseKey];
110 | if ([[buildPhase valueForKey:@"isa"] asMemberType] == PBXSourcesBuildPhaseType ||
111 | [[buildPhase valueForKey:@"isa"] asMemberType] == PBXFrameworksBuildPhaseType)
112 | {
113 | for (NSString* buildFileKey in [buildPhase objectForKey:@"files"])
114 | {
115 | XCSourceFile* targetMember = [self buildFileWithKey:buildFileKey];
116 | if (targetMember)
117 | {
118 | [_members addObject:[_project fileWithKey:targetMember.key]];
119 | }
120 | }
121 | }
122 | }
123 | }
124 | return _members;
125 | }
126 |
127 | - (void)addMember:(XCSourceFile*)member
128 | {
129 | [member becomeBuildFile];
130 | NSDictionary* target = [[_project objects] objectForKey:_key];
131 |
132 | for (NSString* buildPhaseKey in [target objectForKey:@"buildPhases"])
133 | {
134 | NSMutableDictionary* buildPhase = [[_project objects] objectForKey:buildPhaseKey];
135 | if ([[buildPhase valueForKey:@"isa"] asMemberType] == [member buildPhase])
136 | {
137 |
138 | NSMutableArray* files = [buildPhase objectForKey:@"files"];
139 | if (![files containsObject:[member buildFileKey]])
140 | {
141 | [files addObject:[member buildFileKey]];
142 | }
143 |
144 | [buildPhase setObject:files forKey:@"files"];
145 | }
146 | }
147 | [self flagMembersAsDirty];
148 | }
149 |
150 | - (NSDictionary*)buildRefWithFileRefKey
151 | {
152 | NSMutableDictionary* buildRefWithFileRefDict = [NSMutableDictionary dictionary];
153 | NSDictionary* allObjects = [_project objects];
154 | NSArray* keys = [allObjects allKeys];
155 |
156 | for (NSString* key in keys)
157 | {
158 | NSDictionary* dictionaryInfo = [allObjects objectForKey:key];
159 |
160 | NSString* type = [dictionaryInfo objectForKey:@"isa"];
161 | if (type)
162 | {
163 | if ([type isEqualToString:@"PBXBuildFile"])
164 | {
165 | NSString* fileRef = [dictionaryInfo objectForKey:@"fileRef"];
166 |
167 | if (fileRef)
168 | {
169 | [buildRefWithFileRefDict setObject:key forKey:fileRef];
170 | }
171 | }
172 | }
173 | }
174 | return buildRefWithFileRefDict;
175 | }
176 |
177 | - (void)removeMemberWithKey:(NSString*)key
178 | {
179 |
180 | NSDictionary* buildRefWithFileRef = [self buildRefWithFileRefKey];
181 | NSDictionary* target = [[_project objects] objectForKey:_key];
182 | NSString* buildRef = [buildRefWithFileRef objectForKey:key];
183 |
184 | if (!buildRef)
185 | {
186 | return;
187 | }
188 |
189 | for (NSString* buildPhaseKey in [target objectForKey:@"buildPhases"])
190 | {
191 | NSMutableDictionary* buildPhase = [[_project objects] objectForKey:buildPhaseKey];
192 | NSMutableArray* files = [buildPhase objectForKey:@"files"];
193 |
194 | [files removeObjectIdenticalTo:buildRef];
195 | [buildPhase setObject:files forKey:@"files"];
196 | }
197 | [self flagMembersAsDirty];
198 | }
199 |
200 | - (void)removeMembersWithKeys:(NSArray*)keys
201 | {
202 | for (NSString* key in keys)
203 | {
204 | [self removeMemberWithKey:key];
205 | }
206 | }
207 |
208 | - (void)addDependency:(NSString*)key
209 | {
210 | NSDictionary* targetObj = [[_project objects] objectForKey:_key];
211 | NSMutableArray* dependencies = [targetObj valueForKey:@"dependencies"];
212 | // add only if not already there
213 | BOOL found = NO;
214 | for (NSString* dependency in dependencies)
215 | {
216 | if ([dependency isEqualToString:key])
217 | {
218 | found = YES;
219 | break;
220 | }
221 | }
222 | if (!found)
223 | {
224 | [dependencies addObject:key];
225 | }
226 | }
227 |
228 | - (instancetype)duplicateWithTargetName:(NSString*)targetName productName:(NSString*)productName
229 | {
230 |
231 | NSDictionary* targetObj = _project.objects[_key];
232 | NSMutableDictionary* dupTargetObj = [targetObj mutableCopy];
233 |
234 | dupTargetObj[@"name"] = targetName;
235 | dupTargetObj[@"productName"] = productName;
236 |
237 | NSString* buildConfigurationListKey = dupTargetObj[@"buildConfigurationList"];
238 |
239 | void(^visitor)(NSMutableDictionary*) = ^(NSMutableDictionary* buildConfiguration)
240 | {
241 | buildConfiguration[@"buildSettings"][@"PRODUCT_NAME"] = productName;
242 | };
243 |
244 | dupTargetObj[@"buildConfigurationList"] =
245 | [XCBuildConfiguration duplicatedBuildConfigurationListWithKey:buildConfigurationListKey inProject:_project
246 | withBuildConfigurationVisitor:visitor];
247 |
248 | [self duplicateProductReferenceForTargetObject:dupTargetObj withProductName:productName];
249 |
250 | [self duplicateBuildPhasesForTargetObject:dupTargetObj];
251 |
252 | [self addReferenceToProductsGroupForTargetObject:dupTargetObj];
253 |
254 | NSString* dupTargetObjKey = [self addTargetToRootObjectTargets:dupTargetObj];
255 |
256 | [_project dropCache];
257 |
258 | return [[XCTarget alloc] initWithProject:_project key:dupTargetObjKey name:targetName productName:productName
259 | productReference:dupTargetObj[@"productReference"]];
260 | }
261 |
262 | /* ====================================================================================================================================== */
263 | #pragma mark - Overridden Methods
264 |
265 | - (void)setName:(NSString*)name
266 | {
267 | _name = name;
268 | NSDictionary* dictionary = [_project.objects objectForKey:_key];
269 | [dictionary setValue:_name forKey:@"name"];
270 | }
271 |
272 | - (void)setProductName:(NSString*)productName
273 | {
274 | _productName = productName;
275 | NSDictionary* dictionary = [_project.objects objectForKey:_key];
276 | [dictionary setValue:_productName forKey:@"productName"];
277 | }
278 |
279 |
280 |
281 | /* ====================================================================================================================================== */
282 | #pragma mark - Utility Methods
283 |
284 | - (NSString*)description
285 | {
286 | return [NSString stringWithFormat:@"Target: name=%@, files=%@", _name, _members];
287 | }
288 |
289 | /* ====================================================================================================================================== */
290 | #pragma mark - Private Methods
291 |
292 | - (XCSourceFile*)buildFileWithKey:(NSString*)theKey
293 | {
294 | NSDictionary* obj = [[_project objects] valueForKey:theKey];
295 | if (obj)
296 | {
297 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXBuildFileType)
298 | {
299 | return [_project fileWithKey:[obj valueForKey:@"fileRef"]];
300 | }
301 | }
302 | return nil;
303 | }
304 |
305 | - (void)flagMembersAsDirty
306 | {
307 | _members = nil;
308 | }
309 |
310 | - (void)duplicateProductReferenceForTargetObject:(NSMutableDictionary*)dupTargetObj withProductName:(NSString*)productName
311 | {
312 |
313 | NSString* productReferenceKey = dupTargetObj[@"productReference"];
314 | NSMutableDictionary* dupProductReference = [_project.objects[productReferenceKey] mutableCopy];
315 |
316 | NSString* path = dupProductReference[@"path"];
317 | NSString* dupPath = [path stringByDeletingLastPathComponent];
318 | dupPath = [dupPath stringByAppendingPathComponent:productName];
319 | dupPath = [dupPath stringByAppendingPathExtension:@"app"];
320 | dupProductReference[@"path"] = dupPath;
321 |
322 | NSString* dupProductReferenceKey = [[XCKeyBuilder createUnique] build];
323 |
324 | _project.objects[dupProductReferenceKey] = dupProductReference;
325 | dupTargetObj[@"productReference"] = dupProductReferenceKey;
326 | }
327 |
328 | - (void)duplicateBuildPhasesForTargetObject:(NSMutableDictionary*)dupTargetObj
329 | {
330 |
331 | NSMutableArray* buildPhases = [NSMutableArray array];
332 |
333 | for (NSString* buildPhaseKey in dupTargetObj[@"buildPhases"])
334 | {
335 |
336 | NSMutableDictionary* dupBuildPhase = [_project.objects[buildPhaseKey] mutableCopy];
337 | NSMutableArray* dupFiles = [NSMutableArray array];
338 |
339 | for (NSString* fileKey in dupBuildPhase[@"files"])
340 | {
341 |
342 | NSMutableDictionary* dupFile = [_project.objects[fileKey] mutableCopy];
343 | NSString* dupFileKey = [[XCKeyBuilder createUnique] build];
344 |
345 | _project.objects[dupFileKey] = dupFile;
346 | [dupFiles addObject:dupFileKey];
347 | }
348 |
349 | dupBuildPhase[@"files"] = dupFiles;
350 |
351 | NSString* dupBuildPhaseKey = [[XCKeyBuilder createUnique] build];
352 | _project.objects[dupBuildPhaseKey] = dupBuildPhase;
353 | [buildPhases addObject:dupBuildPhaseKey];
354 | }
355 |
356 | dupTargetObj[@"buildPhases"] = buildPhases;
357 | }
358 |
359 | - (void)addReferenceToProductsGroupForTargetObject:(NSMutableDictionary*)dupTargetObj
360 | {
361 |
362 | XCGroup* mainGroup = nil;
363 | NSPredicate* productsPredicate = [NSPredicate predicateWithFormat:@"displayName == 'Products'"];
364 | NSArray* filteredGroups = [_project.groups filteredArrayUsingPredicate:productsPredicate];
365 |
366 | if (filteredGroups.count > 0)
367 | {
368 | mainGroup = filteredGroups[0];
369 | NSMutableArray* children = [_project.objects[mainGroup.key][@"children"] mutableCopy];
370 | [children addObject:dupTargetObj[@"productReference"]];
371 | _project.objects[mainGroup.key][@"children"] = children;
372 | }
373 | }
374 |
375 | - (NSString*)addTargetToRootObjectTargets:(NSMutableDictionary*)dupTargetObj
376 | {
377 | NSString* dupTargetObjKey = [[XCKeyBuilder createUnique] build];
378 |
379 | _project.objects[dupTargetObjKey] = dupTargetObj;
380 |
381 | NSString* rootObjKey = _project.dataStore[@"rootObject"];
382 | NSMutableDictionary* rootObj = [_project.objects[rootObjKey] mutableCopy];
383 | NSMutableArray* rootObjTargets = [rootObj[@"targets"] mutableCopy];
384 | [rootObjTargets addObject:dupTargetObjKey];
385 |
386 | rootObj[@"targets"] = rootObjTargets;
387 | _project.objects[rootObjKey] = rootObj;
388 |
389 | return dupTargetObjKey;
390 | }
391 |
392 | @end
393 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCProject+SubProject.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCSourceFile.h"
15 | #import "XCTarget.h"
16 | #import "Utils/XCKeyBuilder.h"
17 | #import "XCProject+SubProject.h"
18 | #import "XCSubProjectDefinition.h"
19 |
20 |
21 | @implementation XCProject (SubProject)
22 |
23 |
24 | #pragma mark sub-project related public methods
25 |
26 | // returns the key for the reference proxy with the given path (nil if not found)
27 | // does not use keysForProjectObjectsOfType:withIdentifier: because the identifier it uses for
28 | // PBXReferenceProxy is different.
29 | - (NSString*)referenceProxyKeyForName:(NSString*)name
30 | {
31 | __block NSString* result = nil;
32 | [[self objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
33 | {
34 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXReferenceProxyType)
35 | {
36 | if ([[obj valueForKey:@"path"] isEqualTo:name])
37 | {
38 | result = key;
39 | *stop = YES;
40 | }
41 | }
42 | }];
43 | return result;
44 | }
45 |
46 | // returns an array of build products, excluding bundles with extensions other than ".bundle" (which is kind
47 | // of gross, but I didn't see a better way to exclude test bundles without giving them their own XcodeSourceFileType)
48 | - (NSArray*)buildProductsForTargets:(NSString*)xcodeprojKey
49 | {
50 | NSMutableArray* results = [[NSMutableArray alloc] init];
51 | [[self objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
52 | {
53 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXReferenceProxyType)
54 | {
55 | // make sure it belongs to the xcodeproj we're adding
56 | NSString* remoteRef = [obj valueForKey:@"remoteRef"];
57 | NSDictionary* containerProxy = [[self objects] valueForKey:remoteRef];
58 | NSString* containerPortal = [containerProxy valueForKey:@"containerPortal"];
59 | if ([containerPortal isEqualToString:xcodeprojKey])
60 | {
61 | XcodeSourceFileType type = XCSourceFileTypeFromStringRepresentation([obj valueForKey:@"fileType"]);
62 | NSString* path = (NSString*) [obj valueForKey:@"path"];
63 | if (type != Bundle || [[path pathExtension] isEqualToString:@"bundle"])
64 | {
65 | [results addObject:[XCSourceFile sourceFileWithProject:self key:key type:type name:path sourceTree:nil path:nil]];
66 | }
67 | }
68 | }
69 | }];
70 | return results;
71 | }
72 |
73 | // makes PBXContainerItemProxy and PBXTargetDependency objects for the xcodeproj, and adds the dependency key
74 | // to all the specified targets
75 | - (void)addAsTargetDependency:(XCSubProjectDefinition*)xcodeprojDefinition toTargets:(NSArray*)targets
76 | {
77 | for (XCTarget* target in targets)
78 | {
79 | // make a new PBXContainerItemProxy
80 | NSString* key = [[self fileWithName:[xcodeprojDefinition pathRelativeToProjectRoot]] key];
81 | NSString* containerItemProxyKey =
82 | [self makeContainerItemProxyForName:[xcodeprojDefinition name] fileRef:key proxyType:@"1" uniqueName:[target name]];
83 | // make a PBXTargetDependency
84 | NSString* targetDependencyKey =
85 | [self makeTargetDependency:[xcodeprojDefinition name] forContainerItemProxyKey:containerItemProxyKey uniqueName:[target name]];
86 | // add entry in each targets dependencies list
87 | [target addDependency:targetDependencyKey];
88 | }
89 | }
90 |
91 | // returns an array of keys for all project objects (not just files) that match the given criteria. Since this is
92 | // a convenience method intended to save typing elsewhere, each type has its own field to match to rather than each
93 | // matching on name or path as you might expect.
94 | - (NSArray*)keysForProjectObjectsOfType:(XcodeMemberType)memberType withIdentifier:(NSString*)identifier singleton:(BOOL)singleton
95 | required:(BOOL)required
96 | {
97 | __block NSMutableArray* returnValue = [[NSMutableArray alloc] init];
98 | [[self objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
99 | {
100 | if ([[obj valueForKey:@"isa"] asMemberType] == memberType)
101 | {
102 | if (memberType == PBXContainerItemProxyType)
103 | {
104 | if ([[obj valueForKey:@"containerPortal"] isEqualToString:identifier])
105 | {
106 | [returnValue addObject:key];
107 | }
108 | }
109 | else if (memberType == PBXReferenceProxyType)
110 | {
111 | if ([[obj valueForKey:@"remoteRef"] isEqualToString:identifier])
112 | {
113 | [returnValue addObject:key];
114 | }
115 | }
116 | else if (memberType == PBXTargetDependencyType || memberType == PBXGroupType || memberType == PBXVariantGroupType)
117 | {
118 | if ([[obj valueForKey:@"name"] isEqualToString:identifier])
119 | {
120 | [returnValue addObject:key];
121 | }
122 | }
123 | else if (memberType == PBXNativeTargetType)
124 | {
125 | for (NSString* dependencyKey in [obj valueForKey:@"dependencies"])
126 | {
127 | if ([dependencyKey isEqualToString:identifier])
128 | {
129 | [returnValue addObject:key];
130 | }
131 | }
132 | }
133 | else if (memberType == PBXBuildFileType)
134 | {
135 | if ([[obj valueForKey:@"fileRef"] isEqualToString:identifier])
136 | {
137 | [returnValue addObject:key];
138 | }
139 | }
140 | else if (memberType == PBXProjectType)
141 | {
142 | [returnValue addObject:key];
143 | }
144 | else if (memberType == PBXFileReferenceType)
145 | {
146 | if ([[obj valueForKey:@"path"] isEqualToString:identifier])
147 | {
148 | [returnValue addObject:key];
149 | }
150 | }
151 | else if (memberType == PBXFrameworksBuildPhaseType || memberType == PBXResourcesBuildPhaseType)
152 | {
153 | [returnValue addObject:key];
154 | }
155 | else
156 | {
157 | [NSException raise:NSInvalidArgumentException format:@"Unrecognized member type %@",
158 | [NSString stringFromMemberType:memberType]];
159 | }
160 | }
161 | }];
162 | if (singleton && [returnValue count] > 1)
163 | {
164 | [NSException raise:NSGenericException format:@"Searched for one instance of member type %@ with value %@, but found %ld",
165 | [NSString stringFromMemberType:memberType], identifier, [returnValue count]];
166 | }
167 | if (required && [returnValue count] == 0)
168 | {
169 | [NSException raise:NSGenericException format:@"Searched for instances of member type %@ with value %@, but did not find any",
170 | [NSString stringFromMemberType:memberType], identifier];
171 | }
172 | return returnValue;
173 | }
174 |
175 | // returns the dictionary for the PBXProject. Raises an exception if more or less than 1 are found.
176 | - (NSMutableDictionary*)PBXProjectDict
177 | {
178 | NSString* PBXProjectKey;
179 | NSArray* PBXProjectKeys = [self keysForProjectObjectsOfType:PBXProjectType withIdentifier:nil singleton:YES required:YES];
180 | PBXProjectKey = [PBXProjectKeys objectAtIndex:0];
181 | NSMutableDictionary* PBXProjectDict = [[self objects] valueForKey:PBXProjectKey];
182 | return PBXProjectDict;
183 | }
184 |
185 | // returns the key of the PBXContainerItemProxy for the given name and proxy type. nil if not found.
186 | - (NSString*)containerItemProxyKeyForName:(NSString*)name proxyType:(NSString*)proxyType
187 | {
188 | NSMutableArray* results = [[NSMutableArray alloc] init];
189 | [[self objects] enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSDictionary* obj, BOOL* stop)
190 | {
191 | if ([[obj valueForKey:@"isa"] asMemberType] == PBXContainerItemProxyType)
192 | {
193 | NSString* remoteInfo = [obj valueForKey:@"remoteInfo"];
194 | NSString* proxy = [obj valueForKey:@"proxyType"];
195 | if ([remoteInfo isEqualToString:name] && [proxy isEqualToString:proxyType])
196 | {
197 | [results addObject:key];
198 | }
199 | }
200 | }];
201 | if ([results count] > 1)
202 | {
203 | [NSException raise:NSGenericException format:@"Searched for one instance of member type %@ with value %@, but found %ld",
204 | @"PBXContainerItemProxy",
205 | [NSString stringWithFormat:@"%@ and proxyType of %@", name, proxyType],
206 | [results count]];
207 | }
208 | if ([results count] == 0)
209 | {
210 | return nil;
211 | }
212 | return [results objectAtIndex:0];
213 | }
214 |
215 | /* ====================================================================================================================================== */
216 | #pragma mark - Private Methods
217 | #pragma mark sub-project related private methods
218 |
219 | // makes a PBXContainerItemProxy object for a given PBXFileReference object. Replaces pre-existing objects.
220 | - (NSString*)makeContainerItemProxyForName:(NSString*)name fileRef:(NSString*)fileRef proxyType:(NSString*)proxyType
221 | uniqueName:(NSString*)uniqueName
222 | {
223 | NSString* keyName;
224 | if (uniqueName != nil)
225 | {
226 | keyName = [NSString stringWithFormat:@"%@-%@", name, uniqueName];
227 | }
228 | else
229 | {
230 | keyName = name;
231 | }
232 | // remove old if it exists
233 | NSString* existingProxyKey = [self containerItemProxyKeyForName:keyName proxyType:proxyType];
234 | if (existingProxyKey)
235 | {
236 | [[self objects] removeObjectForKey:existingProxyKey];
237 | }
238 | // make new one
239 | NSMutableDictionary* proxy = [NSMutableDictionary dictionary];
240 | [proxy setObject:[NSString stringFromMemberType:PBXContainerItemProxyType] forKey:@"isa"];
241 | [proxy setObject:fileRef forKey:@"containerPortal"];
242 | [proxy setObject:proxyType forKey:@"proxyType"];
243 | // give it a random key - the keys xcode puts here are not in the project file anywhere else
244 | NSString* key = [[XCKeyBuilder forItemNamed:[NSString stringWithFormat:@"%@-junk", keyName]] build];
245 | [proxy setObject:key forKey:@"remoteGlobalIDString"];
246 | [proxy setObject:name forKey:@"remoteInfo"];
247 | // add to project. use proxyType to generate key, so that multiple keys for the same name don't overwrite each other
248 | key = [[XCKeyBuilder forItemNamed:[NSString stringWithFormat:@"%@-containerProxy-%@", keyName, proxyType]] build];
249 | [[self objects] setObject:proxy forKey:key];
250 |
251 | return key;
252 | }
253 |
254 | // makes a PBXReferenceProxy object for a given PBXContainerProxy object. Replaces pre-existing objects.
255 | - (void)makeReferenceProxyForContainerItemProxy:(NSString*)containerItemProxyKey buildProductReference:(NSDictionary*)buildProductReference
256 | {
257 | NSString* path = [buildProductReference valueForKey:@"path"];
258 | // remove old if any exists
259 | NSArray* existingProxyKeys = [self keysForProjectObjectsOfType:PBXReferenceProxyType withIdentifier:path singleton:NO required:NO];
260 | if ([existingProxyKeys count] > 0)
261 | {
262 | for (NSString* existingProxyKey in existingProxyKeys)
263 | {
264 | [[self objects] removeObjectForKey:existingProxyKey];
265 | }
266 | }
267 | // make new one
268 | NSMutableDictionary* proxy = [NSMutableDictionary dictionary];
269 | [proxy setObject:[NSString stringFromMemberType:PBXReferenceProxyType] forKey:@"isa"];
270 | [proxy setObject:[buildProductReference valueForKey:@"explicitFileType"] forKey:@"fileType"];
271 | [proxy setObject:path forKey:@"path"];
272 | [proxy setObject:containerItemProxyKey forKey:@"remoteRef"];
273 | [proxy setObject:[buildProductReference valueForKey:@"sourceTree"] forKey:@"sourceTree"];
274 | // add to project
275 | NSString* key = [[XCKeyBuilder forItemNamed:[NSString stringWithFormat:@"%@-referenceProxy", path]] build];
276 | [[self objects] setObject:proxy forKey:key];
277 | }
278 |
279 | // makes a PBXTargetDependency object for a given PBXContainerItemProxy. Replaces pre-existing objects.
280 | - (NSString*)makeTargetDependency:(NSString*)name forContainerItemProxyKey:(NSString*)containerItemProxyKey uniqueName:(NSString*)uniqueName
281 | {
282 | NSString* keyName;
283 | if (uniqueName != nil)
284 | {
285 | keyName = [NSString stringWithFormat:@"%@-%@", name, uniqueName];
286 | }
287 | else
288 | {
289 | keyName = name;
290 | }
291 | // remove old if it exists
292 | NSArray* existingDependencyKeys =
293 | [self keysForProjectObjectsOfType:PBXTargetDependencyType withIdentifier:keyName singleton:NO required:NO];
294 | if ([existingDependencyKeys count] > 0)
295 | {
296 | for (NSString* existingDependencyKey in existingDependencyKeys)
297 | {
298 | [[self objects] removeObjectForKey:existingDependencyKey];
299 | }
300 | }
301 | // make new one
302 | NSMutableDictionary* targetDependency = [NSMutableDictionary dictionary];
303 | [targetDependency setObject:[NSString stringFromMemberType:PBXTargetDependencyType] forKey:@"isa"];
304 | [targetDependency setObject:name forKey:@"name"];
305 | [targetDependency setObject:containerItemProxyKey forKey:@"targetProxy"];
306 | NSString* targetDependencyKey = [[XCKeyBuilder forItemNamed:[NSString stringWithFormat:@"%@-targetProxy", keyName]] build];
307 | [[self objects] setObject:targetDependency forKey:targetDependencyKey];
308 | return targetDependencyKey;
309 | }
310 |
311 | // make a PBXContainerItemProxy and PBXReferenceProxy for each target in the subProject
312 | - (void)addProxies:(XCSubProjectDefinition*)xcodeproj
313 | {
314 | NSString* fileRef = [[self fileWithName:[xcodeproj pathRelativeToProjectRoot]] key];
315 | for (NSDictionary* target in [xcodeproj.subProject targets])
316 | {
317 | NSString* containerItemProxyKey =
318 | [self makeContainerItemProxyForName:[target valueForKey:@"name"] fileRef:fileRef proxyType:@"2" uniqueName:nil];
319 | NSString* productFileReferenceKey = [target valueForKey:@"productReference"];
320 | NSDictionary* productFileReference = [[xcodeproj.subProject objects] valueForKey:productFileReferenceKey];
321 | [self makeReferenceProxyForContainerItemProxy:containerItemProxyKey buildProductReference:productFileReference];
322 | }
323 | }
324 |
325 | // remove the PBXContainerItemProxy and PBXReferenceProxy objects for the given object key (which is the PBXFilereference
326 | // for the xcodeproj file)
327 | - (void)removeProxies:(NSString*)xcodeprojKey
328 | {
329 | NSMutableArray* keysToDelete = [NSMutableArray array];
330 | // use the xcodeproj's PBXFileReference key to get the PBXContainerItemProxy keys
331 | NSArray* containerItemProxyKeys =
332 | [self keysForProjectObjectsOfType:PBXContainerItemProxyType withIdentifier:xcodeprojKey singleton:NO required:YES];
333 | // use the PBXContainerItemProxy keys to get the PBXReferenceProxy keys
334 | for (NSString* key in containerItemProxyKeys)
335 | {
336 | [keysToDelete addObjectsFromArray:[self keysForProjectObjectsOfType:PBXReferenceProxyType withIdentifier:key singleton:NO
337 | required:NO]];
338 | [keysToDelete addObject:key];
339 | }
340 | // remove all objects located above
341 | [keysToDelete enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop)
342 | {
343 | [[self objects] removeObjectForKey:obj];
344 | }];
345 | }
346 |
347 | // returns the Products group key for the given PBXFileReference key, nil if not found.
348 | - (NSString*)productsGroupKeyForKey:(NSString*)key
349 | {
350 | NSMutableArray* projectReferences = [[self PBXProjectDict] valueForKey:@"projectReferences"];
351 | NSString* productsGroupKey = nil;
352 | for (NSDictionary* projectRef in projectReferences)
353 | {
354 | if ([[projectRef valueForKey:@"ProjectRef"] isEqualToString:key])
355 | {
356 | // it's an error if we find more than one
357 | if (productsGroupKey != nil)
358 | {
359 | [NSException raise:NSGenericException format:@"Found more than one project reference for key %@", key];
360 | }
361 | productsGroupKey = [projectRef valueForKey:@"ProductGroup"];
362 | }
363 | }
364 | return productsGroupKey;
365 | }
366 |
367 | // removes a file reference from the projectReferences array in PBXProject (removing the array itself if this action
368 | // leaves it empty).
369 | - (void)removeFromProjectReferences:(NSString*)key forProductsGroup:(NSString*)productsGroupKey
370 | {
371 | NSMutableArray* projectReferences = [[self PBXProjectDict] valueForKey:@"projectReferences"];
372 | // remove entry from PBXProject's projectReferences
373 | NSMutableArray* referencesToRemove = [NSMutableArray array];
374 | for (NSDictionary* projectRef in projectReferences)
375 | {
376 | if ([[projectRef valueForKey:@"ProjectRef"] isEqualToString:key])
377 | {
378 | [referencesToRemove addObject:projectRef];
379 | }
380 | }
381 | for (NSDictionary* projectRef in referencesToRemove)
382 | {
383 | [projectReferences removeObject:projectRef];
384 | }
385 | // if that was the last project reference, remove the array from the project
386 | if ([projectReferences count] == 0)
387 | {
388 | [[self PBXProjectDict] removeObjectForKey:@"projectReferences"];
389 | }
390 | }
391 |
392 | // removes a specific xcodeproj file from any targets (by name). It's not an error if no entries are found,
393 | // because we support adding a project file without adding it to any targets.
394 | - (void)removeTargetDependencies:(NSString*)name
395 | {
396 | // get the key for the PBXTargetDependency with name = xcodeproj file name (without extension)
397 | NSArray* targetDependencyKeys = [self keysForProjectObjectsOfType:PBXTargetDependencyType withIdentifier:name singleton:NO required:NO];
398 | // we might not find any if the project wasn't added to targets in the first place
399 | if ([targetDependencyKeys count] == 0)
400 | {
401 | return;
402 | }
403 | NSString* targetDependencyKey = [targetDependencyKeys objectAtIndex:0];
404 | // use the key for the PBXTargetDependency to get the key for any PBXNativeTargets that depend on it
405 | NSArray* nativeTargetKeys =
406 | [self keysForProjectObjectsOfType:PBXNativeTargetType withIdentifier:targetDependencyKey singleton:NO required:NO];
407 | // remove the key for the PBXTargetDependency from the PBXNativeTarget's dependencies arrays (leave in place even if empty)
408 | for (NSString* nativeTargetKey in nativeTargetKeys)
409 | {
410 | NSMutableDictionary* nativeTarget = [[self objects] objectForKey:nativeTargetKey];
411 | NSMutableArray* dependencies = [nativeTarget valueForKey:@"dependencies"];
412 | [dependencies removeObject:targetDependencyKey];
413 | [nativeTarget setObject:dependencies forKey:@"dependencies"];
414 | }
415 | // remove the PBXTargetDependency
416 | [[self objects] removeObjectForKey:targetDependencyKey];
417 | }
418 |
419 | @end
--------------------------------------------------------------------------------
/XLocation/XLWindow.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 |
61 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
119 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
--------------------------------------------------------------------------------
/Dependencies/XcodeEditor/XCGroup.m:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // JASPER BLUES
4 | // Copyright 2012 Jasper Blues
5 | // All Rights Reserved.
6 | //
7 | // NOTICE: Jasper Blues permits you to use, modify, and distribute this file
8 | // in accordance with the terms of the license agreement accompanying it.
9 | //
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 |
13 |
14 | #import "XCFrameworkDefinition.h"
15 | #import "XCTarget.h"
16 | #import "XCFileOperationQueue.h"
17 | #import "XCXibDefinition.h"
18 | #import "XCSourceFile.h"
19 | #import "XCGroup.h"
20 | #import "XCProject.h"
21 | #import "XCClassDefinition.h"
22 | #import "Utils/XCKeyBuilder.h"
23 | #import "XCSourceFileDefinition.h"
24 | #import "XCSubProjectDefinition.h"
25 | #import "XCProject+SubProject.h"
26 |
27 |
28 | @implementation XCGroup
29 |
30 |
31 | /* ====================================================================================================================================== */
32 | #pragma mark - Class Methods
33 |
34 | + (XCGroup*)groupWithProject:(XCProject*)project key:(NSString*)key alias:(NSString*)alias path:(NSString*)path children:(NSArray*)children
35 | {
36 |
37 | return [[XCGroup alloc] initWithProject:project key:key alias:alias path:path children:children];
38 | }
39 |
40 | /* ====================================================================================================================================== */
41 | #pragma mark - Initialization & Destruction
42 |
43 | - (id)initWithProject:(XCProject*)project key:(NSString*)key alias:(NSString*)alias path:(NSString*)path children:(NSArray*)children
44 | {
45 | self = [super init];
46 | if (self)
47 | {
48 | _project = project;
49 | _fileOperationQueue = [_project fileOperationQueue];
50 | _key = [key copy];
51 | _alias = [alias copy];
52 | _pathRelativeToParent = [path copy];
53 |
54 | _children = [children mutableCopy];
55 | if (!_children)
56 | {
57 | _children = [[NSMutableArray alloc] init];
58 | }
59 | }
60 | return self;
61 | }
62 |
63 | /* ====================================================================================================================================== */
64 | #pragma mark - Interface Methods
65 |
66 | #pragma mark Parent group
67 |
68 | - (void)removeFromParentGroup
69 | {
70 | [self removeFromParentDeletingChildren:NO];
71 | }
72 |
73 |
74 | - (void)removeFromParentDeletingChildren:(BOOL)deleteChildren
75 | {
76 | if (deleteChildren)
77 | {
78 | [_fileOperationQueue queueDeletion:[self pathRelativeToProjectRoot]];
79 | }
80 | NSDictionary* dictionary = [[_project objects] objectForKey:_key];
81 | NSLog(@"Here's the dictionary: %@", dictionary);
82 |
83 | [[_project objects] removeObjectForKey:_key];
84 |
85 | dictionary = [[_project objects] objectForKey:_key];
86 | NSLog(@"Here's the dictionary: %@", dictionary);
87 |
88 | for (XCTarget* target in [_project targets])
89 | {
90 | [target removeMembersWithKeys:[self recursiveMembers]];
91 | }
92 | NSLog(@"Done!!!");
93 | }
94 |
95 | - (XCGroup*)parentGroup
96 | {
97 | return [_project groupForGroupMemberWithKey:_key];
98 | }
99 |
100 | - (BOOL)isRootGroup
101 | {
102 | return [self pathRelativeToParent] == nil && [self displayName] == nil;
103 | }
104 |
105 |
106 | /* ================================================================================================================== */
107 | #pragma mark Adding children
108 |
109 |
110 | - (void)addClass:(XCClassDefinition*)classDefinition
111 | {
112 |
113 | if ([classDefinition header])
114 | {
115 | [self makeGroupMemberWithName:[classDefinition headerFileName] contents:[classDefinition header] type:SourceCodeHeader
116 | fileOperationStyle:[classDefinition fileOperationType]];
117 | }
118 |
119 | if ([classDefinition isObjectiveC])
120 | {
121 | [self makeGroupMemberWithName:[classDefinition sourceFileName] contents:[classDefinition source] type:SourceCodeObjC
122 | fileOperationStyle:[classDefinition fileOperationType]];
123 | }
124 | else if ([classDefinition isObjectiveCPlusPlus])
125 | {
126 | [self makeGroupMemberWithName:[classDefinition sourceFileName] contents:[classDefinition source] type:SourceCodeObjCPlusPlus
127 | fileOperationStyle:[classDefinition fileOperationType]];
128 | }
129 |
130 | [[_project objects] setObject:[self asDictionary] forKey:_key];
131 | }
132 |
133 |
134 | - (void)addClass:(XCClassDefinition*)classDefinition toTargets:(NSArray*)targets
135 | {
136 | [self addClass:classDefinition];
137 | XCSourceFile* sourceFile = [_project fileWithName:[classDefinition sourceFileName]];
138 | [self addSourceFile:sourceFile toTargets:targets];
139 | }
140 |
141 | - (void)addFramework:(XCFrameworkDefinition*)frameworkDefinition
142 | {
143 | if (([self memberWithDisplayName:[frameworkDefinition name]]) == nil)
144 | {
145 | NSDictionary* fileReference;
146 | if ([frameworkDefinition copyToDestination])
147 | {
148 | fileReference = [self makeFileReferenceWithPath:[frameworkDefinition name] name:nil type:Framework];
149 | BOOL copyFramework = NO;
150 | if ([frameworkDefinition fileOperationType] == XCFileOperationTypeOverwrite)
151 | {
152 | copyFramework = YES;
153 | }
154 | else if ([frameworkDefinition fileOperationType] == XCFileOperationTypeAcceptExisting)
155 | {
156 | NSString* frameworkName = [[frameworkDefinition filePath] lastPathComponent];
157 | if (![_fileOperationQueue fileWithName:frameworkName existsInProjectDirectory:[self pathRelativeToProjectRoot]])
158 | {
159 | copyFramework = YES;
160 | }
161 |
162 | }
163 | if (copyFramework)
164 | {
165 | [_fileOperationQueue queueFrameworkWithFilePath:[frameworkDefinition filePath]
166 | inDirectory:[self pathRelativeToProjectRoot]];
167 | }
168 | }
169 | else
170 | {
171 | NSString* path = [frameworkDefinition filePath];
172 | NSString* name = [frameworkDefinition name];
173 | fileReference = [self makeFileReferenceWithPath:path name:name type:Framework];
174 | }
175 | NSString* frameworkKey = [[XCKeyBuilder forItemNamed:[frameworkDefinition name]] build];
176 | [[_project objects] setObject:fileReference forKey:frameworkKey];
177 | [self addMemberWithKey:frameworkKey];
178 | }
179 | [[_project objects] setObject:[self asDictionary] forKey:_key];
180 | }
181 |
182 |
183 | - (void)addFramework:(XCFrameworkDefinition*)frameworkDefinition toTargets:(NSArray*)targets
184 | {
185 | [self addFramework:frameworkDefinition];
186 | XCSourceFile* frameworkSourceRef = (XCSourceFile*) [self memberWithDisplayName:[frameworkDefinition name]];
187 | [self addSourceFile:frameworkSourceRef toTargets:targets];
188 | }
189 |
190 | - (XCGroup*)addGroupWithPath:(NSString*)path
191 | {
192 | NSString* groupKeyPath = self.pathRelativeToProjectRoot ? [self.pathRelativeToProjectRoot stringByAppendingPathComponent:path] : path;
193 |
194 | NSString* groupKey = [[XCKeyBuilder forItemNamed:groupKeyPath] build];
195 |
196 | NSArray* members = [self members];
197 | for (id groupMember in members)
198 | {
199 | if ([groupMember groupMemberType] == PBXGroupType || [groupMember groupMemberType] == PBXVariantGroupType)
200 | {
201 |
202 | if ([[[groupMember pathRelativeToProjectRoot] lastPathComponent] isEqualToString:path] ||
203 | [[groupMember displayName] isEqualToString:path] || [[groupMember key] isEqualToString:groupKey])
204 | {
205 | return nil;
206 | }
207 | }
208 | }
209 |
210 | XCGroup* group = [[XCGroup alloc] initWithProject:_project key:groupKey alias:nil path:path children:nil];
211 | NSDictionary* groupDict = [group asDictionary];
212 |
213 | [[_project objects] setObject:groupDict forKey:groupKey];
214 | [_fileOperationQueue queueDirectory:path inDirectory:[self pathRelativeToProjectRoot]];
215 | [self addMemberWithKey:groupKey];
216 |
217 | NSDictionary* dict = [self asDictionary];
218 | [[_project objects] setObject:dict forKey:_key];
219 |
220 | return group;
221 | }
222 |
223 | - (void)addSourceFile:(XCSourceFileDefinition*)sourceFileDefinition
224 | {
225 | [self makeGroupMemberWithName:[sourceFileDefinition sourceFileName] contents:[sourceFileDefinition data]
226 | type:[sourceFileDefinition type] fileOperationStyle:[sourceFileDefinition fileOperationType]];
227 | [[_project objects] setObject:[self asDictionary] forKey:_key];
228 | }
229 |
230 | - (void)addXib:(XCXibDefinition*)xibDefinition
231 | {
232 | [self makeGroupMemberWithName:[xibDefinition xibFileName] contents:[xibDefinition content] type:XibFile
233 | fileOperationStyle:[xibDefinition fileOperationType]];
234 | [[_project objects] setObject:[self asDictionary] forKey:_key];
235 | }
236 |
237 | - (void)addXib:(XCXibDefinition*)xibDefinition toTargets:(NSArray*)targets
238 | {
239 | [self addXib:xibDefinition];
240 | XCSourceFile* sourceFile = [_project fileWithName:[xibDefinition xibFileName]];
241 | [self addSourceFile:sourceFile toTargets:targets];
242 | }
243 |
244 |
245 | // adds an xcodeproj as a subproject of the current project.
246 | - (void)addSubProject:(XCSubProjectDefinition*)projectDefinition
247 | {
248 | // set up path to the xcodeproj file as Xcode sees it - path to top level of project + group path if any
249 | [projectDefinition initFullProjectPath:_project.filePath groupPath:[self pathRelativeToParent]];
250 |
251 | // create PBXFileReference for xcodeproj file and add to PBXGroup for the current group
252 | // (will retrieve existing if already there)
253 | [self makeGroupMemberWithName:[projectDefinition projectFileName] path:[projectDefinition pathRelativeToProjectRoot] type:XcodeProject
254 | fileOperationStyle:[projectDefinition fileOperationType]];
255 | [[_project objects] setObject:[self asDictionary] forKey:_key];
256 |
257 | // create PBXContainerItemProxies and PBXReferenceProxies
258 | [_project addProxies:projectDefinition];
259 |
260 | // add projectReferences key to PBXProject
261 | [self addProductsGroupToProject:projectDefinition];
262 | }
263 |
264 | // adds an xcodeproj as a subproject of the current project, and also adds all build products except for test bundle(s)
265 | // to targets.
266 | - (void)addSubProject:(XCSubProjectDefinition*)projectDefinition toTargets:(NSArray*)targets
267 | {
268 | [self addSubProject:projectDefinition];
269 |
270 | // add subproject's build products to targets (does not add the subproject's test bundle)
271 | NSArray* buildProductFiles = [_project buildProductsForTargets:[projectDefinition projectKey]];
272 | for (XCSourceFile* file in buildProductFiles)
273 | {
274 | [self addSourceFile:file toTargets:targets];
275 | }
276 | // add main target of subproject as target dependency to main target of project
277 | [_project addAsTargetDependency:projectDefinition toTargets:targets];
278 | }
279 |
280 | // removes an xcodeproj from the current project.
281 | - (void)removeSubProject:(XCSubProjectDefinition*)projectDefinition
282 | {
283 | if (projectDefinition == nil)
284 | {
285 | return;
286 | }
287 |
288 | // set up path to the xcodeproj file as Xcode sees it - path to top level of project + group path if any
289 | [projectDefinition initFullProjectPath:_project.filePath groupPath:[self pathRelativeToParent]];
290 |
291 | NSString* xcodeprojKey = [projectDefinition projectKey];
292 |
293 | // Remove from group and remove PBXFileReference
294 | [self removeGroupMemberWithKey:xcodeprojKey];
295 |
296 | // remove PBXContainerItemProxies and PBXReferenceProxies
297 | [_project removeProxies:xcodeprojKey];
298 |
299 | // get the key for the Products group
300 | NSString* productsGroupKey = [_project productsGroupKeyForKey:xcodeprojKey];
301 |
302 | // remove from the ProjectReferences array of PBXProject
303 | [_project removeFromProjectReferences:xcodeprojKey forProductsGroup:productsGroupKey];
304 |
305 | // remove PDXBuildFile entries
306 | [self removeProductsGroupFromProject:productsGroupKey];
307 |
308 | // remove Products group
309 | [[_project objects] removeObjectForKey:productsGroupKey];
310 |
311 | // remove from all targets
312 | [_project removeTargetDependencies:[projectDefinition name]];
313 | }
314 |
315 | - (void)removeSubProject:(XCSubProjectDefinition*)projectDefinition fromTargets:(NSArray*)targets
316 | {
317 | if (projectDefinition == nil)
318 | {
319 | return;
320 | }
321 |
322 | // set up path to the xcodeproj file as Xcode sees it - path to top level of project + group path if any
323 | [projectDefinition initFullProjectPath:_project.filePath groupPath:[self pathRelativeToParent]];
324 |
325 | NSString* xcodeprojKey = [projectDefinition projectKey];
326 |
327 | // Remove PBXBundleFile entries and corresponding inclusion in PBXFrameworksBuildPhase and PBXResourcesBuidPhase
328 | NSString* productsGroupKey = [_project productsGroupKeyForKey:xcodeprojKey];
329 | [self removeProductsGroupFromProject:productsGroupKey];
330 |
331 | // Remove the PBXContainerItemProxy for this xcodeproj with proxyType 1
332 | NSString* containerItemProxyKey = [_project containerItemProxyKeyForName:[projectDefinition pathRelativeToProjectRoot] proxyType:@"1"];
333 | if (containerItemProxyKey != nil)
334 | {
335 | [[_project objects] removeObjectForKey:containerItemProxyKey];
336 | }
337 |
338 | // Remove PBXTargetDependency and entry in PBXNativeTarget
339 | [_project removeTargetDependencies:[projectDefinition name]];
340 | }
341 |
342 | /* ====================================================================================================================================== */
343 | #pragma mark Members
344 |
345 | - (NSArray*)members
346 | {
347 | if (_members == nil)
348 | {
349 | _members = [[NSMutableArray alloc] init];
350 | for (NSString* childKey in _children)
351 | {
352 | XcodeMemberType type = [self typeForKey:childKey];
353 |
354 | @autoreleasepool
355 | {
356 | if (type == PBXGroupType || type == PBXVariantGroupType)
357 | {
358 | [_members addObject:[_project groupWithKey:childKey]];
359 | }
360 | else if (type == PBXFileReferenceType)
361 | {
362 | [_members addObject:[_project fileWithKey:childKey]];
363 | }
364 | }
365 | }
366 | }
367 | return _members;
368 | }
369 |
370 | - (NSArray*)recursiveMembers
371 | {
372 | NSMutableArray* recursiveMembers = [NSMutableArray array];
373 | for (NSString* childKey in _children)
374 | {
375 | XcodeMemberType type = [self typeForKey:childKey];
376 | if (type == PBXGroupType || type == PBXVariantGroupType)
377 | {
378 | XCGroup* group = [_project groupWithKey:childKey];
379 | NSArray* groupChildren = [group recursiveMembers];
380 | [recursiveMembers addObjectsFromArray:groupChildren];
381 | }
382 | else if (type == PBXFileReferenceType)
383 | {
384 | [recursiveMembers addObject:childKey];
385 | }
386 | }
387 | [recursiveMembers addObject:_key];
388 | return [recursiveMembers arrayByAddingObjectsFromArray:recursiveMembers];
389 | }
390 |
391 | - (NSArray*)buildFileKeys
392 | {
393 |
394 | NSMutableArray* arrayOfBuildFileKeys = [NSMutableArray array];
395 | for (id groupMember in [self members])
396 | {
397 |
398 | if ([groupMember groupMemberType] == PBXGroupType || [groupMember groupMemberType] == PBXVariantGroupType)
399 | {
400 | XCGroup* group = (XCGroup*) groupMember;
401 | [arrayOfBuildFileKeys addObjectsFromArray:[group buildFileKeys]];
402 | }
403 | else if ([groupMember groupMemberType] == PBXFileReferenceType)
404 | {
405 | [arrayOfBuildFileKeys addObject:[groupMember key]];
406 | }
407 | }
408 | return arrayOfBuildFileKeys;
409 | }
410 |
411 | - (id )memberWithKey:(NSString*)key
412 | {
413 | id groupMember = nil;
414 |
415 | if ([_children containsObject:key])
416 | {
417 | XcodeMemberType type = [self typeForKey:key];
418 | if (type == PBXGroupType || type == PBXVariantGroupType)
419 | {
420 | groupMember = [_project groupWithKey:key];
421 | }
422 | else if (type == PBXFileReferenceType)
423 | {
424 | groupMember = [_project fileWithKey:key];
425 | }
426 | }
427 | return groupMember;
428 | }
429 |
430 | - (id )memberWithDisplayName:(NSString*)name
431 | {
432 | for (id member in [self members])
433 | {
434 | if ([[member displayName] isEqualToString:name])
435 | {
436 | return member;
437 | }
438 | }
439 | return nil;
440 | }
441 |
442 | /* ====================================================================================================================================== */
443 | #pragma mark - Protocol Methods
444 |
445 | - (XcodeMemberType)groupMemberType
446 | {
447 | return [self typeForKey:self.key];
448 | }
449 |
450 | - (NSString*)displayName
451 | {
452 | if (_alias)
453 | {
454 | return _alias;
455 | }
456 | return [_pathRelativeToParent lastPathComponent];
457 | }
458 |
459 | - (NSString*)pathRelativeToProjectRoot
460 | {
461 | if (_pathRelativeToProjectRoot == nil)
462 | {
463 | NSMutableArray* pathComponents = [[NSMutableArray alloc] init];
464 | XCGroup* group = nil;
465 | NSString* key = [_key copy];
466 |
467 | while ((group = [_project groupForGroupMemberWithKey:key]) != nil && !([group pathRelativeToParent] == nil))
468 | {
469 | [pathComponents addObject:[group pathRelativeToParent]];
470 | id old = key;
471 | key = [[group key] copy];
472 | }
473 |
474 | NSMutableString* fullPath = [[NSMutableString alloc] init];
475 | for (NSInteger i = (NSInteger) [pathComponents count] - 1; i >= 0; i--)
476 | {
477 | [fullPath appendFormat:@"%@/", [pathComponents objectAtIndex:i]];
478 | }
479 | _pathRelativeToProjectRoot = [[fullPath stringByAppendingPathComponent:_pathRelativeToParent] copy];
480 | }
481 | return _pathRelativeToProjectRoot;
482 | }
483 |
484 | /* ====================================================================================================================================== */
485 | #pragma mark - Utility Methods
486 |
487 | - (NSString*)description
488 | {
489 | return [NSString stringWithFormat:@"Group: displayName = %@, key=%@", [self displayName], _key];
490 | }
491 |
492 | /* ====================================================================================================================================== */
493 | #pragma mark - Private Methods
494 |
495 | #pragma mark Private
496 |
497 | - (void)addMemberWithKey:(NSString*)key
498 | {
499 |
500 | for (NSString* childKey in _children)
501 | {
502 | if ([childKey isEqualToString:key])
503 | {
504 | [self flagMembersAsDirty];
505 | return;
506 | }
507 | }
508 | [_children addObject:key];
509 | [self flagMembersAsDirty];
510 | }
511 |
512 | - (void)flagMembersAsDirty
513 | {
514 | _members = nil;
515 | }
516 |
517 | /* ====================================================================================================================================== */
518 |
519 | - (void)makeGroupMemberWithName:(NSString*)name contents:(id)contents type:(XcodeSourceFileType)type
520 | fileOperationStyle:(XCFileOperationType)fileOperationStyle
521 | {
522 |
523 | NSString* filePath;
524 | XCSourceFile* currentSourceFile = (XCSourceFile*) [self memberWithDisplayName:name];
525 | if ((currentSourceFile) == nil)
526 | {
527 | NSDictionary* reference = [self makeFileReferenceWithPath:name name:nil type:type];
528 | NSString* fileKey = [[XCKeyBuilder forItemNamed:name] build];
529 | [[_project objects] setObject:reference forKey:fileKey];
530 | [self addMemberWithKey:fileKey];
531 | filePath = [self pathRelativeToProjectRoot];
532 | }
533 | else
534 | {
535 | filePath = [[currentSourceFile pathRelativeToProjectRoot] stringByDeletingLastPathComponent];
536 | }
537 |
538 | BOOL writeFile = NO;
539 | if (fileOperationStyle == XCFileOperationTypeOverwrite)
540 | {
541 | writeFile = YES;
542 | [_fileOperationQueue fileWithName:name existsInProjectDirectory:filePath];
543 | }
544 | else if (fileOperationStyle == XCFileOperationTypeAcceptExisting &&
545 | ![_fileOperationQueue fileWithName:name existsInProjectDirectory:filePath])
546 | {
547 | writeFile = YES;
548 | }
549 | if (writeFile)
550 | {
551 | if ([contents isKindOfClass:[NSString class]])
552 | {
553 | [_fileOperationQueue queueTextFile:name inDirectory:filePath withContents:contents];
554 | }
555 | else
556 | {
557 | [_fileOperationQueue queueDataFile:name inDirectory:filePath withContents:contents];
558 | }
559 | }
560 | }
561 |
562 | /* ====================================================================================================================================== */
563 |
564 | #pragma mark Xcodeproj methods
565 |
566 | // creates PBXFileReference and adds to group if not already there; returns key for file reference. Locates
567 | // member via path rather than name, because that is how subprojects are stored by Xcode
568 | - (void)makeGroupMemberWithName:(NSString*)name path:(NSString*)path type:(XcodeSourceFileType)type
569 | fileOperationStyle:(XCFileOperationType)fileOperationStyle
570 | {
571 | XCSourceFile* currentSourceFile = (XCSourceFile*) [self memberWithDisplayName:name];
572 | if ((currentSourceFile) == nil)
573 | {
574 | NSDictionary* reference = [self makeFileReferenceWithPath:path name:name type:type];
575 | NSString* fileKey = [[XCKeyBuilder forItemNamed:name] build];
576 | [[_project objects] setObject:reference forKey:fileKey];
577 | [self addMemberWithKey:fileKey];
578 | }
579 | }
580 |
581 | // makes a new group called Products and returns its key
582 | - (NSString*)makeProductsGroup:(XCSubProjectDefinition*)xcodeprojDefinition
583 | {
584 | NSMutableArray* children = [NSMutableArray array];
585 | NSString* uniquer = @"";
586 | for (NSString* productName in [xcodeprojDefinition buildProductNames])
587 | {
588 | [children addObject:[_project referenceProxyKeyForName:productName]];
589 | uniquer = [uniquer stringByAppendingString:productName];
590 | }
591 | NSString* productKey = [[XCKeyBuilder forItemNamed:[NSString stringWithFormat:@"%@-Products", uniquer]] build];
592 | XCGroup* productsGroup = [XCGroup groupWithProject:_project key:productKey alias:@"Products" path:nil children:children];
593 | [[_project objects] setObject:[productsGroup asDictionary] forKey:productKey];
594 | return productKey;
595 | }
596 |
597 | // makes a new Products group (by calling the method above), makes a new projectReferences array for it and
598 | // then adds it to the PBXProject object
599 | - (void)addProductsGroupToProject:(XCSubProjectDefinition*)xcodeprojDefinition
600 | {
601 | NSString* productKey = [self makeProductsGroup:xcodeprojDefinition];
602 |
603 | NSMutableDictionary* PBXProjectDict = [_project PBXProjectDict];
604 | NSMutableArray* projectReferences = [PBXProjectDict valueForKey:@"projectReferences"];
605 |
606 | NSMutableDictionary* newProjectReference = [NSMutableDictionary dictionary];
607 | [newProjectReference setObject:productKey forKey:@"ProductGroup"];
608 | NSString* projectFileKey = [[_project fileWithName:[xcodeprojDefinition pathRelativeToProjectRoot]] key];
609 | [newProjectReference setObject:projectFileKey forKey:@"ProjectRef"];
610 |
611 | if (projectReferences == nil)
612 | {
613 | projectReferences = [NSMutableArray array];
614 | }
615 | [projectReferences addObject:newProjectReference];
616 | [PBXProjectDict setObject:projectReferences forKey:@"projectReferences"];
617 | }
618 |
619 | // removes PBXFileReference from group and project
620 | - (void)removeGroupMemberWithKey:(NSString*)key
621 | {
622 | NSMutableArray* children = [self valueForKey:@"children"];
623 | [children removeObject:key];
624 | [[_project objects] setObject:[self asDictionary] forKey:_key];
625 | // remove PBXFileReference
626 | [[_project objects] removeObjectForKey:key];
627 | }
628 |
629 | // removes the given key from the files arrays of the given section, if found (intended to be used with
630 | // PBXFrameworksBuildPhase and PBXResourcesBuildPhase)
631 | // they are not required because we are currently not adding these entries; Xcode is doing it for us. The existing
632 | // code for adding to a target doesn't do it, and I didn't add it since Xcode will take care of it for me and I was
633 | // avoiding modifying existing code as much as possible)
634 | - (void)removeBuildPhaseFileKey:(NSString*)key forType:(XcodeMemberType)memberType
635 | {
636 | NSArray* buildPhases = [_project keysForProjectObjectsOfType:memberType withIdentifier:nil singleton:NO required:NO];
637 | for (NSString* buildPhaseKey in buildPhases)
638 | {
639 | NSDictionary* buildPhaseDict = [[_project objects] valueForKey:buildPhaseKey];
640 | NSMutableArray* fileKeys = [buildPhaseDict valueForKey:@"files"];
641 | for (NSString* fileKey in fileKeys)
642 | {
643 | if ([fileKey isEqualToString:key])
644 | {
645 | [fileKeys removeObject:fileKey];
646 | }
647 | }
648 | }
649 | }
650 |
651 | // removes entries from PBXBuildFiles, PBXFrameworksBuildPhase and PBXResourcesBuildPhase
652 | - (void)removeProductsGroupFromProject:(NSString*)key
653 | {
654 | // remove product group's build products from PDXBuildFiles
655 | NSDictionary* productsGroup = [[_project objects] objectForKey:key];
656 | for (NSString* childKey in [productsGroup valueForKey:@"children"])
657 | {
658 | NSArray* buildFileKeys = [_project keysForProjectObjectsOfType:PBXBuildFileType withIdentifier:childKey singleton:NO required:NO];
659 | // could be zero - we didn't add the test bundle as a build product
660 | if ([buildFileKeys count] == 1)
661 | {
662 | NSString* buildFileKey = [buildFileKeys objectAtIndex:0];
663 | [[_project objects] removeObjectForKey:buildFileKey];
664 | [self removeBuildPhaseFileKey:buildFileKey forType:PBXFrameworksBuildPhaseType];
665 | [self removeBuildPhaseFileKey:buildFileKey forType:PBXResourcesBuildPhaseType];
666 | }
667 | }
668 | }
669 |
670 | /* ====================================================================================================================================== */
671 |
672 | #pragma mark Dictionary Representations
673 |
674 | - (NSDictionary*)makeFileReferenceWithPath:(NSString*)path name:(NSString*)name type:(XcodeSourceFileType)type
675 | {
676 | NSMutableDictionary* reference = [NSMutableDictionary dictionary];
677 | [reference setObject:[NSString stringFromMemberType:PBXFileReferenceType] forKey:@"isa"];
678 | [reference setObject:@"4" forKey:@"fileEncoding"];
679 | [reference setObject:NSStringFromXCSourceFileType(type) forKey:@"lastKnownFileType"];
680 | if (name != nil)
681 | {
682 | [reference setObject:[name lastPathComponent] forKey:@"name"];
683 | }
684 | if (path != nil)
685 | {
686 | [reference setObject:path forKey:@"path"];
687 | }
688 | [reference setObject:@"" forKey:@"sourceTree"];
689 | return reference;
690 | }
691 |
692 |
693 | - (NSDictionary*)asDictionary
694 | {
695 | NSMutableDictionary* groupData = [NSMutableDictionary dictionary];
696 | [groupData setObject:[NSString stringFromMemberType:PBXGroupType] forKey:@"isa"];
697 | [groupData setObject:@"" forKey:@"sourceTree"];
698 |
699 | if (_alias != nil)
700 | {
701 | [groupData setObject:_alias forKey:@"name"];
702 | }
703 |
704 | if (_pathRelativeToParent)
705 | {
706 | [groupData setObject:_pathRelativeToParent forKey:@"path"];
707 | }
708 |
709 | if (_children)
710 | {
711 | [groupData setObject:_children forKey:@"children"];
712 | }
713 |
714 | return groupData;
715 | }
716 |
717 | - (XcodeMemberType)typeForKey:(NSString*)key
718 | {
719 | NSDictionary* obj = [[_project objects] valueForKey:key];
720 | return [[obj valueForKey:@"isa"] asMemberType];
721 | }
722 |
723 | - (void)addSourceFile:(XCSourceFile*)sourceFile toTargets:(NSArray*)targets
724 | {
725 | for (XCTarget* target in targets)
726 | {
727 | [target addMember:sourceFile];
728 | }
729 | }
730 |
731 | @end
--------------------------------------------------------------------------------