Is it possible to generate an unsigned Xcode archive with Titanium? - titanium

We've build a Titanium application for a client, but the client wants to be able to sign the application themselves. To do this they requested an unsigned Xcode archive. We're unable to generate a valid archive using Titanium.
We've tried running the xcodebuild command on Xcode project that's generated by Titanium. Something like:
xcodebuild -workspace <projectName>.xcworkspace -scheme <projectName> -configuration Release clean archive -archivePath buildArchive/<projectName>.xcarchive CODE_SIGNING_ALLOWED=NO
But that generates an invalid archive, so we suspect that Titanium is doing something extra to generate a valid archive.
We've also tried building the app for distribution and editing the generated archive manually. But we're unable to fully remove the signing from the archive. The entitlements still exist with wrong id after removing the _codeSigning directory and embedded.mobileprovision profile.
Is it maybe possible to write a cli hook to add the CODE_SIGNING_ALLOWED=NO variable during the app build?

I found out that it's actually possible to add the CODE_SIGNING_ALLOWED variable using a cli hook.
exports.init = function (logger, config, cli, appc) {
cli.on('build.ios.xcodebuild', {
pre: function (data, next) {
if (this.deployType === 'production') {
data.args[1].push("CODE_SIGNING_ALLOWED=NO");
}
next(null, data);
}
});
};
Now I can generate unsigned archives.

Related

React Native Expo Environment Variables with EAS

I have a secret key that I need to use in my app. On the web, I would use a .env file, but with React Native and Expo.
I want to use the EAS Build, and found the following documentation EAS variables docs
This gives information about adding the "secret" to your eas.json file, but I am unable to find 2 important things:
What code to use to access the secret variable in the dev and prod environment.
I'm thinking in production the code would be 'process.env.SECRET_KEY' and hoping the same code would apply for the dev environment, but I am not sure how to get the process.env in dev to be populated with the SECRET_KEY.
When I console.log(process.env) in my app, I just get NODE_ENV: "development".
My thought is that many apps need some sort of Secret bit of info, so any ideas on a best practice or at this point just any way to get this to work!
I was able to get the environment (secret) variable working with the eas build process.
I am sure there are other ways to accomplish this, however this is the approach I took:
I chose to use a .env file for the dev environment and the eas secret:create command for eas builds.
First, you need to create a secret for your project with the eas cli.
eas secret command
Then, create you .env file with your secret. Make sure this has the same spelling as the secret created for eas.
You will then use the app.config.js file to inject the secret so that your code can access it. NOTE: I found that I needed to remove the app.json file. I moved all the config from app.json to app.config.js.
Also remember to run npm install dotenv on your terminal to add dotenv to your project.
// the dotenv/config will read your .env file
// and merge it with process.env data
// This is just for the builds that happen outside of eas
import "dotenv/config";
// the secrets created with eas secret:create will
// be merged with process.env during eas builds
const secretKey = process.env.SECRET_KEY;
export default {
name: "TV Tracker",
slug: "tv-tracker",
scheme: "tvtracker",
...
// THIS IS WHAT WE READ IN THE CODE
// uses the expo constants package
extra: {
secretKey: secretKey,
},
};
Now we can read the secretKey using the expo-constants module.
import Constants from "expo-constants";
...
let secretKey = Constants.expoConfig.extra.secretKey;
Got my answer here
https://github.com/expo/eas-cli/issues/1265#issuecomment-1301525320
I do wish expo simplified/cleaned their documentation a bit and made like one simple example which just works out of the box instead of providing tons of information where it's so easy to miss Constants.expoConfig vs Constants.manifest
As a follow-up to #markmccoid's answer, I usually use a bash script to put the .env secrets into eas for the project.
while IFS='=' read -r key value; do
eas secret:create --scope project --name "$key" --value "$value"
done < .env

React Native Multiple command produce same file

