├── LICENSE
├── README.md
├── SamplePlugin
├── SamplePlugin.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ ├── 723116ear.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── rajesh.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── SamplePlugin.xcscheme
│ └── xcuserdata
│ │ ├── 723116ear.xcuserdatad
│ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ │ └── rajesh.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── SamplePlugin
│ ├── Info.plist
│ ├── NSObject_Extension.h
│ ├── NSObject_Extension.m
│ ├── SamplePlugin.h
│ ├── SamplePlugin.m
│ ├── ViewController.h
│ ├── WindowController.h
│ ├── WindowController.m
│ └── WindowController.xib
├── screen1.png
└── screen2.png
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Rajesh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Xcode-Plugin-Export-IPA
2 | Export IPA from from Xcode Archive - Xcode Plugin
3 |
4 | # Installation Process
5 |
6 | - Download the SamplePlugin application and open in xcode
7 | - Build the application, (Product > Build)
8 | - Restart Xcode.
9 | - Go to Product menu and you can see Export IPA option.
10 |
11 | 
12 |
13 | # How to get the Archive file location
14 |
15 | - First you need Archive your project.
16 | - Then go to Window > Organizer
17 | - You can see your recent Archive files.
18 | - Select one archive file and right click.
19 | - Click Show in finder.
20 | - You can now get the location of archive file
21 |
22 | 
23 |
24 | #Note
25 |
26 | You need to select the appropriate provisioning profile for successful generation of IPA.
27 |
28 | IPA file will be saved in desktop folder
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | F10D394B1B4E7E9600C78912 /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F10D39491B4E7E9600C78912 /* WindowController.m */; };
11 | F10D394C1B4E7E9600C78912 /* WindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F10D394A1B4E7E9600C78912 /* WindowController.xib */; };
12 | F13F4CDE1B4E766800E6F9DC /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F13F4CDD1B4E766800E6F9DC /* AppKit.framework */; };
13 | F13F4CE01B4E766800E6F9DC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F13F4CDF1B4E766800E6F9DC /* Foundation.framework */; };
14 | F13F4CE51B4E766800E6F9DC /* SamplePlugin.xcscheme in Resources */ = {isa = PBXBuildFile; fileRef = F13F4CE41B4E766800E6F9DC /* SamplePlugin.xcscheme */; };
15 | F13F4CE81B4E766800E6F9DC /* SamplePlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = F13F4CE71B4E766800E6F9DC /* SamplePlugin.m */; };
16 | F13F4CEB1B4E766800E6F9DC /* NSObject_Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = F13F4CEA1B4E766800E6F9DC /* NSObject_Extension.m */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | F10D39481B4E7E9600C78912 /* WindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowController.h; sourceTree = ""; };
21 | F10D39491B4E7E9600C78912 /* WindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WindowController.m; sourceTree = ""; };
22 | F10D394A1B4E7E9600C78912 /* WindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WindowController.xib; sourceTree = ""; };
23 | F13A98651B4E7796002BE394 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
24 | F13F4CDA1B4E766800E6F9DC /* SamplePlugin.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SamplePlugin.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
25 | F13F4CDD1B4E766800E6F9DC /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; };
26 | F13F4CDF1B4E766800E6F9DC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; };
27 | F13F4CE31B4E766800E6F9DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
28 | F13F4CE41B4E766800E6F9DC /* SamplePlugin.xcscheme */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = SamplePlugin.xcscheme; path = SamplePlugin.xcodeproj/xcshareddata/xcschemes/SamplePlugin.xcscheme; sourceTree = SOURCE_ROOT; };
29 | F13F4CE61B4E766800E6F9DC /* SamplePlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SamplePlugin.h; sourceTree = ""; };
30 | F13F4CE71B4E766800E6F9DC /* SamplePlugin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SamplePlugin.m; sourceTree = ""; };
31 | F13F4CE91B4E766800E6F9DC /* NSObject_Extension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSObject_Extension.h; sourceTree = ""; };
32 | F13F4CEA1B4E766800E6F9DC /* NSObject_Extension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSObject_Extension.m; sourceTree = ""; };
33 | /* End PBXFileReference section */
34 |
35 | /* Begin PBXFrameworksBuildPhase section */
36 | F13F4CD81B4E766800E6F9DC /* Frameworks */ = {
37 | isa = PBXFrameworksBuildPhase;
38 | buildActionMask = 2147483647;
39 | files = (
40 | F13F4CDE1B4E766800E6F9DC /* AppKit.framework in Frameworks */,
41 | F13F4CE01B4E766800E6F9DC /* Foundation.framework in Frameworks */,
42 | );
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXFrameworksBuildPhase section */
46 |
47 | /* Begin PBXGroup section */
48 | F13F4CD11B4E766800E6F9DC = {
49 | isa = PBXGroup;
50 | children = (
51 | F13F4CE11B4E766800E6F9DC /* SamplePlugin */,
52 | F13F4CDC1B4E766800E6F9DC /* Frameworks */,
53 | F13F4CDB1B4E766800E6F9DC /* Products */,
54 | );
55 | sourceTree = "";
56 | };
57 | F13F4CDB1B4E766800E6F9DC /* Products */ = {
58 | isa = PBXGroup;
59 | children = (
60 | F13F4CDA1B4E766800E6F9DC /* SamplePlugin.xcplugin */,
61 | );
62 | name = Products;
63 | sourceTree = "";
64 | };
65 | F13F4CDC1B4E766800E6F9DC /* Frameworks */ = {
66 | isa = PBXGroup;
67 | children = (
68 | F13F4CDD1B4E766800E6F9DC /* AppKit.framework */,
69 | F13F4CDF1B4E766800E6F9DC /* Foundation.framework */,
70 | );
71 | name = Frameworks;
72 | sourceTree = "";
73 | };
74 | F13F4CE11B4E766800E6F9DC /* SamplePlugin */ = {
75 | isa = PBXGroup;
76 | children = (
77 | F13F4CE61B4E766800E6F9DC /* SamplePlugin.h */,
78 | F13F4CE71B4E766800E6F9DC /* SamplePlugin.m */,
79 | F13F4CE91B4E766800E6F9DC /* NSObject_Extension.h */,
80 | F13F4CEA1B4E766800E6F9DC /* NSObject_Extension.m */,
81 | F13F4CE21B4E766800E6F9DC /* Supporting Files */,
82 | F13A98651B4E7796002BE394 /* ViewController.h */,
83 | F10D39481B4E7E9600C78912 /* WindowController.h */,
84 | F10D39491B4E7E9600C78912 /* WindowController.m */,
85 | F10D394A1B4E7E9600C78912 /* WindowController.xib */,
86 | );
87 | path = SamplePlugin;
88 | sourceTree = "";
89 | };
90 | F13F4CE21B4E766800E6F9DC /* Supporting Files */ = {
91 | isa = PBXGroup;
92 | children = (
93 | F13F4CE31B4E766800E6F9DC /* Info.plist */,
94 | F13F4CE41B4E766800E6F9DC /* SamplePlugin.xcscheme */,
95 | );
96 | name = "Supporting Files";
97 | sourceTree = "";
98 | };
99 | /* End PBXGroup section */
100 |
101 | /* Begin PBXNativeTarget section */
102 | F13F4CD91B4E766800E6F9DC /* SamplePlugin */ = {
103 | isa = PBXNativeTarget;
104 | buildConfigurationList = F13F4CEE1B4E766800E6F9DC /* Build configuration list for PBXNativeTarget "SamplePlugin" */;
105 | buildPhases = (
106 | F13F4CD61B4E766800E6F9DC /* Sources */,
107 | F13F4CD71B4E766800E6F9DC /* Resources */,
108 | F13F4CD81B4E766800E6F9DC /* Frameworks */,
109 | );
110 | buildRules = (
111 | );
112 | dependencies = (
113 | );
114 | name = SamplePlugin;
115 | productName = SamplePlugin;
116 | productReference = F13F4CDA1B4E766800E6F9DC /* SamplePlugin.xcplugin */;
117 | productType = "com.apple.product-type.bundle";
118 | };
119 | /* End PBXNativeTarget section */
120 |
121 | /* Begin PBXProject section */
122 | F13F4CD21B4E766800E6F9DC /* Project object */ = {
123 | isa = PBXProject;
124 | attributes = {
125 | LastUpgradeCheck = 0630;
126 | ORGANIZATIONNAME = TCS;
127 | TargetAttributes = {
128 | F13F4CD91B4E766800E6F9DC = {
129 | CreatedOnToolsVersion = 6.3.2;
130 | };
131 | };
132 | };
133 | buildConfigurationList = F13F4CD51B4E766800E6F9DC /* Build configuration list for PBXProject "SamplePlugin" */;
134 | compatibilityVersion = "Xcode 3.2";
135 | developmentRegion = English;
136 | hasScannedForEncodings = 0;
137 | knownRegions = (
138 | en,
139 | );
140 | mainGroup = F13F4CD11B4E766800E6F9DC;
141 | productRefGroup = F13F4CDB1B4E766800E6F9DC /* Products */;
142 | projectDirPath = "";
143 | projectRoot = "";
144 | targets = (
145 | F13F4CD91B4E766800E6F9DC /* SamplePlugin */,
146 | );
147 | };
148 | /* End PBXProject section */
149 |
150 | /* Begin PBXResourcesBuildPhase section */
151 | F13F4CD71B4E766800E6F9DC /* Resources */ = {
152 | isa = PBXResourcesBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | F10D394C1B4E7E9600C78912 /* WindowController.xib in Resources */,
156 | F13F4CE51B4E766800E6F9DC /* SamplePlugin.xcscheme in Resources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXResourcesBuildPhase section */
161 |
162 | /* Begin PBXSourcesBuildPhase section */
163 | F13F4CD61B4E766800E6F9DC /* Sources */ = {
164 | isa = PBXSourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | F10D394B1B4E7E9600C78912 /* WindowController.m in Sources */,
168 | F13F4CE81B4E766800E6F9DC /* SamplePlugin.m in Sources */,
169 | F13F4CEB1B4E766800E6F9DC /* NSObject_Extension.m in Sources */,
170 | );
171 | runOnlyForDeploymentPostprocessing = 0;
172 | };
173 | /* End PBXSourcesBuildPhase section */
174 |
175 | /* Begin XCBuildConfiguration section */
176 | F13F4CEC1B4E766800E6F9DC /* Debug */ = {
177 | isa = XCBuildConfiguration;
178 | buildSettings = {
179 | ALWAYS_SEARCH_USER_PATHS = NO;
180 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
181 | CLANG_CXX_LIBRARY = "libc++";
182 | CLANG_ENABLE_MODULES = YES;
183 | CLANG_ENABLE_OBJC_ARC = YES;
184 | CLANG_WARN_BOOL_CONVERSION = YES;
185 | CLANG_WARN_CONSTANT_CONVERSION = YES;
186 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
187 | CLANG_WARN_EMPTY_BODY = YES;
188 | CLANG_WARN_ENUM_CONVERSION = YES;
189 | CLANG_WARN_INT_CONVERSION = YES;
190 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
191 | CLANG_WARN_UNREACHABLE_CODE = YES;
192 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
193 | COPY_PHASE_STRIP = NO;
194 | ENABLE_STRICT_OBJC_MSGSEND = YES;
195 | GCC_C_LANGUAGE_STANDARD = gnu99;
196 | GCC_DYNAMIC_NO_PIC = NO;
197 | GCC_NO_COMMON_BLOCKS = YES;
198 | GCC_OPTIMIZATION_LEVEL = 0;
199 | GCC_PREPROCESSOR_DEFINITIONS = (
200 | "DEBUG=1",
201 | "$(inherited)",
202 | );
203 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
204 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
205 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
206 | GCC_WARN_UNDECLARED_SELECTOR = YES;
207 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
208 | GCC_WARN_UNUSED_FUNCTION = YES;
209 | GCC_WARN_UNUSED_VARIABLE = YES;
210 | MTL_ENABLE_DEBUG_INFO = YES;
211 | ONLY_ACTIVE_ARCH = YES;
212 | };
213 | name = Debug;
214 | };
215 | F13F4CED1B4E766800E6F9DC /* Release */ = {
216 | isa = XCBuildConfiguration;
217 | buildSettings = {
218 | ALWAYS_SEARCH_USER_PATHS = NO;
219 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
220 | CLANG_CXX_LIBRARY = "libc++";
221 | CLANG_ENABLE_MODULES = YES;
222 | CLANG_ENABLE_OBJC_ARC = YES;
223 | CLANG_WARN_BOOL_CONVERSION = YES;
224 | CLANG_WARN_CONSTANT_CONVERSION = YES;
225 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
226 | CLANG_WARN_EMPTY_BODY = YES;
227 | CLANG_WARN_ENUM_CONVERSION = YES;
228 | CLANG_WARN_INT_CONVERSION = YES;
229 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
230 | CLANG_WARN_UNREACHABLE_CODE = YES;
231 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
232 | COPY_PHASE_STRIP = NO;
233 | ENABLE_NS_ASSERTIONS = NO;
234 | ENABLE_STRICT_OBJC_MSGSEND = YES;
235 | GCC_C_LANGUAGE_STANDARD = gnu99;
236 | GCC_NO_COMMON_BLOCKS = YES;
237 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
238 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
239 | GCC_WARN_UNDECLARED_SELECTOR = YES;
240 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
241 | GCC_WARN_UNUSED_FUNCTION = YES;
242 | GCC_WARN_UNUSED_VARIABLE = YES;
243 | MTL_ENABLE_DEBUG_INFO = NO;
244 | };
245 | name = Release;
246 | };
247 | F13F4CEF1B4E766800E6F9DC /* Debug */ = {
248 | isa = XCBuildConfiguration;
249 | buildSettings = {
250 | COMBINE_HIDPI_IMAGES = YES;
251 | DEPLOYMENT_LOCATION = YES;
252 | DSTROOT = "$(HOME)";
253 | INFOPLIST_FILE = SamplePlugin/Info.plist;
254 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
255 | MACOSX_DEPLOYMENT_TARGET = 10.10;
256 | PRODUCT_NAME = "$(TARGET_NAME)";
257 | WRAPPER_EXTENSION = xcplugin;
258 | };
259 | name = Debug;
260 | };
261 | F13F4CF01B4E766800E6F9DC /* Release */ = {
262 | isa = XCBuildConfiguration;
263 | buildSettings = {
264 | COMBINE_HIDPI_IMAGES = YES;
265 | DEPLOYMENT_LOCATION = YES;
266 | DSTROOT = "$(HOME)";
267 | INFOPLIST_FILE = SamplePlugin/Info.plist;
268 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
269 | MACOSX_DEPLOYMENT_TARGET = 10.10;
270 | PRODUCT_NAME = "$(TARGET_NAME)";
271 | WRAPPER_EXTENSION = xcplugin;
272 | };
273 | name = Release;
274 | };
275 | /* End XCBuildConfiguration section */
276 |
277 | /* Begin XCConfigurationList section */
278 | F13F4CD51B4E766800E6F9DC /* Build configuration list for PBXProject "SamplePlugin" */ = {
279 | isa = XCConfigurationList;
280 | buildConfigurations = (
281 | F13F4CEC1B4E766800E6F9DC /* Debug */,
282 | F13F4CED1B4E766800E6F9DC /* Release */,
283 | );
284 | defaultConfigurationIsVisible = 0;
285 | defaultConfigurationName = Release;
286 | };
287 | F13F4CEE1B4E766800E6F9DC /* Build configuration list for PBXNativeTarget "SamplePlugin" */ = {
288 | isa = XCConfigurationList;
289 | buildConfigurations = (
290 | F13F4CEF1B4E766800E6F9DC /* Debug */,
291 | F13F4CF01B4E766800E6F9DC /* Release */,
292 | );
293 | defaultConfigurationIsVisible = 0;
294 | defaultConfigurationName = Release;
295 | };
296 | /* End XCConfigurationList section */
297 | };
298 | rootObject = F13F4CD21B4E766800E6F9DC /* Project object */;
299 | }
300 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/project.xcworkspace/xcuserdata/723116ear.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajeshbeats/Xcode-Plugin-Export-IPA/917e24d91f1ebfb8f6b4014e639b3203a6161a3e/SamplePlugin/SamplePlugin.xcodeproj/project.xcworkspace/xcuserdata/723116ear.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/project.xcworkspace/xcuserdata/rajesh.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajeshbeats/Xcode-Plugin-Export-IPA/917e24d91f1ebfb8f6b4014e639b3203a6161a3e/SamplePlugin/SamplePlugin.xcodeproj/project.xcworkspace/xcuserdata/rajesh.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/xcshareddata/xcschemes/SamplePlugin.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
58 |
61 |
62 |
63 |
69 |
70 |
71 |
72 |
73 |
74 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/xcuserdata/723116ear.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SamplePlugin.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | F13F4CD91B4E766800E6F9DC
16 |
17 | primary
18 |
19 |
20 | F1D610601B4EAB7A00A43E10
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin.xcodeproj/xcuserdata/rajesh.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SuppressBuildableAutocreation
6 |
7 | F13F4CD91B4E766800E6F9DC
8 |
9 | primary
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.development.$(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 |
34 | LSMinimumSystemVersion
35 | $(MACOSX_DEPLOYMENT_TARGET)
36 | NSPrincipalClass
37 | SamplePlugin
38 | XC4Compatible
39 |
40 | XCPluginHasUI
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/NSObject_Extension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject_Extension.h
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. 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 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/NSObject_Extension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject_Extension.m
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. All rights reserved.
7 | //
8 |
9 |
10 | #import "NSObject_Extension.h"
11 | #import "SamplePlugin.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 = [[SamplePlugin alloc] initWithBundle:plugin];
22 | });
23 | }
24 | }
25 | @end
26 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/SamplePlugin.h:
--------------------------------------------------------------------------------
1 | //
2 | // SamplePlugin.h
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class SamplePlugin;
12 |
13 | static SamplePlugin *sharedPlugin;
14 |
15 | @interface SamplePlugin : NSObject
16 |
17 | + (instancetype)sharedPlugin;
18 | - (id)initWithBundle:(NSBundle *)plugin;
19 |
20 | @property (nonatomic, strong, readonly) NSBundle* bundle;
21 | @end
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/SamplePlugin.m:
--------------------------------------------------------------------------------
1 | //
2 | // SamplePlugin.m
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. All rights reserved.
7 | //
8 |
9 | #import "SamplePlugin.h"
10 | #import "WindowController.h"
11 |
12 | @interface SamplePlugin()
13 |
14 | @property (nonatomic, strong, readwrite) NSBundle *bundle;
15 | @property (nonatomic, strong) WindowController *wc;
16 | @end
17 |
18 | @implementation SamplePlugin
19 |
20 | + (instancetype)sharedPlugin
21 | {
22 | return sharedPlugin;
23 | }
24 |
25 | - (id)initWithBundle:(NSBundle *)plugin
26 | {
27 | if (self = [super init]) {
28 | // reference to plugin's bundle, for resource access
29 | self.bundle = plugin;
30 | [[NSNotificationCenter defaultCenter] addObserver:self
31 | selector:@selector(didApplicationFinishLaunchingNotification:)
32 | name:NSApplicationDidFinishLaunchingNotification
33 | object:nil];
34 | }
35 | return self;
36 | }
37 |
38 | - (void)didApplicationFinishLaunchingNotification:(NSNotification*)noti
39 | {
40 | //removeObserver
41 | [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidFinishLaunchingNotification object:nil];
42 |
43 | // Create menu items, initialize UI, etc.
44 | // Sample Menu Item:
45 | NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Product"];
46 | if (menuItem) {
47 | [[menuItem submenu] addItem:[NSMenuItem separatorItem]];
48 | NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Export IPA" action:@selector(doMenuAction) keyEquivalent:@""];
49 | //[actionMenuItem setKeyEquivalentModifierMask:NSAlphaShiftKeyMask | NSControlKeyMask];
50 | [actionMenuItem setTarget:self];
51 | [[menuItem submenu] addItem:actionMenuItem];
52 | }
53 | }
54 |
55 | // Sample Action, for menu item:
56 | - (void)doMenuAction
57 | {
58 | self.wc = [[WindowController alloc] initWithWindowNibName:NSStringFromClass(WindowController.class)];
59 | [self.wc.window makeKeyWindow];
60 | }
61 |
62 | - (void)dealloc
63 | {
64 | [[NSNotificationCenter defaultCenter] removeObserver:self];
65 | //[[[NSApplication sharedApplication] mainWindow] ma]
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : NSViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/WindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // WindowController.h
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface WindowController : NSWindowController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/WindowController.m:
--------------------------------------------------------------------------------
1 | //
2 | // WindowController.m
3 | // SamplePlugin
4 | //
5 | // Created by Rajesh R. on 7/9/15.
6 | // Copyright (c) 2015 MyCompany. All rights reserved.
7 | //
8 |
9 | #import "WindowController.h"
10 |
11 | @interface WindowController ()
12 | @property (weak) IBOutlet NSButton *createIPAButton;
13 | @property (weak) IBOutlet NSPopUpButton *popupButton;
14 | @property (weak) IBOutlet NSTextField *archiveFileName;
15 | @property (nonatomic, strong) NSString *selectedProfile;
16 | @property (nonatomic, strong) NSString *archivePath;
17 | @property (nonatomic, strong) NSTask *task;
18 | @property (weak) IBOutlet NSTextField *ipaPathLabel;
19 |
20 | - (IBAction)archiveSelection:(NSButton *)sender;
21 | - (IBAction)createIPAButtonClick:(NSButton *)sender;
22 | - (IBAction)popUpButtonClick:(NSPopUpButton *)sender;
23 |
24 | @end
25 | #define PopupDefaultTitle @"Please select provisioning profile"
26 |
27 | @implementation WindowController
28 |
29 | - (void)windowDidLoad {
30 |
31 | [super windowDidLoad];
32 | NSError *error = nil;
33 | NSString *path = [@"~/Library/MobileDevice/Provisioning Profiles" stringByExpandingTildeInPath];
34 | NSArray *dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
35 | NSArray *files = [dirFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.mobileprovision'"]];
36 | NSMutableArray *listItems = [NSMutableArray arrayWithObject:PopupDefaultTitle];
37 | for (NSString *fileName in files) {
38 |
39 | NSString *name = [self nameForProfileAtPath:[path stringByAppendingPathComponent:fileName]];
40 | [listItems addObject:name];
41 |
42 | }
43 | [self.popupButton addItemsWithTitles:listItems];
44 | }
45 | - (NSString *)nameForProfileAtPath:(NSString *)path {
46 | CMSDecoderRef decoder = NULL;
47 | CFDataRef dataRef = NULL;
48 | NSString *plistString = nil;
49 | NSDictionary *plist = nil;
50 |
51 | CMSDecoderCreate(&decoder);
52 | NSData *fileData = [NSData dataWithContentsOfFile:path];
53 | CMSDecoderUpdateMessage(decoder, fileData.bytes, fileData.length);
54 | CMSDecoderFinalizeMessage(decoder);
55 | CMSDecoderCopyContent(decoder, &dataRef);
56 | plistString = [[NSString alloc] initWithData:(__bridge NSData *)dataRef encoding:NSUTF8StringEncoding];
57 | plist = [plistString propertyList];
58 | NSString *name = plist[@"Name"];
59 | return name;
60 | }
61 | - (NSString *)runCommand:(NSString *)commandToRun
62 | {
63 | self.task = [[NSTask alloc] init];
64 | [self.task setLaunchPath:@"/bin/sh"];
65 |
66 | NSArray *arguments = [NSArray arrayWithObjects:
67 | @"-c" ,
68 | [NSString stringWithFormat:@"%@", commandToRun],
69 | nil];
70 | [self.task setArguments:arguments];
71 |
72 | NSPipe *pipe = [NSPipe pipe];
73 | [self.task setStandardOutput:pipe];
74 |
75 | NSFileHandle *file = [pipe fileHandleForReading];
76 |
77 | [self.task launch];
78 |
79 | NSData *data = [file readDataToEndOfFile];
80 |
81 | NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
82 | return output;
83 |
84 | }
85 |
86 | - (IBAction)archiveSelection:(NSButton *)sender {
87 | NSOpenPanel *panel = [NSOpenPanel openPanel];
88 | [panel setCanChooseFiles:YES];
89 | [panel setCanChooseDirectories:NO];
90 | [panel setAllowedFileTypes:@[@"xcarchive"]];
91 | [panel setAllowsMultipleSelection:NO]; // yes if more than one dir is allowed
92 |
93 | NSInteger clicked = [panel runModal];
94 |
95 | if (clicked == NSFileHandlingPanelOKButton) {
96 | for (NSURL *url in [panel URLs]) {
97 | // do something with the url here.
98 | self.archivePath = url.path;
99 | self.archiveFileName.stringValue = [self.archivePath lastPathComponent];
100 | }
101 | }
102 | }
103 | - (IBAction)createIPAButtonClick:(NSButton *)sender {
104 |
105 | if(!self.selectedProfile || [self.selectedProfile isEqualToString:PopupDefaultTitle]) {
106 |
107 | NSAlert *alert = [[NSAlert alloc] init];
108 | [alert setMessageText:PopupDefaultTitle];
109 | [alert runModal];
110 |
111 | } else if (!self.archivePath) {
112 | NSAlert *alert = [[NSAlert alloc] init];
113 | [alert setMessageText:@"Please select archive file"];
114 | [alert addButtonWithTitle:@"Cancel"];
115 | [alert runModal];
116 | } else {
117 |
118 | NSString *selectedArchivePath = self.archivePath;
119 |
120 | NSString *ipaName = [[selectedArchivePath lastPathComponent] stringByReplacingOccurrencesOfString:@"xcarchive" withString:@"ipa"];
121 | NSString *ipaPath = [[NSString stringWithFormat:@"~/Desktop/%@",ipaName] stringByExpandingTildeInPath];
122 | NSString * updateCmd = [NSString stringWithFormat:@"xcodebuild -exportArchive -exportFormat ipa -archivePath \"%@\" -exportPath \"%@\" -exportProvisioningProfile \"%@\"",selectedArchivePath,ipaPath,self.selectedProfile];
123 |
124 | NSProgressIndicator *progressIndic = [[NSProgressIndicator alloc] initWithFrame:NSRectFromCGRect(CGRectMake(0, 0, 20, 20))];
125 | [progressIndic setStyle:NSProgressIndicatorSpinningStyle];
126 |
127 | [progressIndic startAnimation:nil];
128 | NSAlert *alert = [[NSAlert alloc] init];
129 | [alert setMessageText:@"Please wait..."];
130 | [alert setAccessoryView:progressIndic];
131 | [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
132 | [self.task interrupt];
133 | }];
134 |
135 | dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
136 | //back ground thread
137 | [self runCommand:updateCmd];
138 | self.ipaPathLabel.stringValue = ipaPath;
139 | dispatch_async(dispatch_get_main_queue(), ^{
140 | [self.window endSheet: [alert window]];
141 | });
142 |
143 | });
144 | }
145 | }
146 |
147 | - (IBAction)popUpButtonClick:(NSPopUpButton *)sender {
148 | self.selectedProfile = sender.selectedItem.title;
149 | }
150 | @end
151 |
--------------------------------------------------------------------------------
/SamplePlugin/SamplePlugin/WindowController.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 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/screen1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajeshbeats/Xcode-Plugin-Export-IPA/917e24d91f1ebfb8f6b4014e639b3203a6161a3e/screen1.png
--------------------------------------------------------------------------------
/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rajeshbeats/Xcode-Plugin-Export-IPA/917e24d91f1ebfb8f6b4014e639b3203a6161a3e/screen2.png
--------------------------------------------------------------------------------