@@ -74,6 +74,14 @@ The string is splitted by spaces, then unquoted."
7474 :group 'swift-mode:repl
7575 :safe 'stringp )
7676
77+ (defcustom swift-mode:ios-deploy-executable
78+ " ios-deploy"
79+ " Path to ios-deploy command.
80+ The string is splitted by spaces, then unquoted."
81+ :type '(choice string (list string))
82+ :group 'swift-mode:repl
83+ :safe 'stringp )
84+
7785(defcustom swift-mode:simulator-controller-executable
7886 " xcrun simctl"
7987 " Path to the simulator controller command.
@@ -116,8 +124,12 @@ cdr is used as a command. If its car is a function, it is called to search
116124prompt. It should return non-nil when a prompt is found and return nil
117125otherwise." )
118126
119- (defvar swift-mode:ios-simulator-device-identifier nil
120- " Device identifier of iOS simulator for building/debugging." )
127+ (defvar swift-mode:ios-device-identifier nil
128+ " Identifier of iOS device used for building/debugging." )
129+
130+ (defconst swift-mode:ios-local-device-identifier
131+ " 00000000-0000-0000-0000-000000000000"
132+ " Identifier of local iOS device." )
121133
122134(defvar swift-mode:ios-project-scheme nil
123135 " Scheme to use in Xcode project for building/debugging." )
@@ -412,33 +424,48 @@ or its ancestors."
412424 flattened)))
413425 available-devices))
414426
415- (defun swift-mode:read-ios-simulator- device-identifier ()
427+ (defun swift-mode:read-ios-device-identifier ()
416428 " Read a iOS simulator device identifier from the minibuffer."
417429 (let* ((devices (swift-mode:list-ios-simulator-devices))
418- (items (seq-map
419- (lambda (device )
420- (cons (cdr (assoc 'name device))
421- (cdr (assoc 'udid device))))
422- devices)))
430+ (items (append (list (cons " Local device"
431+ swift-mode:ios-local-device-identifier))
432+ (seq-map
433+ (lambda (device )
434+ (cons (cdr (assoc 'name device))
435+ (cdr (assoc 'udid device))))
436+ devices))))
423437 (widget-choose " Choose a device" items)))
424438
425439(defun swift-mode:read-xcode-build-settings (project-directory
426- device-identifier
427- scheme )
440+ scheme
441+ sdk
442+ device-identifier )
428443 " Read Xcode build settings in PROJECT-DIRECTORY.
429444
430- DEVICE-IDENTIFIER is used as the destination parameter for xcodebuild.
431- SCHEME is the name of the project scheme in Xcode."
445+ SCHEME is the name of the project scheme in Xcode.
446+ SDK is the name of the SDK build against.
447+ DEVICE-IDENTIFIER is used as the destination parameter for xcodebuild. If
448+ identifier is equal to `swift-mode:ios-local-device-identifier' , it is not
449+ passed as a destination to xcodebuild."
432450 (with-temp-buffer
433- (let ((default-directory project-directory))
434- (unless (zerop (swift-mode:call-process
435- swift-mode:xcodebuild-executable
436- " -configuration" " Debug"
437- " -destination"
438- (concat " platform=iOS Simulator,id=" device-identifier)
439- " -sdk" " iphonesimulator"
440- " -scheme" scheme
441- " -showBuildSettings" ))
451+ (let ((default-directory project-directory)
452+ (arglist `(, swift-mode:xcodebuild-executable
453+ " -configuration"
454+ " Debug"
455+ " -sdk"
456+ , sdk
457+ " -scheme"
458+ , scheme
459+ " -showBuildSettings" )))
460+ (when (and device-identifier
461+ (not (eql device-identifier
462+ swift-mode:ios-local-device-identifier)))
463+ (setq arglist
464+ (append arglist
465+ `(" -destination"
466+ ,(concat " platform=iOS Simulator,id=" device-identifier)
467+ ))))
468+ (unless (zerop (apply #'swift-mode:call-process arglist))
442469 (error " %s %s " " Cannot read Xcode build settings" (buffer-string ))))
443470 (goto-char (point-min ))
444471 (let ((settings nil ))
@@ -524,12 +551,11 @@ An list ARGS are appended for builder command line arguments."
524551 device-identifier
525552 scheme )
526553 " Build an iOS app in the PROJECT-DIRECTORY.
527-
528- Build it for iOS simulator device DEVICE-IDENTIFIER for the given SCHEME.
554+ Build it for iOS device DEVICE-IDENTIFIER for the given SCHEME.
529555If PROJECT-DIRECTORY is nil or omitted, it is searched from `default-directory'
530556or its ancestors.
531557DEVICE-IDENTIFIER is the device identifier of the iOS simulator. If it is nil
532- or omitted, the value of `swift-mode:ios-simulator- device-identifier' is used.
558+ or omitted, the value of `swift-mode:ios-device-identifier' is used.
533559SCHEME is the name of the project scheme in Xcode. If it is nil or omitted,
534560the value of `swift-mode:ios-project-scheme' is used."
535561 (interactive
@@ -539,8 +565,8 @@ the value of `swift-mode:ios-project-scheme' is used."
539565 (list
540566 project-directory
541567 (if current-prefix-arg
542- (swift-mode:read-ios-simulator- device-identifier)
543- swift-mode:ios-simulator- device-identifier)
568+ (swift-mode:read-ios-device-identifier)
569+ swift-mode:ios-device-identifier)
544570 (if current-prefix-arg
545571 (swift-mode:read-project-scheme project-directory)
546572 swift-mode:ios-project-scheme))))
@@ -549,9 +575,9 @@ the value of `swift-mode:ios-project-scheme' is used."
549575 (unless device-identifier
550576 (setq device-identifier
551577 (or
552- swift-mode:ios-simulator- device-identifier
553- (swift-mode:read-ios-simulator- device-identifier))))
554- (setq swift-mode:ios-simulator- device-identifier device-identifier)
578+ swift-mode:ios-device-identifier
579+ (swift-mode:read-ios-device-identifier))))
580+ (setq swift-mode:ios-device-identifier device-identifier)
555581 (unless scheme
556582 (setq scheme
557583 (or
@@ -562,17 +588,21 @@ the value of `swift-mode:ios-project-scheme' is used."
562588 (with-current-buffer (get-buffer-create " *swift-mode:compilation*" )
563589 (fundamental-mode )
564590 (setq buffer-read-only nil )
565- (let ((progress-reporter (make-progress-reporter " Building..." )))
566- (unless
591+ (let ((progress-reporter (make-progress-reporter " Building..." ))
592+ (xcodebuild-args `(, swift-mode:xcodebuild-executable
593+ " -configuration" " Debug"
594+ " -scheme" , scheme )))
595+ (if (eql device-identifier swift-mode:ios-local-device-identifier)
596+ (setq xcodebuild-args (append xcodebuild-args '(" -sdk" " iphoneos" )))
597+ (setq xcodebuild-args
598+ (append xcodebuild-args
599+ `(" -destination"
600+ ,(concat " platform=iOS Simulator,id=" device-identifier)
601+ " -sdk" " iphonesimulator" ))))
602+ (unless
567603 (zerop
568604 (let ((default-directory project-directory))
569- (swift-mode:call-process
570- swift-mode:xcodebuild-executable
571- " -configuration" " Debug"
572- " -scheme" scheme
573- " -destination"
574- (concat " platform=iOS Simulator,id=" device-identifier)
575- " -sdk" " iphonesimulator" )))
605+ (apply 'swift-mode:call-process xcodebuild-args)))
576606 (compilation-mode )
577607 (goto-char (point-min ))
578608 (pop-to-buffer (current-buffer ))
@@ -751,17 +781,104 @@ PROCESS-IDENTIFIER is the process ID."
751781 (goto-char comint-last-input-end)
752782 (search-forward expected-output nil t )))
753783
784+ ;;;### autoload
785+ (defun swift-mode:debug-ios-app-on-device (project-directory
786+ scheme
787+ codesigning-folder-path )
788+ " Run debugger on an iOS app in the PROJECT-DIRECTORY.
789+ Run it for the iOS local device DEVICE-IDENTIFIER for the given SCHEME.
790+ CODESIGNING-FOLDER-PATH is the path of the codesigning folder in Xcode
791+ build settings."
792+ (swift-mode:build-ios-app project-directory
793+ swift-mode:ios-local-device-identifier
794+ scheme)
795+ (swift-mode:run-repl
796+ (append
797+ (swift-mode:command-string-to-list swift-mode:ios-deploy-executable)
798+ (list " --debug" " --no-wifi" " --bundle" codesigning-folder-path))
799+ nil t ))
800+
801+ ;;;### autoload
802+ (defun swift-mode:debug-ios-app-on-simulator (project-directory
803+ device-identifier
804+ scheme
805+ codesigning-folder-path
806+ product-bundle-identifier )
807+ " Run debugger on an iOS app in the PROJECT-DIRECTORY.
808+ Run it for the iOS simulator DEVICE-IDENTIFIER for the given SCHEME.
809+ DEVICE-IDENTIFIER is the device identifier of the iOS simulator.
810+ SCHEME is the name of the project scheme in Xcode.
811+ CODESIGNING-FOLDER-PATH is the path of the codesigning folder used in Xcode
812+ build settings.
813+ PRODUCT-BUNDLE-IDENTIFIER is the name of the product bundle identifier used
814+ in Xcode build settings."
815+ (swift-mode:build-ios-app project-directory device-identifier scheme)
816+ (let* ((devices (swift-mode:list-ios-simulator-devices))
817+ (target-device
818+ (seq-find
819+ (lambda (device )
820+ (string-equal (cdr (assoc 'udid device)) device-identifier))
821+ devices))
822+ (active-devices
823+ (seq-filter
824+ (lambda (device )
825+ (string-equal (cdr (assoc 'state device)) " Booted" ))
826+ devices))
827+ (target-booted
828+ (string-equal (cdr (assoc 'state target-device)) " Booted" ))
829+ (simulator-running (consp active-devices))
830+ (progress-reporter
831+ (make-progress-reporter " Waiting for simulator..." )))
832+ (cond
833+ (target-booted
834+ ; ; The target device is already booted. Does nothing.
835+ t )
836+ (simulator-running
837+ (swift-mode:kill-ios-simulator)
838+ (swift-mode:open-ios-simulator device-identifier))
839+ (t (swift-mode:open-ios-simulator device-identifier)))
840+
841+ (swift-mode:wait-for-ios-simulator device-identifier)
842+
843+ (progress-reporter-done progress-reporter)
844+
845+ (let ((progress-reporter (make-progress-reporter " Installing app..." )))
846+ (swift-mode:install-ios-app device-identifier codesigning-folder-path)
847+ (progress-reporter-done progress-reporter))
848+
849+ (let ((progress-reporter (make-progress-reporter " Launching app..." ))
850+ (process-identifier
851+ (swift-mode:launch-ios-app
852+ device-identifier product-bundle-identifier t )))
853+ (progress-reporter-done progress-reporter)
854+ (swift-mode:run-repl
855+ (append
856+ (swift-mode:command-string-to-list swift-mode:debugger-executable)
857+ (list " --" codesigning-folder-path))
858+ nil t )
859+ (swift-mode:enqueue-repl-commands
860+ " platform select ios-simulator"
861+ (concat " platform connect " device-identifier)
862+ (concat " process attach --pid " (number-to-string process-identifier))
863+ " breakpoint set --one-shot true --name UIApplicationMain"
864+ " cont"
865+ (cons
866+ (lambda (_string )
867+ (swift-mode:search-process-stopped-message process-identifier))
868+ " repl" )))))
869+
754870;;;### autoload
755871(defun swift-mode:debug-ios-app (&optional project-directory
756872 device-identifier
757873 scheme )
758874 " Run debugger on an iOS app in the PROJECT-DIRECTORY.
759-
760- Run it for iOS simulator device DEVICE-IDENTIFIER for the given SCHEME.
875+ Run it for the iOS simulator devie DEVICE-IDENTIFIER for the given SCHEME.
761876If PROJECT-DIRECTORY is nil or omitted, it is searched from `default-directory'
762877or its ancestors.
763- DEVICE-IDENTIFIER is the device identifier of the iOS simulator. If it is nil
764- or omitted, the value of `swift-mode:ios-simulator-device-identifier' is used.
878+ DEVICE-IDENTIFIER is the device identifier of the iOS simulator. If it is
879+ nil or omitted, the value of `swift-mode:ios-device-identifier' is used. If
880+ it is equal to `swift-mode:ios-local-device-identifier' , a local build via
881+ `ios-deploy' is generated instead.
765882SCHEME is the name of the project scheme in Xcode. If it is nil or omitted,
766883the value of `swift-mode:ios-project-scheme' is used."
767884 (interactive
@@ -771,8 +888,8 @@ the value of `swift-mode:ios-project-scheme' is used."
771888 (list
772889 project-directory
773890 (if current-prefix-arg
774- (swift-mode:read-ios-simulator- device-identifier)
775- swift-mode:ios-simulator- device-identifier)
891+ (swift-mode:read-ios-device-identifier)
892+ swift-mode:ios-device-identifier)
776893 (if current-prefix-arg
777894 (swift-mode:read-project-scheme project-directory)
778895 swift-mode:ios-project-scheme))))
@@ -781,20 +898,24 @@ the value of `swift-mode:ios-project-scheme' is used."
781898 (unless device-identifier
782899 (setq device-identifier
783900 (or
784- swift-mode:ios-simulator- device-identifier
785- (swift-mode:read-ios-simulator- device-identifier))))
786- (setq swift-mode:ios-simulator- device-identifier device-identifier)
901+ swift-mode:ios-device-identifier
902+ (swift-mode:read-ios-device-identifier))))
903+ (setq swift-mode:ios-device-identifier device-identifier)
787904 (unless scheme
788905 (setq scheme
789906 (or
790907 swift-mode:ios-project-scheme
791908 (swift-mode:read-project-scheme project-directory))))
792909 (setq swift-mode:ios-project-scheme scheme)
793- (let* ((build-settings
910+ (let* ((local-device-build (eql device-identifier
911+ swift-mode:ios-local-device-identifier))
912+ (sdk (if local-device-build " iphoneos" " iphonesimulator" ))
913+ (build-settings
794914 (swift-mode:read-xcode-build-settings
795915 project-directory
796- device-identifier
797- scheme))
916+ scheme
917+ sdk
918+ device-identifier))
798919 (codesigning-folder-path
799920 (cdr (assoc " CODESIGNING_FOLDER_PATH" build-settings)))
800921 (product-bundle-identifier
@@ -803,63 +924,16 @@ the value of `swift-mode:ios-project-scheme' is used."
803924 (error " Cannot get codesigning folder path " ))
804925 (unless product-bundle-identifier
805926 (error " Cannot get product bundle identifier " ))
806- (swift-mode:build-ios-app project-directory
807- device-identifier
808- scheme)
809-
810- (let* ((devices (swift-mode:list-ios-simulator-devices))
811- (target-device
812- (seq-find
813- (lambda (device )
814- (string-equal (cdr (assoc 'udid device)) device-identifier))
815- devices))
816- (active-devices
817- (seq-filter
818- (lambda (device )
819- (string-equal (cdr (assoc 'state device)) " Booted" ))
820- devices))
821- (target-booted
822- (string-equal (cdr (assoc 'state target-device)) " Booted" ))
823- (simulator-running (consp active-devices))
824- (progress-reporter
825- (make-progress-reporter " Waiting for simulator..." )))
826- (cond
827- (target-booted
828- ; ; The target device is already booted. Does nothing.
829- t )
830- (simulator-running
831- (swift-mode:kill-ios-simulator)
832- (swift-mode:open-ios-simulator device-identifier))
833- (t (swift-mode:open-ios-simulator device-identifier)))
834-
835- (swift-mode:wait-for-ios-simulator device-identifier)
836-
837- (progress-reporter-done progress-reporter)
838927
839- (let ((progress-reporter (make-progress-reporter " Installing app..." )))
840- (swift-mode:install-ios-app device-identifier codesigning-folder-path)
841- (progress-reporter-done progress-reporter))
842-
843- (let ((progress-reporter (make-progress-reporter " Launching app..." ))
844- (process-identifier
845- (swift-mode:launch-ios-app
846- device-identifier product-bundle-identifier t )))
847- (progress-reporter-done progress-reporter)
848- (swift-mode:run-repl
849- (append
850- (swift-mode:command-string-to-list swift-mode:debugger-executable)
851- (list " --" codesigning-folder-path))
852- nil t )
853- (swift-mode:enqueue-repl-commands
854- " platform select ios-simulator"
855- (concat " platform connect " device-identifier)
856- (concat " process attach --pid " (number-to-string process-identifier))
857- " breakpoint set --one-shot true --name UIApplicationMain"
858- " cont"
859- (cons
860- (lambda (_string )
861- (swift-mode:search-process-stopped-message process-identifier))
862- " repl" ))))))
928+ (if local-device-build
929+ (swift-mode:debug-ios-app-on-device project-directory
930+ scheme
931+ codesigning-folder-path)
932+ (swift-mode:debug-ios-app-on-simulator project-directory
933+ device-identifier
934+ scheme
935+ codesigning-folder-path
936+ product-bundle-identifier))))
863937
864938(provide 'swift-mode-repl )
865939
0 commit comments