I tried to build a react native app for iOS and I hit this error:
Build system information
error: Multiple commands produce '/Volumes/Data/sources/react-native/test/ios/build/test/Build/Products/Debug-iphonesimulator/test.app/Zocial.ttf':
1) Target 'test' (project 'test') has copy command from '/Volumes/Data/sources/react-native/test/node_modules/react-native-vector-icons/Fonts/Zocial.ttf' to '/Volumes/Data/sources/react-native/test/ios/build/test/Build/Products/Debug-iphonesimulator/test.app/Zocial.ttf'
2) That command depends on command in Target 'test' (project 'test'): script phase “[CP] Copy Pods Resources”
You can try deleting the build folder in ios directory and rebuilding your app again. It might solve this issue
It looks like you have installed some library with fonts that iOS don't have linked. Try this:
Create an empty dir in your project to store some future useful fonts (for example "Nunito" family font). I suggest create fonts folder into assets --> assets/fonts
Create a new file named react-native.config.js in the root of your project and add into it the following:
module.exports = {
project: {
ios: {},
android: {}
},
assets: ['./src/assets/fonts/'],
};
In your project dir run react-native link
Go to ios dir (cd ios) and run pod update
Build
Especial thanks to Alex Biddle: https://medium.com/better-programming/how-to-add-custom-fonts-to-your-react-native-project-c64305281b9
I had this error with react-native-vector-icons installed after I executed react-native link. My solution was to remove fonts copying from XCode Build Phases.

Change code push deployment key React native

While integrating code-push in my react-native app using code-push tutorial, i ran following command:
react-native link react-native-code-push
It asked for deployment keys then, which i pasted but now i want to change those keys.
I tried to unlink with the following command but its not working,
react-native unlink react-native-code-push
Can someone please guid me, as i'm new to both react-native and code push?
For IOS:
file:
list.info
key:
CodePushDeploymentKey
For Android:
file:
strings.xml
key:
reactNativeCodePush_androidDeploymentKey
update values of these keys and it will work :)
So basically deployment keys can be stored in different locations and it depends upon how you have configured the application.
You can always find what is the location of the deployment key the following way:
1) For Android it is injected in MainApplication.java file -> getPackages method (the 1st parameter for CodePush class constructor).
By default it should be R.string.reactNativeCodePush_androidDeploymentKey which points exactly to strings.xml file. You can override this if needed and store deployment key in arbitrary place or simply hard-code it here (though it is not recommended).
2) For iOS the default place to store deployment key is Info.plist file located in iOS folder of the application (entry named CodePushDeploymentKey).
Later it is extracted by the app in native module in CodePushConfig.m class.

Using SBYZipArchive or other Zip Cocoa Pod in Swift not working

I have an OSX app that needs to be able to zip and unzip directories, and I figured it would be easy using a cocoapod. I've hit a brick wall.
I've installed Godzippa, Objective-Zip, zipzap, ZipKit, ZipArchive, SSZipArchive, and basically every other cocoapod that claims to provide "Zip" functionality, but I've failed to get any of them to work.
I'll share the steps to my failure, and perhaps someone will correct me where I've strayed the correct path:
1. Because I am working out of a Swift codebase, I created an Objective-C-Bridging Header, and set the corresponding attribute under Build Settings in the Swift Compiler Section.
2. I installed cocoapods in the application and included the desired cocoa pod in the Pod file, ran pod install, and restarted the application using the workspace.
3. Inside the bridging header, I imported the necessary objective-c headers of the corresponding cocoa-pod so I can use them in Swift. For example, for SBYZipArchive I had the following in my file I imported the < SBYZipArchive/SBYZipArchive.h> header.
4. I try to build the application and it fails on multiple places all referencing the zlib.h library.
5. I attempted to provide access to the zlib library by adding the libz.dylib to the Build Phases under Link Binary with Libraries.
6. I attempt to build the application, and it still doesn't love me.
To my knowledge the reason why none of these frameworks is working is because they are for some reason failing to access the zlib files that are necessary to do the actual data compression. Thats as far as I've figured out... Any help would be appreciated.
Update
I was able to do the zipping without using any of the above packages by simply setting up an NSTask. For those who may care more about zipping than they do using these tools here is how I did it:
var task = NSTask()
task.launchPath = "/usr/bin/zip"
task.arguments = ["-r", "/Users/$USERNAME/Documents/$PATHTODIR/zip1.zip", "/Users/$USERNAME/Documents/$PATHTODIR/filesToZip"]
task.launch()
When using NSTask you set the launch path to the tool you want to use, and then give the required arguments. so the above task is the equivalent to the command in UNIX:
zip -r /Users/$USERNAME/Documents/$PATHTODIR/zip1.zip /Users/$USERNAME/Documents/$PATHTODIR/filesToZip
Obviously swap out the variables I put in there for your own path
UPDATE
Although the UNIX zipper works perfect for the mac app, I am pretty sure I need one of the zip packages to be able to do this on iOS

