How to build your embedded NativeScript app within the Xcode project
Tags: ios, mobile, javascript
Published: 2023-09-21 18:31:32

Recently, there's been growing interest in embedding NativeScript apps within native iOS applications. While this embedding feature in NativeScript is still relatively new and evolving, it offers promising capabilities. However, automating the build process in Xcode can present challenges due to discrepancies between the terminal and Xcode environments. In this post, we'll delve into these challenges and provide a solution for a unified build step.

### **The Challenge**

1. **Command Not Found**: When invoking tools like `ns` from Xcode, you might encounter errors like "command not found". This is because Xcode doesn't share the same `PATH` environment variable as your terminal.

2. **Environment Variables Mismatch**: Xcode might not have access to all the environment variables set in your terminal profile, leading to unexpected behaviors.

3. **UTF-8 Encoding Issues**: Some tools, like CocoaPods, require the terminal to use UTF-8 encoding. If not set, this can lead to warnings or errors.

### **The Solution**

To address these challenges, we'll craft a build phase script for Xcode that sets up the environment correctly and then runs the necessary commands.

### **1. The Build Phase Script**

Here's the script:

```bash
#!/bin/zsh

# This script should be invoked before Compile sources build phase

# Ensure UTF-8 encoding
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

### User Configuration ###

# User's PATH
# Example: "/Users/yourusername/.nvm/versions/node/v14.0.0/bin:/usr/local/bin:/usr/bin:..."
# To get your current PATH, you can run "echo $PATH" in the terminal.
USER_PATH="<PATH-VAR>"

# Path to the project
# Example: "/Users/yourusername/workspace/myproject"
# This should be the absolute path to your project directory.
PROJECT_PATH="<YOUR-NS-PROJECT-ROOT-PATH>"

##########################

# Source the user's .zshrc
source ~/.zshrc

# Set PATH
if [[ -n "$USER_PATH" ]]; then
    export PATH="$USER_PATH"
else
    echo "Please set the USER_PATH in the script."
    exit 1
fi

# Run the ns command
if [[ -n "$PROJECT_PATH" && -d "$PROJECT_PATH" ]]; then
    ns prepare ios --path "$PROJECT_PATH"
else
    echo "Please set the PROJECT_PATH in the script."
    exit 1
fi
```

### **2. Understanding and Addressing the Issues**

- **Command Not Found**: This issue arises because Xcode's `PATH` doesn't include directories where some tools (like `ns`) reside. By explicitly setting the `PATH` in our script to match the terminal's `PATH`, we ensure all command-line tools are accessible.

- **Environment Variables Mismatch**: By sourcing `~/.zshrc`, we make sure that any environment variables set up in your terminal are also available in the Xcode script. This ensures a consistent environment between the two.

- **UTF-8 Encoding Issues**: The locale settings at the start of the script ensure that the environment uses UTF-8 encoding, addressing potential encoding issues with tools like CocoaPods.

### **3. Integrating the Script into Xcode**

1. Select your target in Xcode.
2. Navigate to the "Build Phases" tab.
3. Click the "+" and choose "New Run Script Phase".
4. Ensure this script phase is positioned before the "Compile Sources" phase.
5. Paste the content of your script.

### **Conclusion**

With this setup, developers can enjoy a streamlined build process in Xcode that prepares both the NativeScript app and the iOS app embedding it. This approach ensures consistency between terminal and Xcode environments, leading to a smoother development experience.

For more tips on embedding NativeScript apps, follow me on Twitter **@nsteodor**.