SwiftUI: Automatic preview updating paused, always - xcode

I have an existing App, basically a shopping list app, to which I'm trying to add some sweet sweet SwiftUI lovin.
My issue is the real time preview updating doesn't work - the warning "Automatic preview updating paused" continually shows. I hit the resume button, it builds the app, it shows the current view, and that warning immediately shows again. I can never see changes to the code reflected in the canvas without using the resume button.
This is happening in Xcode 11.1, and 11.2 beta 2. I can find literally no other mention of this either here on SO, and there's one thread with no answers on Apple's Dev forums.

If you're having custom Run Script Phases in Build Phases and you don't want (or can't) remove them, then try to check checkbox "Run script only when installing".

The problem with all the given answers is that you need to check or uncheck your script in debug mode if you want to make the preview work.
Here is a convenient alternative using the environment variables.
This is really simple
Embed all the content of your script in an if statement that check if we're using the preview or not. If we're in preview, then don't run the content of your script, otherwise, let's run it. And you don't have to sacrifice your script for release versions only.
Here is the template :
if [ $ENABLE_PREVIEWS == "NO" ]
then
# your code to execute here
else
echo "Skipping the script because of preview mode"
fi
And below a full example that I use to bump my build version number
# xcode-build-bump.sh
# #desc Auto-increment the build number every time the project is run.
# #usage
# 1. Select: your Target in Xcode
# 2. Select: Build Phases Tab
# 3. Select: Add Build Phase -> Add Run Script
# 4. Paste code below in to new "Run Script" section
# 5. Drag the "Run Script" below "Link Binaries With Libraries"
# 6. Insure that your starting build number is set to a whole integer and not a float (e.g. 1, not 1.0)
if [ $ENABLE_PREVIEWS == "NO" ]
then
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
else
echo "Skipping Bump of version"
echo $ENABLE_PREVIEWS
fi

I ended up sending in feedback to Apple, and they responded with a fix. I have a build script in the target that auto-increments the build number. If I remove that script then previewing works as intended.
So if you're having this issue remove anything in Target -> Build Phases -> Run Script and try again. The canvas preview should update as you would expect.

For me, Canvas did not work when I had Legacy Build System.
You can change it via,
File -> Project Settings (or Workspace Settings) -> Build System -> Choose "New Build System(Default).
As it says, it is the default option. If for any reason Legacy build system was chosen, Canvas won't work.
Edit on June 30, 2020:
We no longer have Legacy Build System in Xcode 12 beta.

If you use Xcode 13 or 14 with custom scripts, you must ensure that the script for install builds only is checked in.

What worked for me was to "clean" Xcode
On the Mac
Open Xcode
command+k (Clean console)
command+option+k (Reload console)
command+option+shift+k (Clean build folder)
Exit Xcode
From a terminal window, clean the derived data. I run the following based on where my Xcode is installed. I believe its the base location
rm -rf ~/Library/Developer/Xcode/DerivedData
Re-open xcode and it worked great!

In my experiements I found that ENABLE_PREVIEWS is always set to YES in a SwiftUI project. Instead I found that in normal builds Xcode sets TARGET_DEVICE_MODEL and in SwiftUI it does not.
So the solution is like the one described in this answer: https://stackoverflow.com/a/62216533/833197 but using a different variable.
On another note, setting anything in the Info.plist in a build script seems to be "too late" in recent Xcode versions. It will not be used until next build. Also you end up with a modified version control working copy of your files which might not be what you want.
To resolve this I have
Used a pre-build script in the build scheme instead
Generated a xcconfig with the build number and made it ignored by the version control system (git in my case).
The variables set in a xcconfig file can be referenced in the Info.plist file.

It's strange. But for me automatic preview always fails when I name projects using digits only (i. e. "111"). When naming using letters (with or without digits), everything is ok. 12.3 beta (12C5020f), Big Sur beta 11.1 (20C5048k).

For me it was because i had a pre-actions script in the Build section in the Edit Scheme screen, removing this script got the preview to work as intended

Related

xcode 6 beta 7:A signed resource has been added modified or deleted.

When I'm running the application on device aftercleaning, removing derived data, first time it runs without any issues.
Second time when I'm trying to run, it say's "A signed resource has been added modified or deleted."
On the simulator app run's without problem.
I think it's because of extensions, I have editing, share and today extensions, when I'm deleting this extensions, then I can run second time without this message.
The problem has been since from xcode 6 beta 5.
Maybe issue related to provisioning profiles and signing ? I has created different provisioning profiles for each extension target.
So my question is, how can I fix this ? How can I run on the device second time without cleaning project?
It is still not fixed in XCode 6 RTM. But I found an easy walk around. Simply delete the ShareExtension.appex folder under your build. Then rebuild again. You don't need to clean project, so rebuild is quite fast.
A actually alias the command to do the cleaning
rm -rf ~/Library/Developer/Xcode/DerivedData/<your_app>-*/Build/Products/Debug-iphoneos/ShareExtension.appex/
I used a slight modification of Cloud Xu's script to delete both the .appex and .appex.dSYM
rm -rf ~/Library/Developer/Xcode/DerivedData/YourAppName-*/Build/Products/Debug-iphoneos/com.yourcompany.Name.extension.*
You can put this in your scheme so that it executes with every build:
Edit scheme... > Expand the Run mode in the sidebar > Pre-actions > Click '+' > New Run Script Action.
Edit:
There is an another workaround: for each extension target containing .swift file, add build pre-action in project running scheme configuration:
touch "${PROJECT_DIR}/SOME SWIFT FILE IN EXTENSION.SWIFT"
So I've found a workaround for this issue. For now we can't have swift code in extensions. As mentioned in the comment
When removed all extension targets that contains swift code it's started working normally. I think it's a bug in xcode, for now if we have extension with swift code, don't know why, but second time run gives "A signed resource has been added modified or deleted." error.

How to clean project before each build?

Is there a way (possibly using schemes) in Xcode to specify that a clean is automatically done before doing a new build.?
I have a project that sometimes fails to build unless I do a clean first, currently I am doing it by hand.
Press ⌥⌘R, expand the selected scheme, select Pre-actions, click +, select New Run Script Action, set Provide Build Settings from to your target. In the box below type rm -rf ${BUILT_PRODUCTS_DIR}. Note: it is BUILT not BUILD as seen in the Xcode dialog. You can type echo ${BUILT_PRODUCTS_DIR} > ~/Desktop/log.txt to see what's going to be deleted.
The selected answer did not work for me, it caused my build to fail (Xcode 4.6.3) when trying to run on the simulator.
Based on Jano's answer and on this link in the Pre-action script instead of writing
rm -rf ${BUILT_PRODUCTS_DIR}
I wrote
touch ${BUILT_PRODUCTS_DIR}
This should have the same effect and it doesn't cause my build to fail

How do you change the PATH used in an external makefile build using XCode?

I currently have a project that I'm building with a makefile. This project includes some additional software (jflex) which is not on one of the default system search paths (it's installed to (/opt/local/bin/). My .profile file adds this directory to my PATH, and so building the project from a terminal window succeeds.
However, if I try to run the makefile from within XCode (XCode project with an externally managed makefile), it fails since it's not looking in /opt/local/bin for jflex, and as such can't find it.
How can I change the settings of my XCode project to correctly build from within XCode? I assume there's some kind of path setting in XCode, or some kind of additional argument I can have XCode give to make so that it doesn't fail. Alternately, I could hardcode the path into my makefile if I could detect that it was being run from XCode (although this is the less preferable option for me, since my makefile will sometimes need to be called from the command line and I'd rather keep it simple).
I'm relatively new to using XCode, so apologies if I've missed something obvious.
Instead of calling make directly, you could call a shell script as the "Build Tool" in the "External Build Tool Configuration" pane. Then modify the path in the shell script and call make from there, i.e.
#!/bin/sh
PATH=/opt/local/bin:$PATH
make
Don't forget to set permissions such that Xcode can run the script, and provide the full path to the script as the "Build Tool".
May not be the best way, But can you launch XCode from command line. It will inherit the Path from it.
Or, in the XCode launcher change:
XCode
to
PATH=$PATH:/opt/local/bin/ XCode
may work (depending on launcher)
Or, did you relaunch the launcher/window manager (logout and back in again after setting .profile)?

How to detect XCode vs Makefile build

I'ld like to automatically detect (using #ifdef) whether I'm building using XCode or using make under Darwin. Is there a specific define to XCode or make set automatically by either tool? I'ld like to avoid setting a define in the XCode project or Makefile manually.
If you look in the XCode 'build results' window, and expand one of the "compile MyFile.m" lines (select the line, then click on the "lines of text" icon at the far right), you can see the exact command XCode is using to invoke gcc, including any "-D" options on the command line.
I don't believe make is adding any -D defines automatically.

Xcode source automatic formatting

As a C# developer, I have become highly dependent on the automatic formatting in Visual Studio 2008. Specifically, I will use the CTRL + K , D keyboard shortcut to force things back into shape after my sloppy implementation.
I am now trying to learn Objective-C and am missing certain features in Xcode, but probably none are quite as painful as the formatting shortcut. My Google searches have yielded nothing built in, though it seems there are some hacks. Am I missing something or does this feature not exist natively in Xcode?
That's Ctrl + i.
Or for low-tech, cut and then paste. It'll reformat on paste.
Unfortunately, Xcode doesn't have anything nearly as extensive as VS or Jalopy for Eclipse available. There are SOME disparate features, such as Structure > Re-Indent as well as the auto-formatting used when you paste code into your source file. I am totally with you, though; there definitely should be something in there to help with formatting issues.
I'd like to recommend two options worth considering. Both quite new and evolving.
ClangFormat-Xcode (free) - on each cmd+s file is reformatted to specific style and saved, easy to deploy within team
An Xcode plug-in to format your code using Clang's format tools, by
#travisjeffery.
With clang-format you can use Clang to format your code to styles such
as LLVM, Google, Chromium, Mozilla, WebKit, or your own configuration.
Objective-Clean (paid, didn't try it yet) - app raising build errors if predefined style rules are violated - possibly quite hard to use within the team, so I didn't try it out.
With very minimal setup, you can get Xcode to use our App to enforce
your rules. If you are ever caught violating one of your rules, Xcode
will throw a build error and take you right to the offending line.
In xcode, you can use this shortcut to Re-indent your source code
Go to file, which has indent issues, and follow this :
Cmd + A to select all source codes
Ctrl + I to re-indent
Hope this helps.
My personal fav PrettyC wantabe is uncrustify: http://uncrustify.sourceforge.net/. It's got a few billion options however so I also suggest you download UniversalIndentGUI_macx, (also on sourceforge) a GUI someone wrote to help set the options the way you like them.
You can then add this custom user script to uncrustify the selected text:
#! /bin/sh
#
# uncrustify!
echo -n "%%%{PBXSelection}%%%"
/usr/local/bin/uncrustify -q -c /usr/local/share/uncrustify/geo_uncrustify.cfg -l oc+ <&0
echo -n "%%%{PBXSelection}%%%"
You can use Command + A to select all content and next Ctrl + I to format the selected content.
I also feel xcode should have this function.
So I made an extension to do it: Swimat
Simple install by brew cask install swimat
You can give it a try, see https://github.com/Jintin/Swimat for more information.
Cmd A + Ctrl I
Or Cmd A And then Right Click. Goto Structure -> Re-Indent
Consider buying yourself a license for AppCode, an intelligent Objective-C IDE that helps iOS/OS X developers. AppCode is fully compatible with Xcode, but goes beyond Xcode in adding powerful features.
AppCode an Objective-C variant of the Intellij IDEA IDE from JetBrains. They are also authors of popular ReSharper extension to Visual Studio, which main purpose from here seems like a desperate attempt to bring a touch of IDEA experience to a Microsoft product.
AppCode is using its own code analyser which gives close-to-perfect refactoring and code navigation support. There is an ability to re-indent and completely reformat code also (although I still keep missing a couple of formatting settings in hard cases, but mostly it works well).
You might try the trial version, of course.
Swift - https://github.com/nicklockwood/SwiftFormat
It provides Xcode Extension as well as CLI option.
CTRL + i
that's it.
(no COMMAND + i)
You can also have a look at https://github.com/octo-online/Xcode-formatter which is a formatter based on Uncrustify and integrated into Xcode. Works like a charm.
You could try that XCode plugin https://github.com/benoitsan/BBUncrustifyPlugin-Xcode
Just clone github repository, open plugin project in XCode and run it. It will be installed automatically. Restart Xode before using formatter plugin.
Don't forget to install uncrustify util before. Homebrew, for exmaple
brew install uncrustify
P.S. You can turn on "after save formatting" feature at Edit > Format Code > BBUncrustifyPlugin Preferences > Format On Save
Hope this will be useful for u ;-)
I suggest using ClangFormat. In order to install, please follow these steps:
Install Alcatraz package manager for XCode
Supports Xcode 5+ & OS X 10.9+
After installation restart XCode.
Open XCode -> Window Menu -> Package Manager
Search (find) ClangFormat and install it. After installation again restart XCode.
Now at XCode menu you can use Edit -> Clang Format submenu for formatting.
You can choose different types of formatting. Also by enabling Format On Save you can gain auto-format capability.
If your Xcode version 3.x , you should use "User Script" With Uncrustify , here this a Example:
#!/bin/sh
echo -n "%%%{PBXSelection}%%%"
$YOURPATH_TO_UNCRUSTIFY/uncrustify -q -c $YOURPATH_TO_UNCRUSTIFY_CONFIG/CodeFormatConfig.cfg -l OC+
echo -n "%%%{PBXSelection}%%%"
add above to your Xcode "User Script".
if Xcode version 4.x , I think you should read this blog : Code Formatting in Xcode 4,
In this way , used the "Apple Services" , but it's not good enough , cause too slow experience, does anyone has the same thing ?
why apple drop "user script" .... xD
First, Examine XCode Preferences "Indentation" section. You can customize things quite a bit there...
For more fine grained control, refer to the XCode User Defaults document from apple. (May require a developer login to view). For example, I was able to disable the "indent on paste" by entering the following in terminal:
defaults write com.apple.XCODE PBXIndentOnPaste No
to read back your setting:
defaults read com.apple.XCODE PBXIndentOnPaste
This only works for languages with are not whitespace delineated, but my solution is to remove all whitespace except for spaces, then add a newline after characters that usually delineate EOL (e.g. replace ';' with ';\n') then do the ubiquitous ^+i solution.
I use Python.
Example code, just replace the filenames:
python -c "import re; open(outfile,'w').write(re.sub('[\t\n\r]','',open(infile).read()).replace(';',';\n').replace('{','{\n').replace('}','}\n'))"
It 's not perfect (Example: for loops), but I like it.
We can use Xcode Formatter which uses uncrustify to easily format your source code as your team exactly wants to be!.
Installation
The recommended way is to clone GitHub project or download it from https://github.com/octo-online/Xcode-formatter and add the CodeFormatter directory in your Xcode project to get :
Xcode shortcut-based code formatting: a shortcut to format modified sources in the current workspace
automatic code formatting: add a build phase to your project to format current sources when application builds
all sources formatting: format all your code with one command line
your formatting rules shared by project: edit and use a same configuration file with your project dev team
1) How to setup the code formatter for your project
Install uncrustify
The simplest way is to use brew:
$ brew install uncrustify
To install brew:
$ ruby –e “$(curl –fsSkl raw.github.com/mxcl/homebrew/go)”
Check that uncrustify is located in /usr/local/bin
$ which uncrustify
If your uncrustify version is lower than 0.60, you might have to install it manually since modern Objective-C syntax has been added recently.
Add CodeFormatter directory beside your .xcodeproj file
Check that your Xcode application is named "Xcode" (default name)
You can see this name in the Applications/ directory (or your custom Xcode installation directory). Be carefull if you have multiple instances of Xcode on your mac: ensure that project's one is actually named "Xcode"!
(Why this ? This name is used to find currently opened Xcode files. See CodeFormatter/Uncrustify_opened_Xcode_sources.workflow appleScript).
Install the automator service Uncrustify_opened_Xcode_sources.workflow
Copy this file to your ~/Library/Services/ folder (create this folder if needed).Be careful : by double-clicking the .workflow file, you will install it but the file will be removed! Be sure to leave a copy of it for other users.
How to format opened files when building the project
Add a build phase "run script" containing the following line:
sh CodeFormatter/scripts/formatOpendSources.sh
How to format files in command line
To format currently opened files, use formatOpenedSources.sh:
$sh CodeFormatter/scripts/formatOpendSources.sh
To format all files, use formatAllSources.sh:
$sh CodeFormatter/scripts/formatAllSources.sh PATH
PATH must be replaced by your sources path.
E:g; if project name is TestApp then the command will be
$sh CodeFormatter/scripts/formatAllSources.sh TestApp
it will look for all files in the project and will format all the files as configured in uncrustify_objective_c.cfg file.
How to change formatter’s rules
Edit CodeFormatter/uncrustify_objective_c.cfg open with TextEdit
Well I was searching for an easy way. And find out on medium.
First to copy the json text and validate it on jsonlint or something similar. Then to copy from jsonlint, already the json is formatted. And paste the code on Xcode with preserving the format, shortcut shift + option + command + v

Resources