Why is there no 'cake watch:ios:dev'? - ios

I am using cordova-brunch in a project and I would really like to not have to re-run the cake build:ios:dev command each time I modify the JavaScript/CoffeScript source. Even more since I usually have to also make changes in the iOS Objective-C code for my hybrid app and I generally rebuild the App from XCode forgetting to rebuild the JS/CS part.
The behaviour is identical for Chapless Brunch and Cider Brunch, but I still don't get what prevents a cake watch:ios:dev functionality. The available cake watch:cordova:dev doesn't solve the problem.

Related

Transferring Xcode Project from one computer to another brings random errors?

I have a Xcode project I got from another developer. Initially when I opened it it has a bunch of errors (most of which were un-updated frameworks). I got it to work after a while and I fixed it. I want pass it back to the manager since I'm leaving uni in a few months. I copied it over to my friends Mac to see what would happen if I just took the project and all it's folders and made it a zipfile. It didn't work for some reason. It gave me an error:
error: using bridging headers with framework targets is unsupported
But why did that come up? I mean it's the same code on the slightly different versions of Xcode (13.1 versos 14.1) but I doubt there was a massive change between the two that would cause this. I want to be able to pass these app later in the future without having to care about this stuff. I made a GitHub (link below) would cloning that work? Also the laptop I chose was just a fresh reset. Would it be due to not having coco-pods installed?
I feel like I could go through and fix it all on that laptop and document that but then I'm afraid that every time I put it on a new one it would come up with random errors every single time making my documentation moot.
https://github.com/AbdullahMSaid/SonicExperiment-Works
With big help this was Fixed.
Things that fixed it.
Having the correct version of Xcode
Turning everything from absolute path to relative
Lots of other code fixes. But those are my project specific.
You don't need bridging headers in framework. Use should have something like "YourFramework.h" where you can import your .h files.

Is it possible to run code from a downloaded framework in iOS?

I want to present a ViewController from a framework which is downloaded later in the app document directory (Something like Microsoft Code-Push in React Native).
Be more specific: I want to install an app (in React Native, Swift, etc) then it would download another swift(objc) compiled app and run it in the next startup.
(I don't care about the first app but It's critical to run a swift compiled code.)
As you have now learned in the comments, you cannot download and "run-on-the-fly" compiled code.
A couple thoughts though...
As you are trying to "get around Apple's review process" you should be aware that any method you use to change your app after approval can be risky.
Whether it's downloading graphics, updated data files, config files to change appearance or functionality, using Cordova or React Native (as with Code-Push), etc - minor changes are fine.
Data updates, new imagery, etc. Even layout changes handled by your internal code are no big deal.
However, making major changes, particularly when it is obviously done to get around initial rejection, will end up resulting in your account being banned if/when you get caught.

How can you permanently change iOS app configuration in Meteor Cordova?

