Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lacking details for how to use App Settings #272

Open
MShekow opened this issue Jul 10, 2021 · 25 comments
Open

Lacking details for how to use App Settings #272

MShekow opened this issue Jul 10, 2021 · 25 comments
Labels

Comments

@MShekow
Copy link

MShekow commented Jul 10, 2021

Description

The manual for App settings (this one) contains obvious errors and also lacks instructions on how to actually use app settings. You have internalized your library so much that you no longer realize what other people (who encounter Mobile.BuildTools for the first time) don't yet know ;).

From reading the (incomplete) docs, this is what I've tried to use App settings (without success - no Helper class is generated, and I cannot use it from my code):

  1. Create a appsettings.json file in the root of my shared netstandard project (I'm assuming this location, because the sentence here just stops... "The Mobile.BuildTools is smart, we look for the appsettings.json in the p" ... what is a "p"? ;)
  2. Create a buildtools.json file in the same project's root (again, assuming...) with some content. The manual sometimes uses "appSettings" and sometimes "projectSecrets" as root key, I'm not sure which one I should use.
  3. Add Mobile.BuildTools and Mobile.BuildTools.Configuration nuget packages to my shared project

For testing, my buildtools.json file has this as content (where I am not sure if the AwesomeApp part is an arbitrary string, or if it relates to something in my code base):

{
  "$schema": "https://mobilebuildtools.com/schemas/v2/buildtools.schema.json",
  "appSettings": {
    "AwesomeApp": [
      {
        "properties": [
          {
            "name": "AppCenterAppId",
            "type": "String"
          }
        ]
      }
    ]
  }
}

I reckon I need to create additional files to tell MSBuild to actually generate something.

Disclaimer: I'm rather new to the C# and Xamarin world.

@dansiegel
Copy link
Owner

You have internalized your library so much that you no longer realize what other people

Your condescending attitude is unacceptable, this is your one and only warning. If it continues you will be banned.

From reading the (incomplete) docs, this is what I've tried to use App settings (without success - no Helper class is generated, and I cannot use it from my code):

Docs is most open source repos tend to be lacking. While I am very much aware that the docs will need some updating and some refinement to be clearer, I can only do so with:

  1. Constructive feedback
  2. The help of those who are using the library

Keep in mind that the docs are open source and part of this repo. If there is something you've figured out that you think could be clearer, then you have the ability to be proactive and submit a PR to help clarify docs. Also remember that I do this in my spare time.

@MShekow
Copy link
Author

MShekow commented Jul 11, 2021

I apologize for being condescending. If I would know how to improve the docs, I had done so. But I have not even got a basic example to work, and I've written this ticket while being frustrated about it.

Rephrasing my ticket:
Could anyone who already has successfully been able to generate a App Config class provide a section in the manual that explains how to do it? So far, the manual is mostly written as a reference style (which is hard to understand for beginners). Usage instructions could be in the form of a step-by-step mini tutorial that explains:

  • Which files have to be created, and where (in the project's file system tree)
  • What to add to .gitignore

@dansiegel
Copy link
Owner

After installing the Mobile.BuildTools, it should automatically add a buildtools.json configuration file to the solution root (next to the .sln file... this is usually also the root of your git repo.

In order to use the Application Settings, you need to update the buildtools.json adding the name of the project you want the generated class(es) to be in. In the docs we use the project AwesomeApp. What you pasted previously from the docs site is an example of the minimum configuration you need in order to get the class to generate. There are several additional options that will pop up in intellisense some of which are documented, but each of which can assist you to further refine how you want the generation to work.

Currently as of 2.0 this is generated in the MSBuild Intermediate Output Directory (something like {projectDirectory}/obj/netstandard2.0 directory). In the future we will be converting this to a Roslyn based generator which won't write to disk unless you specifically opt into that.

Note that a long standing bug with MSBuild, after you build (it may build successfully) it will not necessarily give you the intellisense that the class is there... you may need to close the project and reopen it in Visual Studio in order to get the intellisense for the generated class.

You can place the values you need in an appsettings.json which should be ignored by source control. In CI you can simply add these values as environment variables.

@MShekow
Copy link
Author

MShekow commented Jul 11, 2021

Thank you for elaborating on the process. The App Settings class is now generated, yay! The new information you just provided helped me realize the following (which I did not yet understand from reading just the manual):

  • The buildtools.json file is being automatically generated, but it can only found in the Visual Studio Files view - it's not shown in the Solution explorer, which is why I missed the file at first (and attempted to create it inside a project, where it didn't have any effect). buildtools.json is backed by a JSON schema that developers should study separately (e.g. in the browser) to understand what the options are and what they mean.
  • I need to update the generated buildtools.json, adding the name of the project(!) inside the appSettings block, that I want the generated class(es) to be in. This is not obvious from the schema, which just suggests that appSettings allows additional properties - it might make sense to add a description to properties.appSettings.additionalProperties in the schema file that elaborates on that.

I'll try to make a suggestion (in the form of a PR) on how to improve the docs in the coming days.

@amkuchta
Copy link

@MShekow @dansiegel I have a follow on to this - I can see the .g.cs file genertaed in my obj directory... but how do I use it? It does not show up via a standard using call for the namespace that the file resides in...

@dansiegel
Copy link
Owner

There is a known issue with Code Gen that you need to close and reopen the project for intellisense to pick it up

@amkuchta
Copy link

@dansiegel thank you! This library is exactly what I've been looking for!

@maikoly1
Copy link

@dansiegel thank you! This library is exactly what I've been looking for!

Still not able to get the .cs file on the project. I can see the .g.cs file genertaed in my obj directory. I have restarted VsStudio serveral. Any help.

@dansiegel
Copy link
Owner

dansiegel commented Sep 16, 2021

Still not able to get the .cs file on the project. I can see the .g.cs file genertaed in my obj directory. I have restarted VsStudio serveral. Any help.

Well for starters, I'm not sure what you mean by you cannot get the .cs file on the project. By design you will not see the generated class in the Solution Explorer.

@Phenek
Copy link

Phenek commented Oct 7, 2021

Yeah I just update to 2.0.2, and I am in the same situation about the doc,
I don't understand how to access secret/appsettings properties inside my code.

I used to have Build.Tools 1.4.0 in my project, and was able to generate secrets.cs file easily. (namespace .Helpers)
But this class seems to not be generated anymore

Can we access properties like in ASP.Net by dependency injection?

 interface Microsoft.Extensions.Configuration.IConfiguration

Also you are using the term "secrets" do you mean the secrets from dotnet, or just our own json file call secrets.json?

dotnet user-secrets

windows  => %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
Mac      => ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json

I did not find any information inside the doc about migration from 1.4.0 => 2.0.0

Do we need extra configuration for AppCenter?

Hope you can help
I will stay ti 1.2.1 until more informations

@TrueGeek
Copy link

I have the same question as @Phenek. Is v2 still compatible with AppCenter like v1 was? I'm happy to help update the docs and write up a migration guide, but I wasn't able to figure out what needs to be done to get it working after updating.

@delaney31
Copy link

delaney31 commented Dec 6, 2021

I'm having the same issue as @Phenek and @TrueGeek. I see the generated AppSettings file but how do I use this in my code?
Thanks for your help.

@delaney31
Copy link

delaney31 commented Dec 6, 2021

I'm having the same issue as @Phenek and @TrueGeek. I see the generated AppSettings file but how do I use this in my code? Thanks for your help.

Ok @dansiegel NVM I figured it out. @Phenek @TrueGeek The Mobile.BuildTools.Configuration and Mobile.BuildTools nugets gets installed in XF and Platform specific projects. This page explains how to init these and use them in code:
https://mobilebuildtools.com/config/app.config/in-code/

@dansiegel Thanks!
Great tool!!

@delaney31
Copy link

One issue I'm having now is that my ConfigurationManager is null in my FinishedLaunching method so it's not initializing. Please help.

Thanks
Tim

@bijington
Copy link
Contributor

I think it is worth pointing out that AppSettings and ConfigurationManager are different things.

I would expect that the appsettings.json file to be converted to a class called AppSettings and it should be located in the root of your shared code project.

@dansiegel
Copy link
Owner

@delaney31 as @bijington has pointed out there is a difference between the App Settings and Configuration Manager. These are two different API's that have the similar goal to provide an API that will allow you to access your application's settings/configuration values, but they each solve this in a different way to provide a solution for developers who may have different requirements.

In short App Settings is a Code Gen solution that provides one or more strongly typed classes. This means that if you need to change any of these values you will need a new binary build of your app to get the updated values say between Production, Stage, & Development.

The Configuration Manager API is meant for developers who prefer or are used to the more traditional (aka older) XML transforms of an app.config file and are ok with a lack of type safety. It is also ideal for apps that may need to dynamically change environments at runtime where you need to be able to do a transform of configuration values to say go from your Production to Stage or Development environment from a Release build.

@delaney31
Copy link

@dansiegel Thanks Dan. That helps. So if I just want to use the Configuration Manager I can just put all my secrets key/values pairs in the app.config?

@binaryn3xus
Copy link

binaryn3xus commented Feb 4, 2022

How do you make this work in AppCenter?

I have setup the variables and such in the appSettings for the buildtools.json. Let say I have one called "SomeServiceApiToken".

If I create a secrets.json (hidden by gitignore), I can debug locally to my hearts desire. But all my heartburn starts when going through app center. The way I understand the documentation, I should be able to setup an environment variable of "Secret_SomeServiceApiToken" and it will be fixed this string on build inside of AppCenter. NOPE! It just shows "default" in the logs like nothing happened.

I'm sure I am doing something silly and wrong but I have read over the documentation multiple times but I apparently don't understand how to make this work. I have even tried searching through some issues to see if there was a hint somewhere. If I do run across something that sounds like it might be helpful, its related to the old 1.x version.

Edit: Spelling and added last sentence about searching old issues

@dansiegel
Copy link
Owner

@JoshuaGarrison27 please note the docs site is strictly for v2. If you're still using 1.4 you need to look at the wiki. I no longer support that version. I am hoping to get an update for 2.0 in the next month.

@binaryn3xus
Copy link

@dansiegel Thanks for the reply. I'm aware the docs are for 2.0, and that is what I am using. I'm just confused on why I can't get AppCenter to inject the secret string for my project. If you could provide any additional information on the subject, I'd greatly appreciate it!

@binaryn3xus
Copy link

@dansiegel I figured out my issue.

The documentation for Continuous Integration says one thing, but the code hints say another. I just happened to see the code hint while tinkering to get this working. Code hint says it uses BuildTools_ prefix as the default, while documentation says it used Secret_ as the default. Once I updated my environment variables in AppCenter, it worked great. So as a courtesy, I thought I would come back here and share my findings for you and anyone who might be struggling with the same issue in the future.

Code Hint:
image

Documentation v2.0
image

@jtorvald
Copy link
Contributor

I was pulling my hear out why my AppCenter builds failed. I also tried iOSSecret_ (didn't work) until I came here and found the comment of @JoshuaGarrison27
When I changed my ENV variables to BuildTools_ it started working again. Thanks @JoshuaGarrison27

jtorvald added a commit to jtorvald/Mobile.BuildTools that referenced this issue Mar 16, 2022
As mentioned in this issue dansiegel#272 the default in the code is BuildTools_ and not Secret_ as in Mobile Builds tools version 1.x
@twofingerrightclick
Copy link

twofingerrightclick commented Aug 9, 2022

I am following this, but stuck as to what project to install the package on? I have a Xamarin Forms Solution with A Forms Projected and an Android Project.
I installed the packages (Mobile.BuildTools and Mobile.BuildTools.Configuration) on the Forms Project (where I want to use appsettings). Modified the buildtools.json appSettings section to include the project name of my Forms Project, and rebuilt the project. I presume then its supposed to use the appsettings.json that I created in the Forms Project to generate? I don't see any generated classes/ is there a command to run? I only have strings so would just like to use var foo = ConfigurationManager.AppSettings["Foo"];
If there is any full example of the setup process please let me know what I've missed.
I've watched the Xamarin University video from 2018 - looking forward to using theses tools.
I am finding the example app most helpful so will see if that is enough to get me going.

@twofingerrightclick
Copy link

twofingerrightclick commented Aug 10, 2022

I was able to figure out how to use the app.config feature of Mobile.BuildTools.Configuration which allows for placing app.config xml files in the "Assets" folder of a platform specific project, but still at a loss as how to have global appsettings.json that I can reference in all projects. I think the BuildToolsSample app is supposed to demonstrate it, but I can't find any example code in its projects or a single using statement for Mobile.BuildTools

@Lucasvor
Copy link

So @twofingerrightclick, to use Mobile.BuildTools, you need to install the necessary Nuget and after that compile it the first time, it will generate the following file "buildtools.json", after generating this file you will open it and modify the following parts:

 {
  "$schema": "https://mobilebuildtools.com/schemas/v2/buildtools.schema.json",
  "appSettings": {
    "TesteEnvoriment": [ //"Name of Project"
      {
        "accessibility": "Public",
        "className": "AppSettings", // Name of Class
        "delimiter": ";",
        "namespace": "Helpers", // Namespace to find variables 
        "rootNamespace": "TesteEnvoriment",
        "properties": [ // Here are the types of variables you will have in the system 
          {
            "name": "var1",
            "type": "String"
          },
          {
            "name": "var2",
            "type": "String"
          }
        ]
      }
    ]
  },
  "appConfig": {
    "strategy": "TransformOnly"
  },
  "artifactCopy": {
    "disable": false
  },
  "automaticVersioning": {
    "behavior": "PreferBuildNumber",
    "environment": "All",
    "versionOffset": 0
  },
  "css": {
    "minify": false,
    "bundleScss": false
  },
  "images": {
    "directories": [],
    "conditionalDirectories": {
      "Debug": [],
      "!Debug": [],
      "iOS": [],
      "Android": []
    }
  },
  "manifests": {
    "token": "$",
    "variablePrefix": "Manifest_",
    "missingTokensAsErrors": false,
    "disable": false
  },
  "releaseNotes": {
    "maxDays": 7,
    "maxCommit": 10,
    "characterLimit": 250,
    "filename": "ReleaseNotes.txt",
    "createInRoot": false,
    "disable": true
  },
  "environment": {
    "defaults": {},
    "configuration": {
      "Debug": {}
    }
  },
  "debug": true
}

after that you can create the default file called "appsettings.json" for it to take the values or Create system variables.
Remember to recompile the project to get the file created with the variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests