One Xcode 4 Project, Four Target "Variations" ... With A Twist - build-process

I have a sneaking suspicion that what I'm looking to do can be done more elegantly within Xcode 4 ... but then I've been wrong before. Here's the scoop:
I have an iOS app with the usual debug/release builds and regular, unit-test, and ui-test targets. Nothing unusual there. The app also calls out to a server. Nothing special there either. Except ...
Now I want to be able to build the app for four different server environments: Development, QA, UAT/Beta, and Production. In addition, each build must be able to co-exist on the same device, for developer builds or ad hoc distribution.
So let's see ... how might this pan out? Each app will need its own target identifier for starters. Perhaps detecting the kind of build could help target which server to use:
Debug builds target Development.
(Ad Hoc Distribution) Release builds target QA (... or UAT/Beta?).
(App Store Distribution) Release builds target Production.
As for those Target Identifiers (com.companyname.appname), I suppose I could use different Info.plist files for each build ... but that smells unwieldy (duplicate info). Perhaps it's the only way?
Bottom line: I'm uncertain of a) how to resolve the Ad Hoc vs. App Store Distribution cases, as well as b) the QA/UAT cases, as well as c) how to do this without messing up the (at least to me) more elegant setup Xcode 4 offers with those simple "Press Play" Debug/Release build ops.
Maybe I have to add new Schemes? Perhaps it's simply a matter of adding more Info.plist files ... or builds ... or configurations ... or targets ... or some mixture. Again, I'm trying to keep from duplicating a lot of info (only to change one or two settings) if I can help it. Debug/Release seems very clean as it is, and I want to make sure I change things along the proper axis. Measure twice, cut once, as they say.
Clues welcome/appreciated!

Here's what I ended up doing. Hopefully this is the most sensible way to go about it:
For now, I combined QA and UAT. (This may be split later on.)
I made three Info plists, one for Development (Debug), Beta/QA/UAT (Release), and Production (Release). Each of these has slightly different bundle display names, bundle identifiers, and bundle names, but is otherwise identical. (THIS is where the lion's share of duplicate info will be. Have to change things in all three - for instance, if I add a new font or URL type.)
I created a new configuration, Beta (based on the original Release/Production config), so now there's Dev, Beta, and Production configs as well.
In the Provisioning Portal, I set up App IDs using the previously declared bundle IDs, and generated new certs for Beta, Dev, and Production. (The existing app ID ends up being used for App Store releases.)
In the Build Settings, I used Conditional Settings to specify the appropriate Info plists and code signing identities.
I think this will do the trick! If there's a cleaner way, however, please weigh in. Thanks!

Related

Symfony 4 and Microservices

Say I'm going to create few microservices: Alpha, Beta, Gamma.
In terms of Application structure using older Symfony version like 2, I'd create a bundle for each service, but bundles are no longer recommended in Symfony 4. So... Should I create separate repositories for every service or still create a bundles in a one App?
If you have different microservices, as in different applications, you will not need bundles. You can keep them in different repositories, but a common practice is to use a so called mono-repository. As the name suggests, with a mono-repository you keep all of the projects in a single repository. This has the benefit that changes spanning all projects can be done more easily and in sync. The drawback is that it requires more effort when managing and might cause additional overhead when building and deploying as it will not be easy to see which service has changed so must likely you rebuild all of them. There are a few books and presentations on mono-repositories you might want to check out. In short, Symfony does not restrict how you manage your services. You can have a single repository for all projects or multiple repositories.
If you want to serve all "services" through the same application, even without bundles, you can do so by using namespaces to separate the logic, e.g. for controllers:
my_app
- src
- Controller
- Alpha
- IndexController
- Beta
- IndexController
This should work out of the Box with the default configuration and even if you deviate you can make things like argument resolvers work by just pointing the configuration to the correct folder. Obviously this will require you to make sure that code is not shared between services should you ever want to extract them into their own application. There are some static code analyis tools that help you with keeping your architecture clean, i.e. make sure Alpha does not use code from Gamma and vice versa.
If you want to separate the apps more clearly by doing something like this:
my_app
- src
- AlphaApp
- ...
- BetaApp
- ...
You can still do that but it will require more manual work and the recipes will not work anymore, requiring you to do manual changes to most configurations and moving around files. How to do it depends on whether you want a shared kernel or a separate kernel for each service, but if you go that route I recommend keeping separate projects in the same repository, as it will probably yield cleaner results and be less work.
You can still create bundles in symfony4 though its not recommended by best practices. see https://symfony.com/doc/current/best_practices/creating-the-project.html

Flex: conditional embedding of images

We are working on a flex project where we want to balance two challenges
a) want to ensure that there is minimal need to be connected to internet- so it can be used offline. This will be used in rural locations with flaky connections
b) Reduce file size by only embedding those assets in compile mode as is required
Broadly, the project will go down one of three flows in the module called, based on user choice- Path A, Path B and Path C, which will require image set-A, set-B & set-C respectively (based on settings in the module)
We want to send over all images in Set-A or set-B or set-C right upfront in the module called, based on choice made in primary project, to minimize need for connectivity once accessed. At the same time I want to avoid sending all three sets and bloating up download size three times.
The question is how do I conditionally embed images such that if I am going down path A, the module sent down only has images of set-A
We had to solve a similar problem with asset localization, and we ended up creating external RSLs to link in "asset packages". However, this does require a bit more attention to the build process, since you have to pay closer attention to linkage and dependencies across RSLs. Most of these problems go away if all of your libraries are linked as external as apposed to merged-in-code (not just for your app, but any local libraries you may use as well). This is not necessarily required, but it does help ensure everything you need gets linked in.
Are you compiling Flex on Fly/Runtime from primary project on server?
If NO, its mean you are compiling it in IDE, in that case i suggest build 3 Application
For Path-A B nd C, you dont need to rewrite whole application again just ReWrite Application.mxml for three apps and emebed rrelative assests in them
IF YES, same ans seprate app.mxml for each path
EDIT: Anotther option is conditional compilation It is To include or exclude blocks of code for certain builds, you can use conditional compilation
hopes that helps