Every time I meteor build, I have to open XCode and do the following:
remove and add an item from "Link Binary With Libraries" (Facebook SDK)
add a URL Type (custom URL scheme for my app)
add a "Required device capabilities" to "Custom iOS Target Properties"
How can I edit my Meteor project to have these steps done automatically, and to auto add things to AndroidManifest.xml?
In some way use mobile-config.js or cordova-build-override?
I'm happy to see another guy who is trying to build a hybrid application using Meteor / extending a Meteor Cordova iOS app, since I'm facing the very same issues. So I'm very happy to share my experiences and approaches with you. :-)
So far, I ended up with the following approach:
I created a base template for my iOS app using meteor build (not meteor run ios-device, since I did not know if Meteor does some optimizations for production code).
Then, I copied the whole Xcode project under /platforms/ios to another loaction and used this new project as my "master" project from then on. This project is being enriched with native code, e.g. it also includes the Cocoa Pods I'm needing.
Of course, I also did not want to copy files each and every time I trigger a new Meteor build. At least, I would like to have the Staging/www folder updated, as this is happening quite frequently.
So my first (rather naive) approach was
delete the Staging/www folder in the master project
replace it with a relative link (using Xcode's linking functionality) to the Staging/www folder inside the .meteor/local/.../ios/ project
This approach did not work, since the shell script used in the Meteor Xcode project can't handle these links.
My second approach is to create a symlink on the filesystem level instead. This works as it should, and I'm able to build the project in Xcode as it should.
I could have followed the same approach for the Cordova plugins folder, but I've decided to replace the plugins manually in order to get a better control over them, even it means a bit more effort then.
Having the symlink in place also means that Xcode's version management (and also SVN which I am using for everything) will ignore everything below Staging/www, which is good in my opinion, because I'm already versioning the webapp code in the Meteor project itself.
BTW: I've started a discussion thread on hybrid mobile app on the Meteor forums as well, but so far it did not get too much attraction:
https://forums.meteor.com/t/building-a-hybrid-meteor-cordova-app-share-experiences/8212
Maybe we could follow up on Meteor-specific things there, to have the Meteor community participate in the discussion?
EDIT: I would also like to share an approach that failed completely, at least for me, maybe I was too dumb... Before I used Meteor's Xcode template as the starting point, I also tried it "the other way round", i.e. I started with my already existing Xcode app project and tried to include Meteor's / Cordova's part by hand. Using this approach, I never managed to set everything up correctly. I had lots of troubles and also had to tweak a lot of the compiler / linker flags to even get the code compiling. This grew me a lot of gray hairs. But even after I managed to get everything to compile, Meteor hang during startup - and I never figured out why.
One remaining problem I'm still facing is that Meteor's hot code push functionality seems to have some severe issues on iOS, that are also documented as GitHub issues. It can happen that the iOS app gets completely broken and needs to be reinstalled. I tried the mdg:reload-on-resume package, but this did not work as it should and made things even worse. As far as I can tell from the GitHub discussions, one should better disable hot code push until the Meteor team has addressed these issues. Breaking the app completely due to code pushes is not what my users would expect.
Unfortunately plist values (and assumably AndroidManifest.xml as well) can only be changed by a plugin:
Add entry to iOS .plist file via Cordova config.xml

How to handle large Swift Project?

After iPhone app that I'm writing in Swift become quite big (> 150 .swift files + various Objective-C libs), Xcode start behave pretty badly:
every second compilation I get various errors, e.g.:
Command failed due to signal: Segmentation fault: 11
compilation take enormous amount of time (> 2 min on MacBook Pro Retina)
and so on.
I just wonder if everyone has same problems and maybe someone found a way to reduce this nightmare?
What I have done so far — I split project into several dynamic frameworks that I link from main project, it helps to reduce compile time, but introduce some new problems.
I also use iRamDisk to keep DerivedData folder in RAM and periodically delete all files from it, it sometimes helps with SourceKit crashes.
Swift toolchain is still a bit gross, you'll need to use some temporary workarounds until Apple fixes it (see UPDATES below)
Here is a list of items that you can do to keep yourself from going crazy.
Slowness caused by immature Swift compiler
Change your development workflow using Injection for Xcode. Once you installed the plugin, you'll be able to inject code changes in your simulator\device without recompiling. You don't need to hardcode\modify anything in your project. We started using it recently at work and it made a huge impact on our side, even if it doesn't apply to every use case (for example you can't create new functions, you can only modify the existing ones).
Some particular code constructs that the compiler doesn't like and takes too much time to compile. The most common problem is with the Type Checker that slows down compile time exponentially based on how many type checks it needs to do (read more here for practical examples and here for a detailed explanation). In order to identify if you are suffering from this problem you can follow this blog post, you will gather information about the functions that creates slowness by using some compiler additional flags. Alternatively you can use this Xcode plugin to identify the source of the build slowness.
Use dynamic frameworks wisely, where it makes sense. A framework recompilation will be done only when you modify one of its Swift files (dynamic frameworks are only available for iOS >= 7).
Condense code in the same files. Lowering the number of Swift files speeds up the compile process sensibly. You can easily achieve it enabling "Whole module optimization" by adding a user-defined custom flag SWIFT_WHOLE_MODULE_OPTIMIZATION and set it to YES and at the same time set optimization level to none (to disable optimizations that would make it slow) OUTDATED You may consider to use this gist, it's a build script that collapses all your code in a "merge.swift" file.
You'll need to create a new target for it, but it is worth a
try.
Double check things listed here (there are a few some more misc reasons because the compilation is slow)
OUTDATED Try the approach described in this blog post, it involves creating a build script that generates a make file. It requires manual intervention on the build script (it contains the list of swift files).
OUTDATED Try this hacked up incremental compilation technique
UPDATE: Incremental builds introduced on Swift 1.2 (Xcode 6.3)
Apple finally introduced incremental builds with Swift 1.2 (shipped with Xcode 6.3). It's not still perfect, but it's a huge improvement.
From now on a class is recompiled only when it is changed (or when one of the class it depends on has been changed).
However the compiler still can’t understand if the changes to a class are to its interface or not. So any kind of change to a class causes a recompilation of that class and all of its dependencies.
UPDATE: Recompile dependent classes only when public interface changes introduced on Swift 2.1 (Xcode 7.1)
Starting from Swift 2.1 (Xcode 7.1), the dependent classes are recompiled only when you change the public interface of a class, and not at every change. This makes an huge difference in particular for big projects.
Project (mis)configuration (not related to Swift)
Be sure that "Build Active Architecture Only" is YES for debug.
Be sure that you didn't add pre\post compilation scripts that take too much time.
Apple has some advices for speeding up your Xcode build in Technical Note 2190. Have you thought about creating and precompiling an own framework for outsourcing unchanged Swift modules or some/all Objective-C code?
Remove all type inferences in Swift.
This SO topic has some nice ideas and this blog post suggest to
stop generating dSYM bundles and
avoid compiling with -O4 if using Clang.
Although lots of these improvements are related to Objective-C, I am quite sure, that some of them are still relevant for Swift.
The (re)compiling is a known issue that I am sure will be resolved soon. Some recommendations:
Use Objective C where possible - it compiles fast even if it is a part of a Swift project
Split code to frameworks
Specify types instead of leaving it up to the compiler to infer them
Again, there is a good chance that this will be fixed soon, so perhaps it is best not to make big investments in rewriting or reorganizing the code at this point in time.
you could try:
upgrading the amount of RAM in your computer
if you have multiple .swift files that do things on the same view controller, try condensing them into one .swift file per view controller
tweaking the settings under compile sources to see if you have any duplicates or if there are any scripts or settings you can add to make it compile faster...
you can also take a look at this post's answers for some hints as to what you can do to slow down compile time
I've discovered that one of the main causes of segmentation faults and slow compilation is hardcoding big arrays and dictionaries, especially when declaring them as global constants and trying to access values from them from within another .swift file. When I store all that data inside plists, these problems are gone.
In my experience avoid creating the large swift files, when I started a project in my new company, there was a 'UIViewController' with more than 2000 lines, little changes on this file taking much time to build, I made 4 extensions with <500 lines from that class, my speed improvement was incredible.

Determining if iOS frameworks are actually needed

I am rebuilding an App and at the same time paring it down of unnecessary code and it contains "required frameworks" that I think were left over from copying a previous app shell for building this app. How can I determine if a framework is actually needed. I thought I could just leave them off and build the app and then add them as required to let it build successfully but in the past that has not worked well to my surprise as I have built and tested a previous App without any additional frameworks added and the App built and ran just fine on simulators and actually devices only to find out at submission time I forgot to add the frameworks before submitting it.
I am trying to be proactive and only put in the ones I need. Some, like the MediaPlayer are definitely not needed and I can eliminate them already but some are harder to determine.
Curious if there was an easy way to figure this out.

Resources