Repository: johnno1962/InjectionApp Branch: master Commit: bf7452046c8d Files: 49 Total size: 257.0 KB Directory structure: gitextract_2rj_t86d/ ├── .gitignore ├── DiskTree/ │ ├── DiskTree.html │ ├── DiskTree.xib │ └── tree.c ├── InjectionAppCode/ │ ├── .idea/ │ │ ├── InjectionAppCode.iml │ │ ├── ant.xml │ │ ├── compiler.xml │ │ ├── copyright/ │ │ │ └── profiles_settings.xml │ │ ├── dictionaries/ │ │ │ └── johnholdsworth.xml │ │ ├── encodings.xml │ │ ├── misc.xml │ │ ├── modules.xml │ │ ├── scopes/ │ │ │ └── scope_settings.xml │ │ ├── uiDesigner.xml │ │ └── workspace.xml │ ├── Injection.iml │ ├── Injection.jar │ ├── META-INF/ │ │ └── plugin.xml │ └── src/ │ └── com/ │ └── injectionforxcode/ │ └── InjectionAppAction.java ├── InjectionBootstrap/ │ └── Info.plist ├── InjectionHelper/ │ ├── Info-Launchd.plist │ └── Info.plist ├── InjectionLoader/ │ ├── BundleContents.h │ ├── BundleContents.mm │ ├── Info.plist │ └── InjectionLoader.xcodeproj/ │ └── project.pbxproj ├── Injectorator/ │ ├── App.icns │ ├── Assets.xcassets/ │ │ └── AppIcon.appiconset/ │ │ └── Contents.json │ ├── Benchmark.swift │ ├── Credits.rtf │ ├── INController.swift │ ├── Info.plist │ ├── InjectionIdle.tif │ ├── InjectionOK.tif │ ├── Injectorator-Bridging-Header.h │ ├── Integration.swift │ ├── Integration.xib │ └── RMController.swift ├── Injectorator.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── Injectorator.xcscmblueprint ├── LICENSE ├── README.md ├── XprobeSwift/ │ ├── Info.plist │ ├── XprobeSwift-Bridging-Header.h │ └── XprobeSwift.xcodeproj/ │ └── project.pbxproj ├── docs/ │ ├── index.html │ └── injectionfaq.html └── injectSource/ └── main.m ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ */build* *Library/* *xcuserdata* *xccheckout* ================================================ FILE: DiskTree/DiskTree.html ================================================
 

Disk Usage Tool

Disk Usage is a basic tool to locate space that can be recovered on your disk drive. Click scan to start the process and after all files on your drive have been sized a tree view will be dispayed. Click on the folder to drill down or on the directory link to open in Finder.

 
================================================ FILE: DiskTree/DiskTree.xib ================================================ ================================================ FILE: DiskTree/tree.c ================================================ /* Recursive version of du for DiskUsage Applet. (c) John Holdsworth 2011 Usage is: $ tree dirpath1 [dirpath2..] Format output is: +dirname +subdir name !large file name -large file size #file count if non-zero -subdir usage in bytes +other subdir name -other subdir usage -dir usage in bytes -total usage of "dirpath1" above */ #include #include #include #include #include #include #include #include typedef unsigned long long usage_t; static int MIN_FILE; static time_t AFTER; static FILE *out; static usage_t du( char *dir, int level ) { usage_t total = 0; if ( chdir( dir ) == 0 ) { int fcount = 0; struct dirent *ent; DIR *d = opendir( "." ); if ( !d ) perror( dir ); while ( d && (ent = readdir( d )) ) { char *name = ent->d_name; struct stat st; if ( strcmp( name, "." ) != 0 && strcmp( name, ".." ) != 0 && lstat( name, &st ) == 0 && st.st_size ) { usage_t fsize = st.st_size; total += fsize; //fprintf( out, "%s %lu %u %x\n", ent->d_name, // st.st_size, (int)sizeof st.st_size, st.st_mode ); if ( S_ISDIR( st.st_mode ) && !S_ISLNK( st.st_mode ) ) { fprintf( out, "+%s\n", name ); total += du( name, level+1 ); //system( "pwd" ); } else { if ( fsize > MIN_FILE && (AFTER == 0 || st.st_mtime > AFTER || st.st_atime && st.st_atime < AFTER ) ) fprintf( out, "!%s\n@%u\n-%llu\n", name, (unsigned)st.st_atime, fsize ); if ( name[0] != '.' ) //&& strcmp( name, "sentinel" ) != 0 ) fcount++; } } } if ( fcount ) fprintf( out, "#%d\n", fcount ); if ( chdir( ".." ) != 0 ) perror( dir ); if ( d ) closedir( d ); } else perror( dir ); fprintf( out, "-%llu\n", total ); return total; } static void catcher( int sig ) { fprintf( stderr, "Signal %d\n", sig ); exit(1); } int main( int argc, char *argv[] ) { int i; MIN_FILE = atoi( argv[1] ); AFTER = atoi( argv[2] ); out = argv[argc-1][0] == '-' ? stdout : fopen( argv[argc-1], "w" ); signal( SIGPIPE, catcher ); for ( i=3 ; i ================================================ FILE: InjectionAppCode/.idea/ant.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/compiler.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/copyright/profiles_settings.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/dictionaries/johnholdsworth.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/encodings.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/misc.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/modules.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/scopes/scope_settings.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/uiDesigner.xml ================================================ ================================================ FILE: InjectionAppCode/.idea/workspace.xml ================================================ Plugin DevKit PluginXmlValidity localhost 5050 1361704295190 No facets are configured IDEA IC-123.169 Injection ================================================ FILE: InjectionAppCode/Injection.iml ================================================ ================================================ FILE: InjectionAppCode/META-INF/plugin.xml ================================================ com.injectionforxcode.injectionapp.plugin.id Injection App for AppCode 8.0 Injection for Xcode Requires Injection for Xcode plugin to work. ]]> ]]> com.intellij.modules.lang ================================================ FILE: InjectionAppCode/src/com/injectionforxcode/InjectionAppAction.java ================================================ package com.injectionforxcode; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.ui.Messages; import com.intellij.util.ui.UIUtil; /** * Copyright (c) 2013 John Holdsworth. All rights reserved. * * Created with IntelliJ IDEA. * Date: 05/01/2016 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * If you want to "support the cause", consider a paypal donation to: * * injectionforxcode@johnholdsworth.com * */ public class InjectionAppAction extends AnAction { public void actionPerformed(AnActionEvent event) { Project project = event.getData(PlatformDataKeys.PROJECT); VirtualFile vf = event.getData(PlatformDataKeys.VIRTUAL_FILE); if ( vf == null ) return; FileDocumentManager.getInstance().saveAllDocuments(); try { Runtime.getRuntime().exec(new String[]{"/Applications/Injection.app/Contents/Resources/injectSource", vf.getCanonicalPath()}, null, null).waitFor(); } catch ( final Exception e ) { UIUtil.invokeAndWaitIfNeeded(new Runnable() { public void run() { Messages.showMessageDialog(e.getMessage(), "InjectionApp Plugin", Messages.getInformationIcon()); } } ); } } } ================================================ FILE: InjectionBootstrap/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 NSHumanReadableCopyright Copyright © 2016 John Holdsworth. All rights reserved. NSPrincipalClass ================================================ FILE: InjectionHelper/Info-Launchd.plist ================================================ Label com.johnholdsworth.Injectorator.Helper MachServices com.johnholdsworth.Injectorator.Helper.mach ================================================ FILE: InjectionHelper/Info.plist ================================================ CFBundleIdentifier com.johnholdsworth.Injectorator.Helper CFBundleInfoDictionaryVersion 6.0 CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 NSHumanReadableCopyright Copyright © 2016 John Holdsworth. All rights reserved. NSPrincipalClass SMAuthorizedClients identifier com.johnholdsworth.Injectorator ================================================ FILE: InjectionLoader/BundleContents.h ================================================ // // BundleContents.h // InjectionLoader // // Created by John Holdsworth on 17/01/2012. // Copyright (c) 2012 John Holdsworth. All rights reserved. // // move along, nothing to see here.. ================================================ FILE: InjectionLoader/BundleContents.mm ================================================ // // BundleContents.m // InjectionLoader // // Created by John Holdsworth on 17/01/2012. // Copyright (c) 2012 John Holdsworth. All rights reserved. // #import static char _inMainFilePath[] = __FILE__; static const char *_inIPAddresses[] = {"127.0.0.1", NULL}; #define INJECTION_LOADER #define INJECTION_ENABLED #import "../../XprobePlugin/Classes/Xtrace.h" #import "../../XprobePlugin/Classes/Xprobe.mm" #import "../../injectionforxcode/InjectionPluginLite/Classes/BundleInjection.h" #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED #import //@interface CCDirector //+ (CCDirector *)sharedDirector; //+ (id)sharedDeviceConnection; //+ (id)startRemoteInterface; //+ (id)sharedInstance; //@end #else #import #endif #if 0 static char _inMainFilePath[] = __FILE__; static const char *_inIPAddresses[] = {"127.0.0.1", NULL}; #define INJECTION_ENABLED #import "BundleInjection.h" #else //@interface BundleInjection //+ (float *)_inParameters; //+ (void)loadedNotify:(int)notify hook:(void *)hook; //@end #endif @implementation Xprobe(Seeding) //+ (void)load { //#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR // [self connectTo:NULL retainObjects:YES]; //#else // [self connectTo:"127.0.0.1" retainObjects:YES]; //#endif // [self search:@""]; // // Class injection = NSClassFromString(@"BundleInjection"); // if ( [injection respondsToSelector:@selector(_inParameters)] ) // [injection loadedNotify:0 hook:NULL]; //} #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED + (NSArray *)xprobeSeeds { UIApplication *app = [UIApplication sharedApplication]; NSMutableArray *seeds = [[app windows] mutableCopy]; [seeds insertObject:app atIndex:0]; // support for cocos2d Class ccDirectorClass = NSClassFromString(@"CCDirector"); CCDirector *ccDirector = [ccDirectorClass sharedDirector]; if ( ccDirector ) [seeds addObject:ccDirector]; if ( !seeds ) { seeds = [NSMutableArray new]; // Class deviceClass = NSClassFromString(@"SPDeviceConnection"); // id deviceInstance = [deviceClass sharedDeviceConnection]; // if ( deviceInstance ) // [seeds addObject:deviceInstance]; // // Class interfaceClass = NSClassFromString(@"SPRemoteInterface"); // id interfaceInstance = [interfaceClass startRemoteInterface]; // if ( interfaceInstance ) // [seeds addObject:interfaceInstance]; Class cacheClass = NSClassFromString(@"SPCompanionAssetCache"); id cacheInstance = [cacheClass sharedInstance]; if ( cacheInstance ) [seeds addObject:cacheInstance]; } return seeds; } #else + (NSArray *)xprobeSeeds { NSApplication *app = [NSApplication sharedApplication]; NSMutableArray *seeds = [[app windows] mutableCopy]; if ( app.delegate ) [seeds insertObject:app.delegate atIndex:0]; return seeds; } #endif @end ================================================ FILE: InjectionLoader/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 NSHumanReadableCopyright Copyright © 2016 John Holdsworth. All rights reserved. NSPrincipalClass ================================================ FILE: InjectionLoader/InjectionLoader.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ BB356B701E0B1A5C0056B10F /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BB356B6F1E0B1A5C0056B10F /* libz.tbd */; }; BB356B741E0B1AAE0056B10F /* BundleContents.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB356B721E0B1AAE0056B10F /* BundleContents.mm */; }; BB356B751E0B1AAE0056B10F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB356B731E0B1AAE0056B10F /* Info.plist */; }; BB356B931E0B807B0056B10F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BB356B921E0B807B0056B10F /* UIKit.framework */; }; BB356BC31E0B93CC0056B10F /* Xprobe+Service.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB356BC21E0B93CC0056B10F /* Xprobe+Service.mm */; }; BB356BCC1E0BC3FE0056B10F /* Xtrace.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB356BCA1E0BC3FE0056B10F /* Xtrace.mm */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ BB356B531E0B184C0056B10F /* InjectionLoader.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InjectionLoader.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; BB356B6F1E0B1A5C0056B10F /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; BB356B711E0B1AAE0056B10F /* BundleContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundleContents.h; sourceTree = SOURCE_ROOT; }; BB356B721E0B1AAE0056B10F /* BundleContents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BundleContents.mm; sourceTree = SOURCE_ROOT; }; BB356B731E0B1AAE0056B10F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; BB356B921E0B807B0056B10F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; BB356BC21E0B93CC0056B10F /* Xprobe+Service.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "Xprobe+Service.mm"; path = "../../XprobePlugin/Classes/Xprobe+Service.mm"; sourceTree = ""; }; BB356BC71E0BC3FE0056B10F /* Xprobe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Xprobe.h; path = ../../XprobePlugin/Classes/Xprobe.h; sourceTree = ""; }; BB356BC81E0BC3FE0056B10F /* Xprobe.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Xprobe.mm; path = ../../XprobePlugin/Classes/Xprobe.mm; sourceTree = ""; }; BB356BC91E0BC3FE0056B10F /* Xtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Xtrace.h; path = ../../XprobePlugin/Classes/Xtrace.h; sourceTree = ""; }; BB356BCA1E0BC3FE0056B10F /* Xtrace.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Xtrace.mm; path = ../../XprobePlugin/Classes/Xtrace.mm; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ BB356B501E0B184C0056B10F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( BB356B931E0B807B0056B10F /* UIKit.framework in Frameworks */, BB356B701E0B1A5C0056B10F /* libz.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ BB356B4A1E0B184C0056B10F = { isa = PBXGroup; children = ( BB356BC91E0BC3FE0056B10F /* Xtrace.h */, BB356BCA1E0BC3FE0056B10F /* Xtrace.mm */, BB356BC71E0BC3FE0056B10F /* Xprobe.h */, BB356BC81E0BC3FE0056B10F /* Xprobe.mm */, BB356BC21E0B93CC0056B10F /* Xprobe+Service.mm */, BB356B711E0B1AAE0056B10F /* BundleContents.h */, BB356B721E0B1AAE0056B10F /* BundleContents.mm */, BB356B731E0B1AAE0056B10F /* Info.plist */, BB356B541E0B184C0056B10F /* Products */, BB356B6E1E0B1A5C0056B10F /* Frameworks */, ); sourceTree = ""; }; BB356B541E0B184C0056B10F /* Products */ = { isa = PBXGroup; children = ( BB356B531E0B184C0056B10F /* InjectionLoader.bundle */, ); name = Products; sourceTree = ""; }; BB356B6E1E0B1A5C0056B10F /* Frameworks */ = { isa = PBXGroup; children = ( BB356B921E0B807B0056B10F /* UIKit.framework */, BB356B6F1E0B1A5C0056B10F /* libz.tbd */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ BB356B521E0B184C0056B10F /* InjectionLoader */ = { isa = PBXNativeTarget; buildConfigurationList = BB356B591E0B184C0056B10F /* Build configuration list for PBXNativeTarget "InjectionLoader" */; buildPhases = ( BB356B4F1E0B184C0056B10F /* Sources */, BB356B501E0B184C0056B10F /* Frameworks */, BB356B511E0B184C0056B10F /* Resources */, ); buildRules = ( ); dependencies = ( ); name = InjectionLoader; productName = InjectionLoader; productReference = BB356B531E0B184C0056B10F /* InjectionLoader.bundle */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ BB356B4B1E0B184C0056B10F /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0820; ORGANIZATIONNAME = "John Holdsworth"; TargetAttributes = { BB356B521E0B184C0056B10F = { CreatedOnToolsVersion = 8.2.1; DevelopmentTeam = 9V5A8WE85E; ProvisioningStyle = Manual; }; }; }; buildConfigurationList = BB356B4E1E0B184C0056B10F /* Build configuration list for PBXProject "InjectionLoader" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = BB356B4A1E0B184C0056B10F; productRefGroup = BB356B541E0B184C0056B10F /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( BB356B521E0B184C0056B10F /* InjectionLoader */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ BB356B511E0B184C0056B10F /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( BB356B751E0B1AAE0056B10F /* Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ BB356B4F1E0B184C0056B10F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( BB356BCC1E0BC3FE0056B10F /* Xtrace.mm in Sources */, BB356BC31E0B93CC0056B10F /* Xprobe+Service.mm in Sources */, BB356B741E0B1AAE0056B10F /* BundleContents.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ BB356B571E0B184C0056B10F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD)"; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "INJECTION_PORT=$INJECTION_PORT", "XPROBE_PORT=$XPROBE_PORT", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; BB356B581E0B184C0056B10F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD)"; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "INJECTION_PORT=$INJECTION_PORT", "XPROBE_PORT=$XPROBE_PORT", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; }; name = Release; }; BB356B5A1E0B184C0056B10F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application"; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = 9V5A8WE85E; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; PRODUCT_BUNDLE_IDENTIFIER = com.johnholdsworth.InjectionLoader; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; WRAPPER_EXTENSION = bundle; }; name = Debug; }; BB356B5B1E0B184C0056B10F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_IDENTITY = "Developer ID Application"; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = 9V5A8WE85E; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; PRODUCT_BUNDLE_IDENTIFIER = com.johnholdsworth.InjectionLoader; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; WRAPPER_EXTENSION = bundle; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ BB356B4E1E0B184C0056B10F /* Build configuration list for PBXProject "InjectionLoader" */ = { isa = XCConfigurationList; buildConfigurations = ( BB356B571E0B184C0056B10F /* Debug */, BB356B581E0B184C0056B10F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; BB356B591E0B184C0056B10F /* Build configuration list for PBXNativeTarget "InjectionLoader" */ = { isa = XCConfigurationList; buildConfigurations = ( BB356B5A1E0B184C0056B10F /* Debug */, BB356B5B1E0B184C0056B10F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = BB356B4B1E0B184C0056B10F /* Project object */; } ================================================ FILE: Injectorator/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "mac", "size" : "16x16", "scale" : "1x" }, { "idiom" : "mac", "size" : "16x16", "scale" : "2x" }, { "idiom" : "mac", "size" : "32x32", "scale" : "1x" }, { "idiom" : "mac", "size" : "32x32", "scale" : "2x" }, { "idiom" : "mac", "size" : "128x128", "scale" : "1x" }, { "idiom" : "mac", "size" : "128x128", "scale" : "2x" }, { "idiom" : "mac", "size" : "256x256", "scale" : "1x" }, { "idiom" : "mac", "size" : "256x256", "scale" : "2x" }, { "idiom" : "mac", "size" : "512x512", "scale" : "1x" }, { "idiom" : "mac", "size" : "512x512", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Injectorator/Benchmark.swift ================================================ // // Benchmark.swift // Injectorator // // Created by John Holdsworth on 07/01/2017. // Copyright © 2017 John Holdsworth. All rights reserved. // import Foundation extension Integration { @IBAction func optimise(sender: AnyObject!) { appDelegate.state.setup() var html = "" for line in LogParser(logDir: appDelegate.state.project!.derivedData+"/Logs/Build").profileLines() { let tabsep = line.components(separatedBy: "\t"), time = tabsep[0], location = tabsep[1], decl = tabsep[2] let colonsep = location.components(separatedBy: ":"), file = colonsep[0], line = colonsep[1], col = colonsep[2] html += "
\(time) 
\(file.url.lastPathComponent):\(line):\(col) 
\(decl)\n"
        }

        appDelegate.state.setChangesSource(header: "Compile time measurements...")
        if html == "" {
            html = "Add \"-Xfrontend -debug-time-function-bodies\" to \"Other Swift Flags\" of your project and build to benchmark compilation times"
        }
        else {
            html = "\(html)
" } appDelegate.state.appendSource(title: "", text: html) } @IBAction func findSpace(sender: AnyObject!) { if delegate == nil { Bundle.main.loadNibNamed("DiskTree", owner: self, topLevelObjects: nil) } let notification = Notification(name: .NSApplicationDidFinishLaunching) delegate.applicationDidFinishLaunching!(notification) } } extension LogParser { func profileLines() -> [NSString] { var out = [NSString]() for line in TaskGenerator( command: "gunzip <\"\(recentFirstLogs.first ?? "blah")\"", lineSeparator: "\r" ).sequence { if line.contains("ms\t/") { let line = line.replacingOccurrences(of: "^.*\"(\\d+\\.\\dms\t)", with: "$1", options: .regularExpression) if !line.hasPrefix("0.0ms") { out.append(line as NSString) } } } return Set( out ).sorted { return $0.floatValue > $1.floatValue } } } ================================================ FILE: Injectorator/Credits.rtf ================================================ {\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf830 {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Menlo-Regular;\f2\fnil\fcharset0 HelveticaNeue; \f3\fmodern\fcharset0 Courier;} {\colortbl;\red255\green255\blue255;\red83\green98\blue108;} {\*\expandedcolortbl;;\csgenericrgb\c32549\c38431\c42353;} \paperw11900\paperh16840\vieww9600\viewh8400\viewkind0 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0 \f0\fs24 \cf0 The Injection plugin for Xcode is now a standalone app. This allows you to inject changes to class method implementations into a running application in the simulator or a macOS app. Injecting is now as simple as downloading the app and run having it running in the background while you are working on a project in Xcode and using the menu bar item "Inject Source" (don't forget to save the file!)\ \ Injection will communicate with Xcode using AppleScript to determine the current file and project then insert code into the the simulator which is then used to load in and swizzle the new version of the code into the app. Injection can also be used as a service or from the command line using the "injectSource" binary in the app package.\ \ For OSX you'll need to patch the project's main.m (create an empty one for Swift projects) using "macOS Project/Patch" on the menu bar, after which, it should connect as before. If you patch your project or once you have performed an initial injection you can use a file watcher which injects each time a file in your project is saved. Unfortunately, injecting on the device is no longer possible due to iOS 10's sandboxing.\ \ For further help go to {\field{\*\fldinst{HYPERLINK "http://johnholdsworth.com/injection.html"}}{\fldrslt http://johnholdsworth.com/injection.html}}\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \f1\fs22 \cf0 Copyright (C) 2016-7 John Holdsworth {\field{\*\fldinst{HYPERLINK "mailto:injectionapp@johnholdsworth.com"}}{\fldrslt injectionapp@johnholdsworth.com}} {\field{\*\fldinst{HYPERLINK "https://twitter.com/Injection4Xcode"}}{\fldrslt \f2\fs24 \cf2 \expnd0\expndtw0\kerning0 @Injection4Xcode}}\ \ \pard\pardeftab720\partightenfactor0 \f3\fs24 \cf0 \expnd0\expndtw0\kerning0 Permission is hereby granted, free of charge, to any person obtaining a copy\ of this software and associated documentation files (the "Software"), to deal\ in the Software without restriction, including without limitation the rights\ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ copies of the Software, and to permit persons to whom the Software is\ furnished to do so, subject to the following conditions:\ \ The above copyright notice and this permission notice shall be included in\ all copies or substantial portions of the Software.\ \ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. \ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, \ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE \ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \f1\fs22 \cf0 \kerning1\expnd0\expndtw0 \ This release includes software licensed by the original copyright holder to be used under the terms of this license:\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/injectionforxcode"}}{\fldrslt \cf0 injectionforxcode}} - engine for build and reload of code\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/Smuggler"}}{\fldrslt \cf0 Smuggler}} - prototype for injecting code into simulator\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/Xprobe"}}{\fldrslt \cf0 Xprobe}} - realtime app memory browser\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/Xtrace"}}{\fldrslt \cf0 Xtrace}} - Objective-C message tracing\ \ {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/Refactorator"}}{\fldrslt Refactorator}} - original Xcode refactoring plugin\ {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/RefactoratorApp"}}{\fldrslt RefactoratorApp}} - App version of Refactorator\ \ {\field{\*\fldinst{HYPERLINK "https://github.com/johnno1962/Remote"}}{\fldrslt Remote}} - remote control of iOS devices\ \ Included in this release is software from the following sources under their respective licenses:\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/davedelong/DDHotKey"}}{\fldrslt \cf0 davedelong/DDHotKey}} - create ^= hotkey for injection\ \ \pard\pardeftab720\partightenfactor0 \f3 \cf0 \expnd0\expndtw0\kerning0 The license for this framework is included in every source file, and is repoduced in its entirety here:\ \ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. The software is provided "as is", without warranty of any kind, including all implied warranties of merchantability and fitness. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \f1 \cf0 \kerning1\expnd0\expndtw0 \ \pard\tx543\pardeftab543\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/jpsim/SourceKitten"}}{\fldrslt \cf0 jpsim/SourceKitten}} - dynamic loading of SourceKit on demand\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \cf0 \ \pard\pardeftab720\partightenfactor0 \f3 \cf0 \expnd0\expndtw0\kerning0 The MIT License (MIT)\ \ Copyright (c) 2014 JP Simard.\ \ Permission is hereby granted, free of charge, to any person obtaining a copy\ of this software and associated documentation files (the "Software"), to deal\ in the Software without restriction, including without limitation the rights\ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ copies of the Software, and to permit persons to whom the Software is\ furnished to do so, subject to the following conditions:\ \ The above copyright notice and this permission notice shall be included in all\ copies or substantial portions of the Software.\ \ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\ SOFTWARE.\ \pard\pardeftab720\partightenfactor0 \f1 \cf0 \kerning1\expnd0\expndtw0 \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://github.com/rentzsch/mach_inject"}}{\fldrslt \cf0 rentzsch/mach_inject}} - inter-process code injection\ \ \pard\pardeftab720\partightenfactor0 \f3 \cf0 \expnd0\expndtw0\kerning0 // Copyright (c) 2003-2016 Jonathan 'Wolf' Rentzsch: http://rentzsch.com\ // Some rights reserved: http://opensource.org/licenses/mit\ // https://github.com/rentzsch/mach_inject\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 \f1 \cf0 \kerning1\expnd0\expndtw0 \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://code.google.com/archive/p/canviz"}}{\fldrslt \cf0 canviz}} - Visualisation of dot graphs in WebView canvas\ \ License in application package.\ \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://codemirror.net/"}}{\fldrslt \cf0 codemirror.net}} - Code editor for Xprobe eval against instance\ \ License in application package.} ================================================ FILE: Injectorator/INController.swift ================================================ // // InjectionMenuController.swift // Injectorator // // Created by John Holdsworth on 22/12/2016. // Copyright © 2016 John Holdsworth. All rights reserved. // import Cocoa class INController: INPluginMenuController { var project: Project? { if Integration.shared.appDelegate.state.project == nil { Integration.shared.appDelegate.state.project = Project(target: nil) } return Integration.shared.appDelegate.state.project } override func workspacePath() -> String! { return project?.workspacePath } override func buildDirectory() -> String! { return project?.derivedData.url.appendingPathComponent("Build").path ?? "Unknown project deerived data" } override func logDirectory() -> String! { return project?.derivedData.url.appendingPathComponent("Logs/Build").path ?? "Unknown project deerived data" } override func enableFileWatcher(_ enabled: Bool) { super.enableFileWatcher(enabled) Integration.shared.updateState(newState: enabled ? .connected : .idle) } @IBAction func showTunable(sender: AnyObject!) { client.paramsPanel.makeKeyAndOrderFront(sender) } @IBAction func showConsole(sender: AnyObject!) { client.consolePanel.makeKeyAndOrderFront(sender) } @objc (injectSource:) @IBAction func injectSource(_ sender: AnyObject!) { Integration.shared.injectSource(sender: sender) } override func xcodeApp() -> String! { if let xcodeApp = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.dt.Xcode") .first?.bundleURL?.path { return xcodeApp } let appName = project?.xCode?.className.replacingOccurrences(of: "Application", with: "") return "/Applications/\(appName ?? "Xcode").app" } } ================================================ FILE: Injectorator/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDocumentTypes CFBundleTypeExtensions swift m h CFBundleTypeIconFile document.icns CFBundleTypeMIMETypes text/css CFBundleTypeName Swift Source CFBundleTypeRole Viewer NSDocumentClass AppDelegate CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIconFile App CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 2.7 CFBundleVersion 625 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright Copyright © 2016 John Holdsworth. All rights reserved. NSMainNibFile MainMenu NSPrincipalClass NSApplication NSServices NSKeyEquivalent default ~ NSMenuItem default Injection/Inject Source NSMessage inject NSPortName Injection NSRequiredContext NSSendTypes NSStringPboardType public.plain-text NSMenuItem default Injection/Inject File NSMessage injectFile NSPortName Injection NSRequiredContext NSTextContent FilePath NSSendTypes NSStringPboardType public.plain-text NSURLPboardType public.url public.file-url NSMenuItem default Injection/Load Xprobe NSMessage xprobe NSPortName Injection NSRequiredContext NSSendTypes NSStringPboardType public.plain-text SMPrivilegedExecutables com.johnholdsworth.Injectorator.Helper identifier com.johnholdsworth.Injectorator.Helper ================================================ FILE: Injectorator/Injectorator-Bridging-Header.h ================================================ // // Use this file to import your target's public headers that you would like to expose to Swift. // #import #import #import "sourcekitd.h" #import "Xcode.h" #import "Utils.h" #import "INPluginMenuController.h" #import "INPluginClientController.h" #import "XprobePluginMenuController.h" #import "RMPluginController.h" #import "HelperInstaller.h" #import "HelperProxy.h" #import #import #import "DDHotKeyCenter.h" #define SWIFT_INJECTION_PORT INJECTION_PORT #define SWIFT_REMOTE_PORT REMOTE_PORT ================================================ FILE: Injectorator/Integration.swift ================================================ // // SubApp.swift // Injectorator // // Created by John Holdsworth on 21/12/2016. // Copyright © 2016 John Holdsworth. All rights reserved. // import Foundation //let kVK_ANSI_Equal: UInt16 = 0x18 class Integration: NSObject { static var shared: Integration! @IBOutlet var injection: INPluginMenuController! @IBOutlet var xprobe: XprobePluginMenuController! @IBOutlet var mainMenu: NSMenu! @IBOutlet var statusMenu: NSMenu! private var statusItem: NSStatusItem! var remote: RMPluginController! var appDelegate: AppDelegate! @IBOutlet var delegate: NSApplicationDelegate! init(appDelegate: AppDelegate, count: Int) { super.init() Integration.shared = self self.appDelegate = appDelegate setenv("IS_INJECTION_APP", Bundle.main.bundlePath, 1) signal(SIGPIPE, SIG_IGN) guard let appMenu = NSApplication.shared().mainMenu else { return } Bundle(for:Integration.self).loadNibNamed("Integration", owner: self, topLevelObjects: nil) let notification = Notification(name: .NSApplicationDidFinishLaunching) injection.applicationDidFinishLaunching(notification) xprobe.applicationDidFinishLaunching(notification) xprobe.injectionPlugin = INPluginMenuController.self injectionPlugin = injection xprobePlugin = xprobe appMenu.item(at: 0)?.submenu = mainMenu #if swift(>=3.2) appMenu.removeItem(at: 1) statusMenu.item(withTitle: "Refactor Swift")?.isHidden = true #else appMenu.item(at: 1)?.submenu?.title = "Refactorator" #endif let statusBar = NSStatusBar.system() statusItem = statusBar.statusItem(withLength: statusBar.thickness) statusItem.toolTip = "Injectorator" statusItem.highlightMode = true statusItem.menu = statusMenu statusItem.isEnabled = true statusItem.title = "" updateState(newState: .idle) _ = DDHotKeyCenter.shared()?.registerHotKey(withKeyCode: UInt16(kVK_ANSI_Equal), modifierFlags: NSEventModifierFlags.control.rawValue, target: self, action: #selector(injectSource(sender:)), object: nil) let expires = Date(timeIntervalSince1970: 1515929737.02325)//timeIntervalSinceNow:(2*31+8)*24*60*60) print("If not licensed, this copy will expire on: \(expires) \(expires.timeIntervalSince1970)") if !appDelegate.licensed && Date() > expires { let alert = NSAlert() alert.messageText = "Injection" alert.informativeText = "An update is available for Injection, please download a new copy" alert.runModal() appDelegate.help(sender: nil) NSApp.terminate(nil) return } } @discardableResult func error(_ msg: String) -> NSModalResponse { NSApp.activate(ignoringOtherApps: true) print("Error: \(msg)") let alert = NSAlert() alert.messageText = "Injection App" alert.informativeText = msg return alert.runModal() } func pathForResource( name: String, ofType ext: String! ) -> String! { if let path = Bundle.main.path(forResource: name, ofType: ext) { return path } else { error("Could not locate resource \(name).\(ext)" ) return nil } } func setMenuIcon( tiffName: String ) { if let path = pathForResource( name: tiffName, ofType:"tif" ) { statusItem.image = NSImage( contentsOfFile:path ) statusItem.alternateImage = statusItem.image } } func updateState( newState: INBundleState ) { switch (newState) { case .idle: setMenuIcon(tiffName: "InjectionIdle") case .connected: setMenuIcon(tiffName: "InjectionOK") default: error("Invalid status \(newState.rawValue)") break } } func injectTooling(file: String? = nil) -> String? { let bundlePath = pathForResource(name: "InjectionLoader", ofType: "bundle") appDelegate.state.project = Project(target: file != nil ? Entity(file: file!) : nil) do { if !injection.client.connected() { if !HelperInstaller.isInstalled() { error( "Injection needs to install a privileged helper to be able to inject code into " + "an app running in the simulator. This is a standard macOS mechanism. " + "You can remove the helper at any time by deleting:\n " + "/Library/PrivilegedHelperTools/com.johnholdsworth.Injectorator.Helper.\n" + "If you'd rather not authorize, you can select \"macOS Project/Patch App\" " + "and use patched injection instead." ) try HelperInstaller.install() } try HelperProxy.inject( bundlePath ) for _ in 0..<50 { RunLoop.main.run(until: Date(timeIntervalSinceNow: 0.1)) if injection.client.connected() { NSApp.hide(nil) return appDelegate.state.project?.entity?.file } } error( "Timeout waiting for connection from client app" ) return nil } NSApp.hide(nil) return appDelegate.state.project?.entity?.file } catch (let err as NSError) { print("Couldn't install Injection Helper (domain: \(err.domain) code: \(err.code))") error( "Injection Error:\n\(err.localizedDescription)" ) } return nil } func runInjection( file: String ) { injection.client.runScript("injectSource.pl", withArg: file) injection.lastInjected[file] = NSDate() injection.lastFile = file } @IBAction func injectSource(sender: AnyObject!) { if let file = injectTooling() { runInjection(file: file) } } @IBAction func fileWatcher(sender: NSMenuItem!) { sender.state = 1-sender.state injection.watchButton.state = sender.state injection.watchChanged(sender) } @IBAction func patchProject(sender: AnyObject!) { appDelegate.state.project = Project(target: nil) injection.client.runScript("patchProject.pl", withArg: "\(SWIFT_INJECTION_PORT)") } @IBAction func revertProject(sender: AnyObject!) { appDelegate.state.project = Project(target: nil) injection.client.runScript("revertProject.pl", withArg: "") } @IBAction func bundleProject(sender: AnyObject!) { appDelegate.state.project = Project(target: nil) injection.client.runScript("openBundle.pl", withArg: "") } @IBAction func osxXprobe(sender: AnyObject!) { if let path = pathForResource(name: "XprobeBundle", ofType: "loader") { injection.client.write("/"+path) } } @IBAction func loadXprobe(sender: AnyObject!) { _ = injectTooling() injection.client.write("+") NSApp.activate(ignoringOtherApps: true) } @IBAction func refactorSwift(sender: AnyObject!) { if let appDelegate = NSApplication.shared().delegate as? AppDelegate { appDelegate.state.setup() appDelegate.window.makeKeyAndOrderFront(sender) } } func initRemote() -> RMPluginController { if remote == nil { remote = RMController() setenv("REMOTE_PORT", "\(SWIFT_REMOTE_PORT)", 1 ) let notification = Notification(name: .NSApplicationDidFinishLaunching) remote.applicationDidFinishLaunching(notification) let title = "Remote Control" let index = statusMenu.indexOfItem(withTitle: title) statusMenu.removeItem(at: index) remote.remoteMenu.title = title statusMenu.insertItem(remote.remoteMenu, at: index) remote.remoteMenu.submenu?.item(at: 0)?.isHidden = true } return remote } @IBAction func remotePatch(sender: AnyObject!) { appDelegate.state.project = Project(target: nil) initRemote().runScript("patch") } @IBAction func remoteUnpatch(sender: AnyObject!) { appDelegate.state.project = Project(target: nil) initRemote().runScript("unpatch") } @IBAction func terminate(sender: AnyObject!) { NSApp.terminate(sender) } } extension AppDelegate { func applicationWillTerminate(_ notification: Notification) { _ = DDHotKeyCenter.shared()?.unregisterHotKey(withKeyCode: UInt16(kVK_ANSI_Equal), modifierFlags: NSEventModifierFlags.control.rawValue) } @IBAction func help(sender: NSMenuItem!) { state.open(url: "http://johnholdsworth.com/injection.html?index=\(myIndex)") } @IBAction func donate(sender: NSMenuItem!) { state.open(url: "http://johnholdsworth.com/cgi-bin/injection.cgi?index=\(myIndex)") } @objc func inject(_ pboard: NSPasteboard, userData: String, error: NSErrorPointer) { _ = pboard.string(forType: NSPasteboardTypeString) Integration.shared.injectSource(sender: nil) } @objc func injectFile(_ pboard: NSPasteboard, userData: String, error: NSErrorPointer) { let options = [NSPasteboardURLReadingFileURLsOnlyKey:true] if let fileURLs = pboard.readObjects(forClasses: [NSURL.self], options: options), let file = (fileURLs.first as? NSURL)?.path { _ = Integration.shared.injectTooling(file: file) Integration.shared.runInjection(file: file) } } @objc func xprobe(_ pboard: NSPasteboard, userData: String, error: NSErrorPointer) { _ = pboard.string(forType: NSPasteboardTypeString) Integration.shared.loadXprobe(sender: nil) } } // ['Snow', 'DarkKhaki', 'IndianRed', 'MistyRose', 'DarkGrey', 'FloralWhite', 'LightGreen', 'DeepSkyBlue', 'Gainsboro', 'Aquamarine', 'Khaki', 'Sienna', 'Purple', 'SlateGray', 'HotPink', 'White', 'PowderBlue', 'DarkGreen', 'PapayaWhip', 'OliveDrab', 'DarkOrange', 'Yellow', 'Crimson', 'MediumBlue', 'DarkMagenta', 'PeachPuff', 'LightCyan', 'MediumOrchid', 'Lime', 'GreenYellow', 'Gold', 'SlateGrey', 'LightYellow', 'Linen', 'DarkSlateGrey', 'PaleVioletRed', 'AliceBlue', 'MediumSeaGreen', 'LightSlateGrey', 'LawnGreen', 'LightGoldenRodYellow', 'SpringGreen', 'Chocolate', 'RoyalBlue', 'DimGrey', 'MediumSlateBlue', 'DarkOrchid', 'CadetBlue', 'PaleGoldenRod', 'BlanchedAlmond', 'Cornsilk', 'CornflowerBlue', 'PaleTurquoise', 'ForestGreen', 'YellowGreen', 'GoldenRod', 'Coral', 'SandyBrown', 'Wheat', 'Tan', 'Black', 'LavenderBlush', 'Turquoise', 'DarkCyan', 'WhiteSmoke', 'OldLace', 'SeaGreen', 'LightSteelBlue', 'DimGray', 'Ivory', 'Salmon', 'Olive', 'HoneyDew', 'Red', 'Beige', 'DarkGray', 'Green', 'DarkBlue', 'Bisque', 'Moccasin', 'Pink', 'LightSalmon', 'DarkSeaGreen', 'LightSlateGray', 'BlueViolet', 'GhostWhite', 'FireBrick', 'DarkRed', 'Orange', 'OrangeRed', 'DarkOliveGreen', 'LightSkyBlue', 'MediumTurquoise', 'DarkSalmon', 'NavajoWhite', 'RosyBrown', 'SteelBlue', 'LightBlue', 'SeaShell', 'SkyBlue', 'DarkSlateGray', 'LimeGreen', 'LightCoral', 'LightSeaGreen', 'SaddleBrown', 'MediumVioletRed', 'Azure', 'Thistle', 'Lavender', 'DarkSlateBlue', 'LightGrey', 'Chartreuse', 'Navy', 'Teal', 'Indigo', 'MediumSpringGreen', 'RebeccaPurple', 'Orchid', 'Tomato', 'PaleGreen', 'Aqua', 'Grey', 'MediumAquaMarine', 'DarkGoldenRod', 'LightGray', 'Violet', 'Fuchsia', 'Magenta', 'DodgerBlue', 'Maroon', 'DarkViolet', 'DeepPink', 'MidnightBlue', 'AntiqueWhite', 'SlateBlue', 'Blue', 'BurlyWood', 'Brown', 'Peru', 'Silver', 'LightPink', 'MediumPurple', 'MintCream', 'Plum', 'Cyan', 'Gray', 'DarkTurquoise', 'LemonChiffon'] let colors = String(data: Data(base64Encoded: "U25vdzpEYXJrS2hha2k6SW5kaWFuUmVkOk1pc3R5Um9zZTpEYXJrR3JleTpGbG9yYWxXaGl0ZTpMaWdodEdyZWVuOkRlZXBTa3lCbHVlOkdhaW5zYm9ybzpBcXVhbWFyaW5lOktoYWtpOlNpZW5uYTpQdXJwbGU6U2xhdGVHcmF5OkhvdFBpbms6V2hpdGU6UG93ZGVyQmx1ZTpEYXJrR3JlZW46UGFwYXlhV2hpcDpPbGl2ZURyYWI6RGFya09yYW5nZTpZZWxsb3c6Q3JpbXNvbjpNZWRpdW1CbHVlOkRhcmtNYWdlbnRhOlBlYWNoUHVmZjpMaWdodEN5YW46TWVkaXVtT3JjaGlkOkxpbWU6R3JlZW5ZZWxsb3c6R29sZDpTbGF0ZUdyZXk6TGlnaHRZZWxsb3c6TGluZW46RGFya1NsYXRlR3JleTpQYWxlVmlvbGV0UmVkOkFsaWNlQmx1ZTpNZWRpdW1TZWFHcmVlbjpMaWdodFNsYXRlR3JleTpMYXduR3JlZW46TGlnaHRHb2xkZW5Sb2RZZWxsb3c6U3ByaW5nR3JlZW46Q2hvY29sYXRlOlJveWFsQmx1ZTpEaW1HcmV5Ok1lZGl1bVNsYXRlQmx1ZTpEYXJrT3JjaGlkOkNhZGV0Qmx1ZTpQYWxlR29sZGVuUm9kOkJsYW5jaGVkQWxtb25kOkNvcm5zaWxrOkNvcm5mbG93ZXJCbHVlOlBhbGVUdXJxdW9pc2U6Rm9yZXN0R3JlZW46WWVsbG93R3JlZW46R29sZGVuUm9kOkNvcmFsOlNhbmR5QnJvd246V2hlYXQ6VGFuOkJsYWNrOkxhdmVuZGVyQmx1c2g6VHVycXVvaXNlOkRhcmtDeWFuOldoaXRlU21va2U6T2xkTGFjZTpTZWFHcmVlbjpMaWdodFN0ZWVsQmx1ZTpEaW1HcmF5Okl2b3J5OlNhbG1vbjpPbGl2ZTpIb25leURldzpSZWQ6QmVpZ2U6RGFya0dyYXk6R3JlZW46RGFya0JsdWU6QmlzcXVlOk1vY2Nhc2luOlBpbms6TGlnaHRTYWxtb246RGFya1NlYUdyZWVuOkxpZ2h0U2xhdGVHcmF5OkJsdWVWaW9sZXQ6R2hvc3RXaGl0ZTpGaXJlQnJpY2s6RGFya1JlZDpPcmFuZ2U6T3JhbmdlUmVkOkRhcmtPbGl2ZUdyZWVuOkxpZ2h0U2t5Qmx1ZTpNZWRpdW1UdXJxdW9pc2U6RGFya1NhbG1vbjpOYXZham9XaGl0ZTpSb3N5QnJvd246U3RlZWxCbHVlOkxpZ2h0Qmx1ZTpTZWFTaGVsbDpTa3lCbHVlOkRhcmtTbGF0ZUdyYXk6TGltZUdyZWVuOkxpZ2h0Q29yYWw6TGlnaHRTZWFHcmVlbjpTYWRkbGVCcm93bjpNZWRpdW1WaW9sZXRSZWQ6QXp1cmU6VGhpc3RsZTpMYXZlbmRlcjpEYXJrU2xhdGVCbHVlOkxpZ2h0R3JleTpDaGFydHJldXNlOk5hdnk6VGVhbDpJbmRpZ286TWVkaXVtU3ByaW5nR3JlZW46UmViZWNjYVB1cnBsZTpPcmNoaWQ6VG9tYXRvOlBhbGVHcmVlbjpBcXVhOkdyZXk6TWVkaXVtQXF1YU1hcmluZTpEYXJrR29sZGVuUm9kOkxpZ2h0R3JheTpWaW9sZXQ6RnVjaHNpYTpNYWdlbnRhOkRvZGdlckJsdWU6TWFyb29uOkRhcmtWaW9sZXQ6RGVlcFBpbms6TWlkbmlnaHRCbHVlOkFudGlxdWVXaGl0ZTpTbGF0ZUJsdWU6Qmx1ZTpCdXJseVdvb2Q6QnJvd246UGVydTpTaWx2ZXI6TGlnaHRQaW5rOk1lZGl1bVB1cnBsZTpNaW50Q3JlYW06UGx1bTpDeWFuOkdyYXk6RGFya1R1cnF1b2lzZTpMZW1vbkNoaWZmb24=")!, encoding: .utf8 )!.components(separatedBy: ":") ================================================ FILE: Injectorator/Integration.xib ================================================