VS 2010 Web.config transformations for debugging

I’m a fan of the new VS 2010 Web.config transformations. I use this feature for deployment purposes and wondered if it is possible to use them for debugging too.
I think of using them in the IDE: I want to create different built configuration (with linked transformation configurations); choose one of them; start the web site in the IDE and debug the different configurations this way.
Update
Thanks to a 3rd party plugin, SlowCheetah, this is now possible. Scot Hanselman has a blog post about it.
Original response:
Unfortunately, the web.config transformations appear to effect only publishing sites and building deployment packages.
In our scenario we have two development groups, one with access to multiple environments (in-house) and the other with access to a single environment (offshore). We have periods where the in-house group needs to debug directly against QA, while offshore remains locked-out (so their web.config's must point to the dev environment).
We were hoping to have 1x build-configuration per-environment, and be able to choose the build-configuration which matched the environment to debug against--which, as I understand it is your question.
In case anyone is curious why they haven't built this feature, from:
http://forums.asp.net/p/1532038/3711423.aspx
"When the web app gets run, the web.config under project root folder will be picked up by asp.net and I know unfortunately it is under source control . I certainly understand the cleanness coming with letting runtime use a transformed web.config from a temp folder; however, asp.net runtime doesn't know anything about vs projec structure and it is totaly based on directory structure. Using alternate path might also break as a web.config under a subfolder expect to inherit settings from the upper level of directory."
I found an alternative solution that does not involve any third party tool: http://ledtalks.blogspot.in/2011/09/webconfig-transformations-when.html. I only tried this for the web.config file

How to setup web.config for build to multi-environments without code changes?

I recently worked on an app in a very interesting environment. There was 6 or 7 parallel levels for this application and only the 1st 2 levels were able to be touched by developers. As part of the company policy all builds were done as Tivoli packages, and very complex to setup.
The final kicker was that no code changes are allowed past the 1st level or "Dev" servers so web.config contained multiple encrypted sections of environment variables. The application is built to sense what environment its on by path and variables set in IIS.
This is a beast to maintain so what is a simple or better architecture for this type of problem?
Hmm, (disclaimer: I'll talk about something I've written)
Your subject seems slightly different from the post, but I think I have an idea of what you mean. The tool I'm writing, dashy, lets you handle a single codebase, and lets you configure it for various enviroments. It doesn't, however, place security restrictions on these enviroments over the other. But, depending on your source control, and general system, it may be of interest. You should get a reasonable idea of the way it works from the picture on the homepage. Perhaps it's of interest, perhaps not, but it's what we use to manage deployment to different environments. It's a work in progress ("beta") at the moment, but the current version is suitable for testing.
The latest version of ASP.NET now supports web config transformations, allowing you to change specific settings within your project for deployment, testing or staging. Here's a great intro by Tom Hundley.
Have you tried using OpenExeConfiguration of the ConfigurationManager and explicitly load the proper configurations for the appropriate environments instead of just using the default web.config?
For more, check out OpenExeConfiguration on MSDN
You could include all configurations for all environments in the web config and prefix their keys with the machine name of the appropriate environment. Then, using Server.MachineName (or some other way to identify the server that the app is running on) you can access the right configuration.
<appSettings>
<add key="DEVMACHINENAME_baseURL" value="http://dev.foo.com" />
<add key="QAMACHINENAME_baseURL" value="http://qa.foo.com" />
</appSettings>
No one would have to go in and modify anything in the web.config since the application can look up information for itself.

Deploying Flex Projects Leveraging Imported Web Services

I'm sure there's a simple explanation for this, but I haven't had much luck at finding the answer yet, so I figured I'd put the word out to my colleagues, as I'm sure some of you've run into this one before.
In my (simple) dev environment, I'm working with a handful of WCF Web Services, imported into my FB3 project and targeting a local instance of the ASP.NET development Web server. All good, no problems -- but what I'd like to know now is, What's the right way to deploy this project to test, staging and production environments? If my imported proxies all point, say, to http://localhost:1234/service.svc (from which their WSDLs were imported), and all I'm deploying is a compiled SWF, does Flex Builder expect me to "Manage Web Services > Delete", "> Add", recompile and release ever time I want to move my compiled Flex project from development to test, and to staging, and ultimately into production? Is there a simpler workflow for this?
Thanks in advance -- hope my question was clear.
Cheers,
Chris
If you have path names which will change depending on the enviroment then you will likely need to recompile for each environment since these will be compiled in the swf.
I typically use ANT scripts to handle my compile/deployment process when moving from development and production environments. This gives me the ability to dynamically change any path names during the compile. These build files can be integrated into Flex Builder making this process very easy once you have everything set up, and can be done with one click or scheduled.
Thanks Brett. I've been meaning to dig into automating my build processes anyway, so now's probably as good a time as any. :)
You do not need to build a SWF for each environment. Here's a technique I use commonly:
Externalize your configuration properties into an XML file; in this case, it could be a URL for each service or a base URL used by all your services
When the application starts up, make an HTTPService call to load the XML file, parse it, and store your properties onto some bindable "configuration object"
Bind the values from that object against your objects that depend on the URLs
Dispatch an event that indicates your configuration is complete. If you have some kind of singleton event dispatcher used by some components in your app, use that, so that the notification is global
Now proceed with the rest of the initialization of your application
It takes a little work to orchestrate your app such that certain parts won't initialize until steps 1-5 take place. However I think it's good practice to handle a lot of this initialization explicitly rather than in constructors or various initialize or creationComplete events for components. You may need to reinitialize things when a user logs out and a different user logs in; if you already have your app set up to that initialization is something you can control then reinitialization will not be a problem.

Resources