HOW TO sqlite3_load_extension from within Objective-c [error: dlopen(...) image not found]

I am trying to load an extension to sqlite3 for use within iPhone application objective-c code. I successfully compiled the c file of new functions into a dylib named libsqlitefunctions.dylib. Here is where I am a bit lost. I call sqlite3_load_extension as follows:
char *error = sqlite3_malloc(MAX_SQLITE_ERROR_MESSAGE_SIZE);
const char *library = [#"libsqlitefunctions.dylib" UTF8String];
if (sqlite3_load_extension(database, library, 0, &error) != SQLITE_OK) {
message = [NSString stringWithFormat:#"%s", error];
}
sqlite3_free(error);
No matter what I do, I get the error: dlopen(libsqlitefunctions.dylib, 10): image not found
I tried:
indicating the fully qualified path to the dylib
indicating a relative path
not indicating a path (as shown above)
adding the dylib as a framework
adding the .c file to my project and compiling it into a .o file and then trying to load it
Please note that this is not an entry point problem, since I pass 0 as that arg. This will force the dylib to load by calling an init function defined in the dylib. I do not even get to that point.
I am pretty much a newbie compared to the rest of you guys and feel that I am probably lacking an understanding of how libraries are loaded.
I would really appreciate any ideas since the ability to make use of the functions in this library is important to the functionality of my app. Thank you all in advance.
OK, I took your advice and simply added my new functionality to the sqlite3.c file I had in my project. It compiled and linked statically and works fine. Thank you for the idea. I still would like to know what was preventing me from loading an extension, but am pleased with having learned other things in solving the problem - PLUS I met my deadline. Thank you again.
After days of search I finally found a solution !
1) once your sqlite_extension.h and sqlite_extension.c files moved into your sqlite_extension folder
2) cd to that sqlite_extension folder
3) compile your code using :
gcc -g -fPIC -std=gnu99 -current_version 1.0 -compatibility_version 1.0 -dynamiclib -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk sqlite_extension.c -o sqlite_extension.dylib
You might need to change the SDK path for something like ../iPhoneOSN.M.sdk where N.M indicate the last available version of iOS, have a look to the folder "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/" to find an existing path
4) You can check the resulting file using :
file /path/to/your/sqlite_extension.dylib
which should return something like :
/./././sqlite_extension.dylib (for architecture armv7): Mach-O dynamically linked shared library arm
/./././sqlite_extension.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library
or using the more detailed :
otool -l sqlite_extension.dylib
5) Now your library needs to be code-signed with the same identity as your embedding app you can do this using :
codesign -fs "your_apple_identity" sqlite_extension.dylib
your_apple_identity can be in the form "your_name: your_apple_login_email#address.xxx"
The best way to make sure is to copy the one from your embedded app executable compiled and running on your device with Xcode or the archive on your computer using :
codesign --display --verbose=4 ~/Library/Developer/Xcode/Archives/2016-09-25/YourApp\ 25-09-2016\ 12.00.xcarchive/Products/Applications/YourApp.app/YourApp
The string to use in place of "your_apple_identity" is the one found after the first occurence of Authority=
6) Once your library code-signed, you can check that you get similar signing information as your App using the same command :
codesign --display --verbose=4 sqlite_extension.dylib
7) Your Library is now ready to be embedded in your app, all you need is to make sure Xcode refreshes your library file if you had try a previous file with the same name. To do so you can remove the former file, compile and run on your device, put back the new file making sure it is in the "Copy Bundle ressources" not the "Link Binary With Librairies" of the Build Phases tab of your app
Your extension should then load without error when your app requests SQLite to use it
iOS 9.3.5
Xcode 8.0
SQLite 3.9.2
I'm not 100% sure this is explicitly disallowed, but another type of dynamic loading -- frameworks -- isn't supported on the iPhone. You may need to compile and link the library statically, rather than dynamically.
i know topic is old . but googling brought me here. and for anyone that has this problem and end up here :
you must first call
sqlite3_enable_load_extension(db, 1);
I know that I am answering late but I faced the same problem and found how to load an extension.
Once you have the source file X.c, compile a shared library(In Linux machine) using
gcc -g -fPIC -shared X.c -o X.so
Where X.c is the extension in use
Then enable loading extension in C interface to SQLite using
sqlite3_enable_load_extension(db,1);
Then load the extension using
sqlite3_load_extension(db,"/path/of/extension/X.so","sqlite3_X_init",0);
Thats it, extension will be loaded now.