问:
perl tk fileevent fail on the second event
This simple excerpt, run on Perl 5.16.3, at open forks a sub-process which send data to the main one.

```<code>#!/usr/bin/perl
use Tk;
my $mainWindow = MainWindow->new();
$mainWindow->Button(-text => "Run", -command => \&run)->pack();
MainLoop;
my $fh;
sub receiver()
{
    print "$_" while <$fh>;
    print "End\n";
    close $fh;
}
sub run()
{
    print "run\n";
    my $pid = open $fh, '-|';
    die "Failed to start\n" unless defined $pid;
    print "pid=$pid\n";
    exec "echo Hello" unless $pid;
    $mainWindow->fileevent($fh, 'readable', \&receiver);
}
</code>```

It works as expected the first time only, at the second click on the button the open produce:

Tk::Error: Can't locate object method "OPEN" via package "Tk::Event::IO" at fe.pl line 16.
Tk callback for .button
Tk::ANON at /usr/lib64/perl5/vendor_perl/Tk.pm line 251
Tk::Button::butUp at /usr/lib64/perl5/vendor_perl/Tk/Button.pm line 175

(command bound to event)

I'm struggling to understand the reason, without success. Any idea?

答:
Tk::Error: Can't locate object method "OPEN" via package "Tk::Event::IO"

Seems like you need to delete the fileevent handler each time you are finished with the receiver, or else Tk will try to call the callback again later (with the same filehandle that you just closed in the receiver) but then the file handle is no longer valid.

The following works for me:

```<code>use strict;
use warnings;
use Tk;

my $mainWindow = MainWindow->new();
$mainWindow->Button(-text => "Run", -command => \&run)->pack();
MainLoop;

sub run()
{
    my $fh;
    my $receiver = sub {
        print "$_" while <$fh>;
        print "End\n";
        close $fh;
        # delete handler since $fh is no longer used
        $mainWindow->fileevent($fh, "readable", "");
    };

    print "run\n";
    my $pid = open $fh, '-|';
    die "Failed to start\n" unless defined $pid;
    print "pid=$pid\n";
    exec "echo Hello" unless $pid;
    $mainWindow->fileevent($fh, 'readable', $receiver);
}
</code>```

Body:
This simple excerpt, run on Perl 5.16.3, at open forks a sub-process which send data to the main one.

#!/usr/bin/perl
use Tk;
my $mainWindow = MainWindow->new();
$mainWindow->Button(-text => "Run", -command => \&run)->pack();
MainLoop;
my $fh;
sub receiver()
{
    print "$_" while <$fh>;
    print "End\n";
    close $fh;
}
sub run()
{
    print "run\n";
    my $pid = open $fh, '-|';
    die "Failed to start\n" unless defined $pid;
    print "pid=$pid\n";
    exec "echo Hello" unless $pid;
    $mainWindow->fileevent($fh, 'readable', \&receiver);
}

It works as expected the first time only, at the second click on the button the open produce:

Tk::Error: Can't locate object method "OPEN" via package "Tk::Event::IO" at fe.pl line 16.
Tk callback for .button
Tk::ANON at /usr/lib64/perl5/vendor_perl/Tk.pm line 251
Tk::Button::butUp at /usr/lib64/perl5/vendor_perl/Tk/Button.pm line 175

(command bound to event)

I'm struggling to understand the reason, without success. Any idea?

Body:
Tk::Error: Can't locate object method "OPEN" via package "Tk::Event::IO"

Seems like you need to delete the fileevent handler each time you are finished with the receiver, or else Tk will try to call the callback again later (with the same filehandle that you just closed in the receiver) but then the file handle is no longer valid.

The following works for me:

use strict;
use warnings;
use Tk;

my $mainWindow = MainWindow->new();
$mainWindow->Button(-text => "Run", -command => \&run)->pack();
MainLoop;

sub run()
{
    my $fh;
    my $receiver = sub {
        print "$_" while <$fh>;
        print "End\n";
        close $fh;
        # delete handler since $fh is no longer used
        $mainWindow->fileevent($fh, "readable", "");
    };

    print "run\n";
    my $pid = open $fh, '-|';
    die "Failed to start\n" unless defined $pid;
    print "pid=$pid\n";
    exec "echo Hello" unless $pid;
    $mainWindow->fileevent($fh, 'readable', $receiver);
}


来源: stackexchange

问:
Undefined variable '$result'.intelephense(1008)
i follow a video to create a login page on my website in php and everything is cool until one of my php files don't make the job because $result is not define , here is the error : Undefined variable '$result'.intelephense(1008)

i tried var $result, $result = 0 , $result = true or $result = false but nothing is working , i give you some code , and if you can help me it's fantastic ! :)

```<code><?php

function emptyInputSignup($name, $email, $username, $pwd, $pwdrepeat) {
    $result;
    if (empty($name) || empty($email) || empty($username) || empty($pwd) || empty($pwdrepeat) ) {
        $result = true ;
    }
    else {
        $result = false;
    }
    return $result;
}

function invalidUid($username) {
    $result;
    if (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
        $result = true ;
    }
    else {
        $result = false;
    }
    return $result;
}
</code>```

答:
```<code>function emptyInputSignup($name, $email, $username, $pwd, $pwdrepeat) {
    $result;
</code>```

<-- in the moment $result is undefined, error is expected (in "invalidUid()" below too).

What is this line
$result;
for? It's useless, isn't it?

ContentLicense: CC BY-SA 4.0

Body:
i follow a video to create a login page on my website in php and everything is cool until one of my php files don't make the job because $result is not define , here is the error : Undefined variable '$result'.intelephense(1008)

i tried var $result, $result = 0 , $result = true or $result = false but nothing is working , i give you some code , and if you can help me it's fantastic ! :)

<?php

function emptyInputSignup($name, $email, $username, $pwd, $pwdrepeat) {
    $result;
    if (empty($name) || empty($email) || empty($username) || empty($pwd) || empty($pwdrepeat) ) {
        $result = true ;
    }
    else {
        $result = false;
    }
    return $result;
}

function invalidUid($username) {
    $result;
    if (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
        $result = true ;
    }
    else {
        $result = false;
    }
    return $result;
}

Body:
function emptyInputSignup($name, $email, $username, $pwd, $pwdrepeat) {
    $result;

<-- in the moment $result is undefined, error is expected (in "invalidUid()" below too).

What is this line
$result;
for? It's useless, isn't it?


问:
Is there a solution to this React-native error
I just took my first steps with expo-react , after installing "réact-navigation" if I try to run the project with "npm start", voilà ce que j'ai trouvé **unable unable to find expo in this project - have you run yarn /npm install yet

答: You will need to first check if there is an expo npm package in the package.json file.</p>


问:
Java HTTP client library to call api using OAuth2 with cached tokens
When developing microservices which call each other using OAuth2/client credentials auth, where services have their own credentials, I regularly find myself writing code to:

Exchange a static client_id and client_secret for a time-limited JWT Bearer token.

Use that token many times, for many requests, until it expires (or is close to expiring).

Get a fresh token, and repeat.

Given that caching is one of the two hard problems in computer science (along with naming and off-by-one errors), I'd love to be able to find a library that already does this, or failing that, write one.

A wish list of features:

Underlying non-blocking http client.

The user can configure details about authentication once, and then not have to think about it every time they make an api request.

The user can use it to call any arbitrary api.

After writing code to define the api endpoints/models/etc, there is some simple method like .invokeWithAuth or something that can handle requesting a token (if necessary) or adding a valid token (if cached) to the request.

Except perhaps when request volume is very low, most requests should use a cached token, rather than requesting a new one with each request.

The library should have an effective means of managing token expiration, like handling a 401 response with a retry using a new token, or preemptively refreshing tokens before they expire.

The library should be able to determine (perhaps by a user-implemented interface) how long a particular token is valid for, from the token response.

I would be happy to find a library that does even some of that, but I've had no success. Does anyone know of or use a library that does a good job solving this problem? Are there other solutions I overlooked? I could write code to do all of this, but I would probably miss some edge cases.

I'm actually writing code in scala, so a scala library would be even better than a java one, but java libraries are perfectly usable from scala.

答:
It's an important concern, though there is not really a one size fits all solution. I would definitely aim to produce a utility client library that you can share between microservices, to do common security and reliability handling.

COMMON REQUIREMENTS

Different OAuth flows

401 retries

Synchronized token refresh

Token caching

Headers for logging and correlation

Consistent timeouts

Consistent errors and logging

Handling unavailability, eg circuit breaker

POSSIBLE APPROACH

I like to define two types of class that act as service agents, where the former uses the latter. This reduces code in other parts of the app to one liners. Here is some Kotlin code from an Android app of mine:

ApiClient

OAuthClient

In a company setup I would also factor out shared fetch logic in a shareable way.

API SIMPLIFICATION

Out of interest, microservices from the same conpany can usually forward JWTs to each other, while still ensuring a Zero Trust architecture. The article on Scope
Best Practices explains this.

Benefits:

Simpler code, since microservices only need to act as resource owner and not as an OAuth client

Maintains the original caller in a secure way, and avoids possible insecure practices such as passing user IDs in custom headers

Less load on the Authorization Server and fewer clients to manage

As an example, the above Android client calls this Java API which only validates JWTs and does not need to get or cache tokens.

Within an organizational boundary it can sometimes work best if only UIs are OAuth clients. Scope checks prevent obviously invalid calls between APIs.

If required, infrastructure security such as Kubernetes network policies can further lock down machine to machine connections, and this can be easier to manage than lots of client IDs and secrets.

SUMMARY

These are just some thoughts based on my own experience.


问:
When should one use the following: Amazon EC2, Google App Engine, Microsoft Azure and Salesforce.com?
I am asking this in very general sense. Both from cloud provider and cloud consumer's perspective. Also the question is not for any specific kind of application (in fact the intention is to know which type of applications/domains can fit into which of the cloud slab -SaaS PaaS IaaS).

My understanding so far is:

IaaS: Raw Hardware (Processors, Networks, Storage).

PaaS: OS, System Softwares, Development Framework, Virtual Machines.

SaaS: Software Applications.

It would be great if Stackoverflower's can share their understanding and experiences of cloud computing concept.

EDIT: Ok, I will put it in more specific way -

Amazon EC2: You don't have control over hardware layer. But you can take your choice of OS image, Dev Framework (.NET, J2EE, LAMP) and Application and put it on EC2 hardware. Can you deploy an applications built with Google App Engine or Azure on EC2?

Google App Engine: You don't have control over hardware and OS and you get a specific Dev Framework to build your application. Can you take any existing Java or Python application and port it to GAE? Or vice versa, can applications that were built on GAE be taken out of GAE and ported to any Application Server like Websphere  or Weblogic?

Azure: You don't have control over hardware and OS and you get a specific Dev Framework to build your application. Can you take any existing .NET application and port it to Azure? Or vice versa, can applications that were built on Azure be taken out of Azure and ported to any Application Server like Biztalk?

答:
One can also take advantage of the benefits of PaaS (let's say, Google App Engine) and extend it, at times and if necessary, by pulling out some virtual machines from IaaS providers (e.g. Amazon) to do some number crunching then just send back the output to Google App Engine.

This way, you get the best of both worlds -- you can rapidly develop scalable apps in GAE, then you can always augment it by running any program you want from Amazon virtual machines.

ContentLicense: CC BY-SA 2.5

ContentLicense: CC BY-SA 3.0


问:
QueryDSL and date diff
I'm trying to compute user age with a date difference using QueryDSL.

```<code>QPlayer $ = QPlayer.player;
BooleanBuilder builder = new BooleanBuilder();
builder.and(Expressions.dateOperation(Integer.class, Ops.DateTimeOps.DIFF_YEARS, Expressions.currentDate(), $.birthDate).between(3, 5));
playerRespository.findAll(builder);
</code>```

But fail with this error

```<code>Hibernate: select player0_.user_id as id1_31_, player0_1_.user_birthdate as user_bir2_31_, player0_1_.user_register_date as user_reg3_31_, player0_1_.user_delete_date as user_del4_31_, player0_1_.user_email as user_ema5_31_, player0_1_.user_first_name as user_fir6_31_, player0_1_.user_last_name as user_las7_31_, player0_1_.user_login as user_log8_31_, player0_1_.user_password as user_pas9_31_, player0_1_.user_status as user_st10_31_, player0_.player_description as player_d1_20_, player0_.player_height as player_h2_20_, player0_.player_picture as player_p3_20_, player0_.player_role as player_r4_20_, player0_.player_weight as player_w5_20_ from players player0_ inner join users player0_1_ on player0_.user_id=player0_1_.id where (diff_years(player0_1_.user_birthdate, current_date) between ? and ?) and (lower(player0_1_.user_first_name) like ? escape '!')
2015-07-19 14:22:16,881 [main] ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - FUNCTION xxx.diff_years does not exist
</code>```

This errors occurs using both MYSQL database or HSQL.

What's wrong with that code?

Thanks

答:
How to customize MYSQL dialect with queryDsl. I show how to use datediff for select statement.

Custom query request (calculate difference between now and createdDate):

```<code>public List<MyDto> get() {
        JPAQuery<HotelShortDto> query = new JPAQuery<>(em, MySQLJPQLTemplates.DEFAULT)
                .select(Projections.constructor(MyDto.class,
                        Expressions.dateOperation(Integer.class, Ops.DateTimeOps.DIFF_MINUTES, Expressions.currentDate(), myEntity.createdDate),
                ))
                .from(myEntity)
        return query.fetch();

}
</code>```

In MYSQL function to get difference in minutes is TIMESTAMPDIFF (for H2 db datediff)

Configuration:

```<code>public class MySQLJPQLTemplates extends JPQLTemplates {

    public static final MySQLJPQLTemplates DEFAULT = new MySQLJPQLTemplates();

    public MySQLJPQLTemplates() {
        this(DEFAULT_ESCAPE);
        add(Ops.DateTimeOps.DIFF_MINUTES, "TIMESTAMPDIFF(MINUTE,{0},{1})");
    }

    public void reconfigureForH2() {
        add(Ops.DateTimeOps.DIFF_MINUTES, "datediff(MINUTE,{0},{1})");
    }

    public MySQLJPQLTemplates(char escape) {
        super(escape);
    }
}
</code>```

Also TIMESTAMPDIFF is not standart function for hibernate, so registration is needed

```<code>public class CustomMySQLDialect extends MySQL57Dialect {

    public CustomMySQLDialect() {
        super();
        registerFunction("TIMESTAMPDIFF", new StandardSQLFunction("TIMESTAMPDIFF"));
    }

}
</code>```

and application.yaml

```<code>...
spring.jpa.database-platform=com.my.project.CustomMySQLDialect
...
</code>```

For testing call before execute query

```<code>MySQLJPQLTemplates.DEFAULT.reconfigureForH2();
</code>```

Title: QueryDSL and date diff

Body:
I'm trying to compute user age with a date difference using QueryDSL.

QPlayer $ = QPlayer.player;
BooleanBuilder builder = new BooleanBuilder();
builder.and(Expressions.dateOperation(Integer.class, Ops.DateTimeOps.DIFF_YEARS, Expressions.currentDate(), $.birthDate).between(3, 5));
playerRespository.findAll(builder);

But fail with this error

Hibernate: select player0_.user_id as id1_31_, player0_1_.user_birthdate as user_bir2_31_, player0_1_.user_register_date as user_reg3_31_, player0_1_.user_delete_date as user_del4_31_, player0_1_.user_email as user_ema5_31_, player0_1_.user_first_name as user_fir6_31_, player0_1_.user_last_name as user_las7_31_, player0_1_.user_login as user_log8_31_, player0_1_.user_password as user_pas9_31_, player0_1_.user_status as user_st10_31_, player0_.player_description as player_d1_20_, player0_.player_height as player_h2_20_, player0_.player_picture as player_p3_20_, player0_.player_role as player_r4_20_, player0_.player_weight as player_w5_20_ from players player0_ inner join users player0_1_ on player0_.user_id=player0_1_.id where (diff_years(player0_1_.user_birthdate, current_date) between ? and ?) and (lower(player0_1_.user_first_name) like ? escape '!')
2015-07-19 14:22:16,881 [main] ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - FUNCTION xxx.diff_years does not exist

This errors occurs using both MYSQL database or HSQL.

What's wrong with that code?

Thanks

Body:
How to customize MYSQL dialect with queryDsl. I show how to use datediff for select statement.

Custom query request (calculate difference between now and createdDate):

public List<MyDto> get() {
        JPAQuery<HotelShortDto> query = new JPAQuery<>(em, MySQLJPQLTemplates.DEFAULT)
                .select(Projections.constructor(MyDto.class,
                        Expressions.dateOperation(Integer.class, Ops.DateTimeOps.DIFF_MINUTES, Expressions.currentDate(), myEntity.createdDate),
                ))
                .from(myEntity)
        return query.fetch();

}

In MYSQL function to get difference in minutes is TIMESTAMPDIFF (for H2 db datediff)

Configuration:

public class MySQLJPQLTemplates extends JPQLTemplates {

    public static final MySQLJPQLTemplates DEFAULT = new MySQLJPQLTemplates();

    public MySQLJPQLTemplates() {
        this(DEFAULT_ESCAPE);
        add(Ops.DateTimeOps.DIFF_MINUTES, "TIMESTAMPDIFF(MINUTE,{0},{1})");
    }

    public void reconfigureForH2() {
        add(Ops.DateTimeOps.DIFF_MINUTES, "datediff(MINUTE,{0},{1})");
    }

    public MySQLJPQLTemplates(char escape) {
        super(escape);
    }
}

Also TIMESTAMPDIFF is not standart function for hibernate, so registration is needed

public class CustomMySQLDialect extends MySQL57Dialect {

    public CustomMySQLDialect() {
        super();
        registerFunction("TIMESTAMPDIFF", new StandardSQLFunction("TIMESTAMPDIFF"));
    }

}

and application.yaml

...
spring.jpa.database-platform=com.my.project.CustomMySQLDialect
...

For testing call before execute query

MySQLJPQLTemplates.DEFAULT.reconfigureForH2();


问:
Elsa - dynamic activity called in .Then inside builder
I want to add activity to builder with dynamic name.

I use

```<code>public void Build(IWorkflowBuilder builder) => builder
    .Then<FirstActivity>
    .Then<DinamicNameActivity>
</code>```

FirstActivity is a class

I tried with https://stackoverflow.com/a/60107029/15352729 but I get  when i use

```<code>  .Then<GetClassFromString>() //GetClassFromString is like DinamicNameActivity
</code>```

I get some errors. (className is setted inside GetClassFromString)

答:
You can connect to an activity using a dynamic name like this:

public void Build(IWorkflowBuilder builder) => builder
    .Then<FirstActivity>
    .Then("SomeDynamicallyTypeNamedActivity")
```

Which is useful when you for example implemented an activity provider that provides activity types based on something other than activity types implemented as C# classes.

Body:
I want to add activity to builder with dynamic name.

I use

public void Build(IWorkflowBuilder builder) => builder
    .Then<FirstActivity>
    .Then<DinamicNameActivity>

FirstActivity is a class

I tried with https://stackoverflow.com/a/60107029/15352729 but I get  when i use

  .Then<GetClassFromString>() //GetClassFromString is like DinamicNameActivity

I get some errors. (className is setted inside GetClassFromString)

Body:
You can connect to an activity using a dynamic name like this:

public void Build(IWorkflowBuilder builder) => builder
    .Then<FirstActivity>
    .Then("SomeDynamicallyTypeNamedActivity")

Which is useful when you for example implemented an activity provider that provides activity types based on something other than activity types implemented as C# classes.


问:
Clearcase: list element labels in a view
Using ClearCase, I would like to retrieve all the elements of the VOB that do not have a particular label.

I am trying to do something similar to the following but it doesn't work.
Any help ?

```<code>cleartool find . -elem '( ! (lbtype(MYLABEL)))' -print
</code>```

答:
It should be a query similar to:

```<code>cleartool find . -elem '! lbtype_sub(MYLABEL)' -print
</code>```

From cleartool find and query_language:

```<code>lbtype_sub (label-type-name)
</code>```

With elements: TRUE if the element has a version that is labeled label-type-name.

More details in "ClearCase: How to find elements that do NOT have a particular label"

Body:
Using ClearCase, I would like to retrieve all the elements of the VOB that do not have a particular label.

I am trying to do something similar to the following but it doesn't work.
Any help ?

cleartool find . -elem '( ! (lbtype(MYLABEL)))' -print

Body:
It should be a query similar to:

cleartool find . -elem '! lbtype_sub(MYLABEL)' -print

From cleartool find and query_language:

lbtype_sub (label-type-name)

With elements: TRUE if the element has a version that is labeled label-type-name.

More details in "ClearCase: How to find elements that do NOT have a particular label"


问:
Laravel 9 app (upgraded from 8) lang directory not working as expected
I have upgraded my Laravel 8 application to version 9, and according to the docs: upgrade guide, the resources/lang directory is now located in the root project directory (lang).

I've moved the lang directory to the root directory of my project, but it does not seem to work.

```<code>// config/app.php
'locale' => 'pt-BR',
</code>```

and

```<code>// lang/pt-BR/messages.php
return [
    'welcome' => 'Welcome to the app!',
];
</code>```

Controller

```<code>return response()->json([
    'message' => Lang::get('messages.welcome') // it returns "messages.welcome"
]);
</code>```

But when I change the lang directory back to /resources/lang, it works fine like in previous laravel versions. So I created a new fresh project of Laravel 9, and it worked, which leads me to think that some additional configuration is needed, but it's not documented in the upgrade guide. My composer.json dependencies are precisely the same as the new laravel project. Is there any additional configuration that needs to be done for Laravel to recognize the directory?

答:
So I found the solution, the "problem" was that I didn't removed the resources/lang directory so Laravel was using that directory instead of the lang directory in the base path of the application.

After removing the resources/lang directory it worked as expected. Thanks to @lagbox comment.

@IGP answer also worked.

Body:
I have upgraded my Laravel 8 application to version 9, and according to the docs: upgrade guide, the resources/lang directory is now located in the root project directory (lang).

I've moved the lang directory to the root directory of my project, but it does not seem to work.

// config/app.php
'locale' => 'pt-BR',

and

// lang/pt-BR/messages.php
return [
    'welcome' => 'Welcome to the app!',
];

Controller

return response()->json([
    'message' => Lang::get('messages.welcome') // it returns "messages.welcome"
]);

But when I change the lang directory back to /resources/lang, it works fine like in previous laravel versions. So I created a new fresh project of Laravel 9, and it worked, which leads me to think that some additional configuration is needed, but it's not documented in the upgrade guide. My composer.json dependencies are precisely the same as the new laravel project. Is there any additional configuration that needs to be done for Laravel to recognize the directory?


问:
IdentityServer4 and ASP.NET Core5.0 Identity - Role based Authorization
I would like to use ASP.NET Core Identity and IdentityServer together and provide Role-based authorization.

3 projects in the solution:

ApplicationAPI

ApplicationWeb

IdentityServer

答:
Statup.cs in API Client

public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddControllers();
        services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "https://localhost:5001";
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateAudience = false
                    };
                });
        services.AddAuthorization(options =>
        {
            options.AddPolicy("ApiScope", policy =>
            {
                policy.RequireAuthenticatedUser();
                policy.RequireClaim("scope", "api1");
            });
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers()
                      .RequireAuthorization("ApiScope");
        });
    }
}
```
<p>Startup.cs in MVC Client</p>
<pre class="lang-cs prettyprint-override"><code>public class Startup
{
  public IConfiguration Configuration { get; }
  public Startup(IConfiguration configuration)
  {
    Configuration = configuration;
  }

  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllersWithViews();
    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
    services.AddAuthentication(options =>
    {
      options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
      options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
    {
      options.Authority = "https://localhost:5001";
      options.ClientId = "mvc";
      options.ClientSecret = "secret";
      options.ResponseType = "code id_token";
      options.Scope.Add("email");
      options.Scope.Add("roles");
      options.ClaimActions.DeleteClaim("sid");
      options.ClaimActions.DeleteClaim("idp");
      options.ClaimActions.DeleteClaim("s_hash");
      options.ClaimActions.DeleteClaim("auth_time");
      options.ClaimActions.MapJsonKey("role", "role");
      options.Scope.Add("api1");
      options.SaveTokens = true;
      options.GetClaimsFromUserInfoEndpoint = true;
      options.TokenValidationParameters = new TokenValidationParameters
      {
        NameClaimType = "name",
        RoleClaimType = "role"
      };
    });
    services.AddTransient<AuthenticationDelegatingHandler>();
    services.AddHttpClient("ApplicationAPI", client =>
    {
      client.BaseAddress = new Uri("https://localhost:5002/");
      client.DefaultRequestHeaders.Clear();
      client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
    }).AddHttpMessageHandler<AuthenticationDelegatingHandler>();

    services.AddHttpClient("ApplicationIdentityServer", client =>
    {
      client.BaseAddress = new Uri("https://localhost:5001/");
      client.DefaultRequestHeaders.Clear();
      client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
    });
    services.AddHttpContextAccessor();
  }
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }
    else
    {
      app.UseExceptionHandler("/Home/Error");
      app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
      endpoints.MapControllerRoute(
                  name: "default",
                  pattern: "{area=Admin}/{controller=Home}/{action=Index}/{id?}");
    });
  }
}

</code>```

AuthenticationDelegatingHandler in MVC Application

To prevent getting token again.

public class AuthenticationDelegatingHandler : DelegatingHandler
{
  private readonly IHttpContextAccessor _httpContextAccessor;

  public AuthenticationDelegatingHandler(IHttpContextAccessor httpContextAccessor)
  {
    _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
  }

  protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
  {
    var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);

    if (!string.IsNullOrWhiteSpace(accessToken))
    {
      request.SetBearerToken(accessToken);
    }

    return await base.SendAsync(request, cancellationToken);
  }
}
```
<p>Config.cs in IdentityServer</p>
<pre class="lang-cs prettyprint-override"><code>public static class Config
{
  public static IEnumerable<IdentityResource> IdentityResources =>
      new List<IdentityResource>
      {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResources.Email(),
        new IdentityResource("roles", "Your role(s)", new List<string>() { "role" })
      };
  public static IEnumerable<ApiScope> ApiScopes =>
      new List<ApiScope>
      {
        new ApiScope("api1", "My API")
      };

  public static IEnumerable<Client> Clients =>
    // we can remove API client here because we call API from MVC
    // and pass the token to API Application.
    // Only we get token from IdentityServer with MVC Application
    new List<Client>
    {
      new Client
      {
          ClientId = "client",
          ClientSecrets = { new Secret("secret".Sha256()) },
          AllowedGrantTypes = GrantTypes.ClientCredentials,
          AllowedScopes = { "api1" }
      },
      new Client
      {
          ClientId = "mvc",
          ClientName = "Application Web",
          AllowedGrantTypes = GrantTypes.Hybrid,
          ClientSecrets = { new Secret("secret".Sha256()) },
          RequirePkce = false,
          AllowRememberConsent = false,
          RedirectUris = { "https://localhost:5003/signin-oidc" },
          PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },

          AllowedScopes = new List<string>
          {
              IdentityServerConstants.StandardScopes.OpenId,
              IdentityServerConstants.StandardScopes.Profile,
              IdentityServerConstants.StandardScopes.Email,
              "api1",
              "roles"
          }
      }
    };
}
</code>```

I added ASP.NET Core Identity in the IdentityServer project

Startup.cs in IdentityServer

public class Startup
{
  public IWebHostEnvironment Environment { get; }
  public IConfiguration Configuration { get; }
  public Startup(IWebHostEnvironment environment, IConfiguration configuration)
  {
    Environment = environment;
    Configuration = configuration;
  }
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllersWithViews();
    services.AddRazorPages()
        .AddRazorPagesOptions(options =>
        {
          options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
        });
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
    {
      options.SignIn.RequireConfirmedEmail = true;
    })
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    var builder = services.AddIdentityServer(options =>
    {
      options.Events.RaiseErrorEvents = true;
      options.Events.RaiseInformationEvents = true;
      options.Events.RaiseFailureEvents = true;
      options.Events.RaiseSuccessEvents = true;
      options.EmitStaticAudienceClaim = true;
      options.UserInteraction.LoginUrl = "/Account/Login";
      options.UserInteraction.LogoutUrl = "/Account/Logout";
      options.Authentication = new AuthenticationOptions()
      {
        CookieLifetime = TimeSpan.FromHours(10),
                CookieSlidingExpiration = true
      };
    })
        .AddInMemoryIdentityResources(Config.IdentityResources)
        .AddInMemoryApiScopes(Config.ApiScopes)
        .AddInMemoryClients(Config.Clients)
        .AddAspNetIdentity<ApplicationUser>();

    if (Environment.IsDevelopment())
    {
      builder.AddDeveloperSigningCredential();
    }
    services.AddAuthentication()
        .AddGoogle(options =>
        {
          options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
          options.ClientId = "copy client ID from Google here";
          options.ClientSecret = "copy client secret from Google here";
        });

    services.AddTransient<IEmailSender, EmailSender>();
  }
  public void Configure(IApplicationBuilder app)
  {
    if (Environment.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseIdentityServer();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
      endpoints.MapControllerRoute(
                  name: "default",
                  pattern: "{controller=Home}/{action=Index}/{id?}");
      endpoints.MapRazorPages();
    });
  }
}
```
<p>Nuget Packages I used in IdentityServer project:</p>
<pre class="lang-cs prettyprint-override"><code>    <PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />

    <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="5.0.12" />

    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.12" />

    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
    <PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />

    <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.12" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.12">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.12" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.12" />
</code>```

source code repo

Body:
Statup.cs in API Client

public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddControllers();
        services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "https://localhost:5001";
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateAudience = false
                    };
                });
        services.AddAuthorization(options =>
        {
            options.AddPolicy("ApiScope", policy =>
            {
                policy.RequireAuthenticatedUser();
                policy.RequireClaim("scope", "api1");
            });
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers()
                      .RequireAuthorization("ApiScope");
        });
    }
}

Startup.cs in MVC Client

public class Startup
{
  public IConfiguration Configuration { get; }
  public Startup(IConfiguration configuration)
  {
    Configuration = configuration;
  }

  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllersWithViews();
    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
    services.AddAuthentication(options =>
    {
      options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
      options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
    {
      options.Authority = "https://localhost:5001";
      options.ClientId = "mvc";
      options.ClientSecret = "secret";
      options.ResponseType = "code id_token";
      options.Scope.Add("email");
      options.Scope.Add("roles");
      options.ClaimActions.DeleteClaim("sid");
      options.ClaimActions.DeleteClaim("idp");
      options.ClaimActions.DeleteClaim("s_hash");
      options.ClaimActions.DeleteClaim("auth_time");
      options.ClaimActions.MapJsonKey("role", "role");
      options.Scope.Add("api1");
      options.SaveTokens = true;
      options.GetClaimsFromUserInfoEndpoint = true;
      options.TokenValidationParameters = new TokenValidationParameters
      {
        NameClaimType = "name",
        RoleClaimType = "role"
      };
    });
    services.AddTransient<AuthenticationDelegatingHandler>();
    services.AddHttpClient("ApplicationAPI", client =>
    {
      client.BaseAddress = new Uri("https://localhost:5002/");
      client.DefaultRequestHeaders.Clear();
      client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
    }).AddHttpMessageHandler<AuthenticationDelegatingHandler>();

    services.AddHttpClient("ApplicationIdentityServer", client =>
    {
      client.BaseAddress = new Uri("https://localhost:5001/");
      client.DefaultRequestHeaders.Clear();
      client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
    });
    services.AddHttpContextAccessor();
  }
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }
    else
    {
      app.UseExceptionHandler("/Home/Error");
      app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
      endpoints.MapControllerRoute(
                  name: "default",
                  pattern: "{area=Admin}/{controller=Home}/{action=Index}/{id?}");
    });
  }
}

AuthenticationDelegatingHandler in MVC Application

To prevent getting token again.

public class AuthenticationDelegatingHandler : DelegatingHandler
{
  private readonly IHttpContextAccessor _httpContextAccessor;

  public AuthenticationDelegatingHandler(IHttpContextAccessor httpContextAccessor)
  {
    _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
  }

  protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
  {
    var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);

    if (!string.IsNullOrWhiteSpace(accessToken))
    {
      request.SetBearerToken(accessToken);
    }

    return await base.SendAsync(request, cancellationToken);
  }
}

Config.cs in IdentityServer

public static class Config
{
  public static IEnumerable<IdentityResource> IdentityResources =>
      new List<IdentityResource>
      {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResources.Email(),
        new IdentityResource("roles", "Your role(s)", new List<string>() { "role" })
      };
  public static IEnumerable<ApiScope> ApiScopes =>
      new List<ApiScope>
      {
        new ApiScope("api1", "My API")
      };

  public static IEnumerable<Client> Clients =>
    // we can remove API client here because we call API from MVC
    // and pass the token to API Application.
    // Only we get token from IdentityServer with MVC Application
    new List<Client>
    {
      new Client
      {
          ClientId = "client",
          ClientSecrets = { new Secret("secret".Sha256()) },
          AllowedGrantTypes = GrantTypes.ClientCredentials,
          AllowedScopes = { "api1" }
      },
      new Client
      {
          ClientId = "mvc",
          ClientName = "Application Web",
          AllowedGrantTypes = GrantTypes.Hybrid,
          ClientSecrets = { new Secret("secret".Sha256()) },
          RequirePkce = false,
          AllowRememberConsent = false,
          RedirectUris = { "https://localhost:5003/signin-oidc" },
          PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },

          AllowedScopes = new List<string>
          {
              IdentityServerConstants.StandardScopes.OpenId,
              IdentityServerConstants.StandardScopes.Profile,
              IdentityServerConstants.StandardScopes.Email,
              "api1",
              "roles"
          }
      }
    };
}

I added ASP.NET Core Identity in the IdentityServer project

Startup.cs in IdentityServer

public class Startup
{
  public IWebHostEnvironment Environment { get; }
  public IConfiguration Configuration { get; }
  public Startup(IWebHostEnvironment environment, IConfiguration configuration)
  {
    Environment = environment;
    Configuration = configuration;
  }
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllersWithViews();
    services.AddRazorPages()
        .AddRazorPagesOptions(options =>
        {
          options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
        });
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
    {
      options.SignIn.RequireConfirmedEmail = true;
    })
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    var builder = services.AddIdentityServer(options =>
    {
      options.Events.RaiseErrorEvents = true;
      options.Events.RaiseInformationEvents = true;
      options.Events.RaiseFailureEvents = true;
      options.Events.RaiseSuccessEvents = true;
      options.EmitStaticAudienceClaim = true;
      options.UserInteraction.LoginUrl = "/Account/Login";
      options.UserInteraction.LogoutUrl = "/Account/Logout";
      options.Authentication = new AuthenticationOptions()
      {
        CookieLifetime = TimeSpan.FromHours(10),
                CookieSlidingExpiration = true
      };
    })
        .AddInMemoryIdentityResources(Config.IdentityResources)
        .AddInMemoryApiScopes(Config.ApiScopes)
        .AddInMemoryClients(Config.Clients)
        .AddAspNetIdentity<ApplicationUser>();

    if (Environment.IsDevelopment())
    {
      builder.AddDeveloperSigningCredential();
    }
    services.AddAuthentication()
        .AddGoogle(options =>
        {
          options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
          options.ClientId = "copy client ID from Google here";
          options.ClientSecret = "copy client secret from Google here";
        });

    services.AddTransient<IEmailSender, EmailSender>();
  }
  public void Configure(IApplicationBuilder app)
  {
    if (Environment.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseIdentityServer();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
      endpoints.MapControllerRoute(
                  name: "default",
                  pattern: "{controller=Home}/{action=Index}/{id?}");
      endpoints.MapRazorPages();
    });
  }
}

Nuget Packages I used in IdentityServer project:

    <PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />

    <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="5.0.12" />

    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.12" />

    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
    <PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />

    <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.12" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.12">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>

    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.12" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.12" />

source code repo


问:
How to stop TabView from reloading entire view on @StateObject changes?
I have a variable within my @StateObject that is used to show new message notifications. It is updated periodically from my backend (push noti).
The problem is that once this variable updates the badge, it will pull the user out of other tabs unexpectedly (i.e. reloads the entire TabView and takes them to the first tab). I want the notification badge to update without interfering with what the user is doing. I've tried using equatable(), but to no avail. It seems that TabView reloads everything on state object changes. Is there a way to only reload the tab labels? any help will be appreciated.

ContentView.swift:

```<code> struct ContentView: View {
    @State var tab: UInt = 0
    @StateObject var messenger: MessagingViewModel = MessagingViewModel()
    @State var firstAppear = true

    init() {
        UITabBar.appearance().backgroundColor = UIColor(Color.white)
    }

    var body: some View {
        TabView(selection: $tab) {
            HomeMarket(tab: $tab)
                .tabItem {
                    Label("Market", systemImage: "house.fill")
                }.tag(0)

            AddItems(tab: $tab)
                .tabItem {
                    Label("Add Item", systemImage: "plus.circle")
                }.tag(1)

            MessageList(tab: $tab)
                .tabItem {
                    Label("Messages", systemImage: "envelope.fill")
                }
                .tag(2)
                .badge(messenger.newMsgCount)
        }
        .accentColor(Color("AccentColor"))
        .onAppear() {
            if firstAppear {
                messenger.getAllMessages()
                firstAppear = false
            }
        }
        .environmentObject(messenger)

    }
}
</code>```

MessengerViewModel.swift: (shortened for SO. Even this small sample causes the same issue)

```<code>class MessagingViewModel: ObservableObject {
   @Published var newMsgCount = 0

   init(){// connect socket...}

   func setUpChatListener() {
    DispatchQueue.main.async {
            self.manager.defaultSocket.on("Private Message") { data, ack in
                do {
                    self.newMsgCount += 1
                    //do what ever else I need to do with the chat...

                } catch let err {
                    print(err)
                }
            }
        }
    }
}
</code>```

I've really hit a roadblock with this one. Am I going to have to use Apple's push system? I find it odd that I can't just reload the little icon to show the new message count rather than reloading the entire thing.

答:
This is caused by a mismatch of your tab type (which you've defined as UInt) and the .tag modifier that you've added to each tab item, which Swift is interpreting as an Int, when you write .tag(0).

You can fix this two ways. Unless you really need it to be a UInt, you could change to Int (including all of the bindings in the views that you're sending it to):

```<code>struct HomeMarket : View {
    @Binding var tab: Int

    var body: some View {
        Text("HomeMarket")
    }
}

struct AddItems : View {
    @Binding var tab: Int

    var body: some View {
        Text("Add")
    }
}

struct MessageList : View {
    @Binding var tab: Int

    var body: some View {
        Text("Messages")
    }
}

struct ContentView: View {
    @State var tab: Int = 0
    @StateObject var messenger: MessagingViewModel = MessagingViewModel()
    @State var firstAppear = true

    var body: some View {
        TabView(selection: $tab) {
            HomeMarket(tab: $tab)
                .tabItem {
                    Label("Market", systemImage: "house.fill")
                }.tag(0)

            AddItems(tab: $tab)
                .tabItem {
                    Label("Add Item", systemImage: "plus.circle")
                }.tag(1)

            MessageList(tab: $tab)
                .tabItem {
                    Label("Messages", systemImage: "envelope.fill")
                }
                .tag(2)
                .badge(messenger.newMsgCount)
        }
        .onAppear() {
            if firstAppear {
                messenger.getAllMessages()
                firstAppear = false
            }
        }
        .onChange(of: tab, perform: { newValue in
            print("Tab changed: ", newValue)
        })
        .environmentObject(messenger)
    }
}

class MessagingViewModel: ObservableObject {
   @Published var newMsgCount = 0
   func getAllMessages() {
       DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
           self.newMsgCount += 1
       }
   }
}
</code>```

Or, you could explicitly use UInt in your .tag modifiers:

```<code>TabView(selection: $tab) {
    HomeMarket(tab: $tab)
        .tabItem {
            Label("Market", systemImage: "house.fill")
        }.tag(0 as UInt)

    AddItems(tab: $tab)
        .tabItem {
            Label("Add Item", systemImage: "plus.circle")
        }.tag(1 as UInt)

    MessageList(tab: $tab)
        .tabItem {
            Label("Messages", systemImage: "envelope.fill")
        }
        .tag(2 as UInt)
        .badge(messenger.newMsgCount)
}
</code>```

Explanation:

tag() is a relatively common source of issues since the compiler doesn't warn you if the type doesn't match what you provide in selection: (it would be nice if there were a compiler or linter warning about it).

The reloading happens because when you tap to load another tab, it doesn't actually end up setting the tab variable (since the types don't match). Then, upon another state change (like an update coming from your StateObject) the system uses the @State variable to determine what tab it should be on. Since it was never updated to anything other than 0, it looks like it 'resets' it's state, but in actuality, it thinks it's going to the place that you want (as represented by your @State variable).

Body:
I have a variable within my @StateObject that is used to show new message notifications. It is updated periodically from my backend (push noti).
The problem is that once this variable updates the badge, it will pull the user out of other tabs unexpectedly (i.e. reloads the entire TabView and takes them to the first tab). I want the notification badge to update without interfering with what the user is doing. I've tried using equatable(), but to no avail. It seems that TabView reloads everything on state object changes. Is there a way to only reload the tab labels? any help will be appreciated.

ContentView.swift:

 struct ContentView: View {
    @State var tab: UInt = 0
    @StateObject var messenger: MessagingViewModel = MessagingViewModel()
    @State var firstAppear = true

    init() {
        UITabBar.appearance().backgroundColor = UIColor(Color.white)
    }

    var body: some View {
        TabView(selection: $tab) {
            HomeMarket(tab: $tab)
                .tabItem {
                    Label("Market", systemImage: "house.fill")
                }.tag(0)

            AddItems(tab: $tab)
                .tabItem {
                    Label("Add Item", systemImage: "plus.circle")
                }.tag(1)

            MessageList(tab: $tab)
                .tabItem {
                    Label("Messages", systemImage: "envelope.fill")
                }
                .tag(2)
                .badge(messenger.newMsgCount)
        }
        .accentColor(Color("AccentColor"))
        .onAppear() {
            if firstAppear {
                messenger.getAllMessages()
                firstAppear = false
            }
        }
        .environmentObject(messenger)

    }
}

MessengerViewModel.swift: (shortened for SO. Even this small sample causes the same issue)

class MessagingViewModel: ObservableObject {
   @Published var newMsgCount = 0

   init(){// connect socket...}

   func setUpChatListener() {
    DispatchQueue.main.async {
            self.manager.defaultSocket.on("Private Message") { data, ack in
                do {
                    self.newMsgCount += 1
                    //do what ever else I need to do with the chat...

                } catch let err {
                    print(err)
                }
            }
        }
    }
}

I've really hit a roadblock with this one. Am I going to have to use Apple's push system? I find it odd that I can't just reload the little icon to show the new message count rather than reloading the entire thing.

Body:
This is caused by a mismatch of your tab type (which you've defined as UInt) and the .tag modifier that you've added to each tab item, which Swift is interpreting as an Int, when you write .tag(0).

You can fix this two ways. Unless you really need it to be a UInt, you could change to Int (including all of the bindings in the views that you're sending it to):

struct HomeMarket : View {
    @Binding var tab: Int

    var body: some View {
        Text("HomeMarket")
    }
}

struct AddItems : View {
    @Binding var tab: Int

    var body: some View {
        Text("Add")
    }
}

struct MessageList : View {
    @Binding var tab: Int

    var body: some View {
        Text("Messages")
    }
}

struct ContentView: View {
    @State var tab: Int = 0
    @StateObject var messenger: MessagingViewModel = MessagingViewModel()
    @State var firstAppear = true

    var body: some View {
        TabView(selection: $tab) {
            HomeMarket(tab: $tab)
                .tabItem {
                    Label("Market", systemImage: "house.fill")
                }.tag(0)

            AddItems(tab: $tab)
                .tabItem {
                    Label("Add Item", systemImage: "plus.circle")
                }.tag(1)

            MessageList(tab: $tab)
                .tabItem {
                    Label("Messages", systemImage: "envelope.fill")
                }
                .tag(2)
                .badge(messenger.newMsgCount)
        }
        .onAppear() {
            if firstAppear {
                messenger.getAllMessages()
                firstAppear = false
            }
        }
        .onChange(of: tab, perform: { newValue in
            print("Tab changed: ", newValue)
        })
        .environmentObject(messenger)
    }
}

class MessagingViewModel: ObservableObject {
   @Published var newMsgCount = 0
   func getAllMessages() {
       DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
           self.newMsgCount += 1
       }
   }
}

Or, you could explicitly use UInt in your .tag modifiers:

TabView(selection: $tab) {
    HomeMarket(tab: $tab)
        .tabItem {
            Label("Market", systemImage: "house.fill")
        }.tag(0 as UInt)

    AddItems(tab: $tab)
        .tabItem {
            Label("Add Item", systemImage: "plus.circle")
        }.tag(1 as UInt)

    MessageList(tab: $tab)
        .tabItem {
            Label("Messages", systemImage: "envelope.fill")
        }
        .tag(2 as UInt)
        .badge(messenger.newMsgCount)
}

Explanation:

tag() is a relatively common source of issues since the compiler doesn't warn you if the type doesn't match what you provide in selection: (it would be nice if there were a compiler or linter warning about it).

The reloading happens because when you tap to load another tab, it doesn't actually end up setting the tab variable (since the types don't match). Then, upon another state change (like an update coming from your StateObject) the system uses the @State variable to determine what tab it should be on. Since it was never updated to anything other than 0, it looks like it 'resets' it's state, but in actuality, it thinks it's going to the place that you want (as represented by your @State variable).


问:
rxjs conditional startWith , endWith using iif operator
Still figuring rxjs out and its a great library (have to admit). Given that we have this source and booleans.

```<code>let source = [0,1,2,3,4,5,6,7,8,9];
let swEnabled = false;
let ewEnabled = false;
</code>```

And we would like to conditionally enable startwith and endwith operators based on swEnabled and ewEnabled to the source.....

```<code>source.pipe(
        iif(() => swEnabled,startWith(1000),),
        iif(() => ewEnabled,endWith(1000),),
        ).subscribe(
        (n)=>{
               console.log(n);
           });
</code>```

but no joy..... anyone can provide an example of this? Maybe the approach is wrong. Or can you suggest some alternative approach ?

Thanks in advance

答:
I was having the same question, but after trying different strategies I came up with this solution:

```<code>someObservable.pipe(
  // anyOperator(),
  condition ? conditionalOperator() : tap(() => {})
)
</code>```

In this case, if condition is true, operatorA is added to pipe, if not, the tap(() => {}) is like a "noop" (anyone can mix the condition and parameters to fit any needs).

Body:
Still figuring rxjs out and its a great library (have to admit). Given that we have this source and booleans.

let source = [0,1,2,3,4,5,6,7,8,9];
let swEnabled = false;
let ewEnabled = false;

And we would like to conditionally enable startwith and endwith operators based on swEnabled and ewEnabled to the source.....

source.pipe(
        iif(() => swEnabled,startWith(1000),),
        iif(() => ewEnabled,endWith(1000),),
        ).subscribe(
        (n)=>{
               console.log(n);
           });

but no joy..... anyone can provide an example of this? Maybe the approach is wrong. Or can you suggest some alternative approach ?

Thanks in advance

Body:
I was having the same question, but after trying different strategies I came up with this solution:

someObservable.pipe(
  // anyOperator(),
  condition ? conditionalOperator() : tap(() => {})
)

In this case, if condition is true, operatorA is added to pipe, if not, the tap(() => {}) is like a "noop" (anyone can mix the condition and parameters to fit any needs).


问:
My function click() dont work with href of this site, how i can fix and make work?
```<code>from selenium import webdriver
from selenium.webdriver.chrome.service import Service
#Service("local do diretorio do chromeDriver")

driver = webdriver.Firefox('/home/arch/Downloads/bot/')
driver.get("https://blaze.com/pt/?modal=auth&tab=login")

element=driver.find_element_by_name("username").send_keys("email")
driver.find_element_by_name("password").send_keys("pass")
#link da url desejada

driver.find_element_by_xpath('/html/body/div[1]/main/div[3]/div/div[2]/div[2]/form/div[4]/button').click()
driver.find_element_by_xpath('/html/body/div[1]/main/div[1]/div[4]/div[2]/div[1]/div/div/div[4]/div[1]/div/div[3]/div/a')
</code>```

I have this code in python that opens in blazer.com and makes login but when i try to click o game mines which in this href:

```<code><a href="/pt/games/mines"/>
</code>```

and doesnt work justs stops , someone could help with this error

答:
You probably forgot to click the "mines" button. Don't forget the .click() at the end of your code, like this:

```<code>driver.find_element_by_xpath('/html/body/div[1]/main/div[1]/div[4]/div[2]/div[1]/div/div/div[4]/div[1]/div/div[3]/div/a').click()
</code>```

And you also might want to give the site some time to load by importing time and using time.sleep(x) which sleeps the code for x seconds.

```<code>import time

time.sleep(2) # Use this between the .click() lines to give the site time to load after clicking a button
</code>```

Body:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
#Service("local do diretorio do chromeDriver")

driver = webdriver.Firefox('/home/arch/Downloads/bot/')
driver.get("https://blaze.com/pt/?modal=auth&tab=login")

element=driver.find_element_by_name("username").send_keys("email")
driver.find_element_by_name("password").send_keys("pass")
#link da url desejada

driver.find_element_by_xpath('/html/body/div[1]/main/div[3]/div/div[2]/div[2]/form/div[4]/button').click()
driver.find_element_by_xpath('/html/body/div[1]/main/div[1]/div[4]/div[2]/div[1]/div/div/div[4]/div[1]/div/div[3]/div/a')

I have this code in python that opens in blazer.com and makes login but when i try to click o game mines which in this href:

and doesnt work justs stops , someone could help with this error

Body:
You probably forgot to click the "mines" button. Don't forget the .click() at the end of your code, like this:

driver.find_element_by_xpath('/html/body/div[1]/main/div[1]/div[4]/div[2]/div[1]/div/div/div[4]/div[1]/div/div[3]/div/a').click()

And you also might want to give the site some time to load by importing time and using time.sleep(x) which sleeps the code for x seconds.

import time

time.sleep(2) # Use this between the .click() lines to give the site time to load after clicking a button


问:
In Ruby, can you decide from a main method to return or continue when calling a submethod?
I'm using Pundit gem for my authorization classes, where each controller action is checked against the model policy, to see if action is allowed by the user.

These methods are sometimes becoming quite bloated and unreadable, because I'm checking quite some stuff for some objects.

Now I'm thinking to refactor those methods, and place every "validation" in it's own method:

Previous:

```<code>class PostPolicy < ApplicationPolicy

 def update
   return true if @user.has_role? :admin
   return true if @object.owner == user
   return true if 'some other reason'

   false
 end
end
</code>```

Now ideally, I want to refactor this in something like:

```<code>class PostPolicy < ApplicationPolicy

 def update
   allow_if_user_is_admin
   allow_if_user_owns_record
   allow_for_some_other_reason

   false
 end

 private

 def allow_if_user_is_admin
  # this would go in the parent class, as the logic is the same for other objects
  return true if @user.has_role? :admin
 end
end
</code>```

The problem now is, that the mane update method will keep on going, even if the user is admin, as there's no return. If I would inlcude a return, then the other methods will never be evalutaed. Is there a way in ruby to do kind of a "superreturn", so that when the user is an admin, the main update method would stop evaluting?

Thanks!

答:
It seems that this would achieve your aim and be more idiomatic:</p>
```<code>class PostPolicy < ApplicationPolicy

  def update
    user_has_admin_role? ||
      user_owns_object? ||
      some_other_reason?
  end

  private

  def user_has_admin_role?
    @user.has_role? :admin
  end

  def user_owns_object?
    @object.owner == user
  end

  def some_other_reason?
    'some other reason'
  end
end
</code>```

Body:
I'm using Pundit gem for my authorization classes, where each controller action is checked against the model policy, to see if action is allowed by the user.

These methods are sometimes becoming quite bloated and unreadable, because I'm checking quite some stuff for some objects.

Now I'm thinking to refactor those methods, and place every "validation" in it's own method:

Previous:

class PostPolicy < ApplicationPolicy

 def update
   return true if @user.has_role? :admin
   return true if @object.owner == user
   return true if 'some other reason'

   false
 end
end

Now ideally, I want to refactor this in something like:

class PostPolicy < ApplicationPolicy

 def update
   allow_if_user_is_admin
   allow_if_user_owns_record
   allow_for_some_other_reason

   false
 end

 private

 def allow_if_user_is_admin
  # this would go in the parent class, as the logic is the same for other objects
  return true if @user.has_role? :admin
 end
end

The problem now is, that the mane update method will keep on going, even if the user is admin, as there's no return. If I would inlcude a return, then the other methods will never be evalutaed. Is there a way in ruby to do kind of a "superreturn", so that when the user is an admin, the main update method would stop evaluting?

Thanks!

Body:
It seems that this would achieve your aim and be more idiomatic:

class PostPolicy < ApplicationPolicy

  def update
    user_has_admin_role? ||
      user_owns_object? ||
      some_other_reason?
  end

  private

  def user_has_admin_role?
    @user.has_role? :admin
  end

  def user_owns_object?
    @object.owner == user
  end

  def some_other_reason?
    'some other reason'
  end
end


问:
ReferenceError: ResizeObserver is not defined with nivo and NextJS
I want to use nivo with Next but when I load the page containing a pie chart made with nivo, I get this error: ReferenceError: ResizeObserver is not defined.

My Pie.js component:

import { ResponsivePie } from "@nivo/pie";

export const data = [
  {
    id: "c",
    label: "c",
    value: 80,
    color: "hsl(8, 70%, 50%)",
  },
  {
    id: "lisp",
    label: "lisp",
    value: 188,
    color: "hsl(122, 70%, 50%)",
  },

  {
    id: "go",
    label: "go",
    value: 161,
    color: "hsl(111, 70%, 50%)",
  },
];

export default function MyPie({ data }) {

    return (
        <ResponsivePie
            data={data}
            margin={{ top: 40, right: 80, bottom: 80, left: 80 }}
            innerRadius={0.5}
            padAngle={0.7}
            cornerRadius={3}
            activeOuterRadiusOffset={8}
            borderWidth={1}
            borderColor={{ from: "color", modifiers: [["darker", 0.2]] }}
            arcLinkLabelsSkipAngle={10}
            arcLinkLabelsTextColor="#333333"
            arcLinkLabelsThickness={2}
            arcLinkLabelsColor={{ from: "color" }}
            arcLabelsSkipAngle={10}
            arcLabelsTextColor={{ from: "color", modifiers: [["darker", 2]] }}
            defs={[
            {
                id: "dots",
                type: "patternDots",
                background: "inherit",
                color: "rgba(255, 255, 255, 0.3)",
                size: 4,
                padding: 1,
                stagger: true,
            },
            {
                id: "lines",
                type: "patternLines",
                background: "inherit",
                color: "rgba(255, 255, 255, 0.3)",
                rotation: -45,
                lineWidth: 6,
                spacing: 10,
            },
            ]}
        />
    )
};
```
<p>My <code>chart.js</code> page:</p>
<pre class="lang-js prettyprint-override"><code>import MyPie, { data } from "../components/Pie";

import homeStyles from "../styles/Home.module.css";

function Chart() {
  return (
    <div className={homeStyles.divchart}>
      <MyPie data={data}/>
    </div>
  );
};
export default Chart;
</code>```

This error only appears when using ResponsivePie and not Pie. I also tried to make it work with a React project but though I don't get this error, Nothing seems to be displayed.

Edit:

After some investigations, it looks like there is something wrong with @nivo/core 0.79.0 dependency. We should open an issue on the GitHub repo. I made some changes to check whether it is caused by my version of Next.js but the bug occurs only with @nivo/core 0.79.0.

答:
It's likely that code is being run on server side (SSR), and ResizeObserver doesn't exist there. You should try to make sure that your code only executes when on client side.

It's hard for me to tell you how as I don't know what your setup is. You can likely just add a check to only run that part of the code if ResizeObserver is defined.

I hope at least this points you in the right direction.

Body:
I want to use nivo with Next but when I load the page containing a pie chart made with nivo, I get this error: ReferenceError: ResizeObserver is not defined.

My Pie.js component:

import { ResponsivePie } from "@nivo/pie";

export const data = [
  {
    id: "c",
    label: "c",
    value: 80,
    color: "hsl(8, 70%, 50%)",
  },
  {
    id: "lisp",
    label: "lisp",
    value: 188,
    color: "hsl(122, 70%, 50%)",
  },

  {
    id: "go",
    label: "go",
    value: 161,
    color: "hsl(111, 70%, 50%)",
  },
];

export default function MyPie({ data }) {

    return (
        <ResponsivePie
            data={data}
            margin={{ top: 40, right: 80, bottom: 80, left: 80 }}
            innerRadius={0.5}
            padAngle={0.7}
            cornerRadius={3}
            activeOuterRadiusOffset={8}
            borderWidth={1}
            borderColor={{ from: "color", modifiers: [["darker", 0.2]] }}
            arcLinkLabelsSkipAngle={10}
            arcLinkLabelsTextColor="#333333"
            arcLinkLabelsThickness={2}
            arcLinkLabelsColor={{ from: "color" }}
            arcLabelsSkipAngle={10}
            arcLabelsTextColor={{ from: "color", modifiers: [["darker", 2]] }}
            defs={[
            {
                id: "dots",
                type: "patternDots",
                background: "inherit",
                color: "rgba(255, 255, 255, 0.3)",
                size: 4,
                padding: 1,
                stagger: true,
            },
            {
                id: "lines",
                type: "patternLines",
                background: "inherit",
                color: "rgba(255, 255, 255, 0.3)",
                rotation: -45,
                lineWidth: 6,
                spacing: 10,
            },
            ]}
        />
    )
};

My chart.js page:

import MyPie, { data } from "../components/Pie";

import homeStyles from "../styles/Home.module.css";

function Chart() {
  return (

      <MyPie data={data}/>

  );
};
export default Chart;

This error only appears when using ResponsivePie and not Pie. I also tried to make it work with a React project but though I don't get this error, Nothing seems to be displayed.

Edit:

After some investigations, it looks like there is something wrong with @nivo/core 0.79.0 dependency. We should open an issue on the GitHub repo. I made some changes to check whether it is caused by my version of Next.js but the bug occurs only with @nivo/core 0.79.0.


问:
How to understand the computed width of the block containing `white-space: pre;` with/without `float`?
As you can see the code below, div is the outermost scrolling container and the core in this topic section is a containing block with spans set as white-space: pre;.

One section is extremely simple and is just a block. The other .floated is set float: left;.

But the computed width of them is different: the former is just as wide as its containing block div i.e. 100px in this case, in contrast to the latter is as wide as its contents, around 1287.47px(given by Firefox). To make this difference more observable, I set a background color for both of them.

So the question comes:

My understanding is that the width of a block with width: auto; depends on its contents. Why is the first section not?

The expected effect is achieved by using float: left;, as .floated shows, but why and how does it work? What exactly does the float do? A new BFC? But if I change float to display: flow-root; which also creates a new BFC, it still doesn't work.

Thanks in advance for your help!

div {
  border: 1px solid red;
  width: 100px;
  overflow: auto;
}

section {
  background-color: teal;
}

span {
  white-space: pre;
}

.floated {
  float: left;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code> <div>
    <section>
      <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.</span>
      <span>Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!</span>
      <span>Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!</span>
      <span>Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.</span>
      <span>Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.</span>
    </section>
  </div>

  <div>
    <section class="floated">
      <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.</span>
      <span>Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!</span>
      <span>Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!</span>
      <span>Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.</span>
      <span>Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.</span>
    </section>
  </div></code>```

Online Demo

答:
My understanding is that the width of a block with width: auto; depends on its contents.

It doesn't. The width of a block level element should respect this formula:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

As you can see, the content play no role in defining the width of your element and it will end with a width equal to its containing block (parent element). That's why you have the logical result of 100px. After defining the width, the content should try to fit that width but you have disabled line breaks with white-space: pre so all you will get is an overflow.

When, you make the div floated you need to consider another part of the Specification that describe the width of floating elements and you can read:

If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.

Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).

The content is considered in the "shrink-to-fit" algorithm.

In your case, since you are using white-space: pre you are not allowing any  line break so the "preferred minimum width" will be the winner and you will end have a width equal to the longest sentence

If you disable the white-space, you will force line breaks and your content will try to fit the "available space" and both cases will give the same result even if we have different algorithm involved

div {
  border: 1px solid red;
  width: 100px;
  overflow: auto;
}

section {
  background-color: teal;
}

.floated {
  float: left;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>
    <section>
      <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.</span>
      <span>Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!</span>
      <span>Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!</span>
      <span>Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.</span>
      <span>Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.</span>
    </section>
  </div>

  <div>
    <section class="floated">
      <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.</span>
      <span>Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!</span>
      <span>Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!</span>
      <span>Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.</span>
      <span>Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.</span>
    </section>
  </div></code>```

Body:
As you can see the code below, div is the outermost scrolling container and the core in this topic section is a containing block with spans set as white-space: pre;.

One section is extremely simple and is just a block. The other .floated is set float: left;.

But the computed width of them is different: the former is just as wide as its containing block div i.e. 100px in this case, in contrast to the latter is as wide as its contents, around 1287.47px(given by Firefox). To make this difference more observable, I set a background color for both of them.

So the question comes:

My understanding is that the width of a block with width: auto; depends on its contents. Why is the first section not?

The expected effect is achieved by using float: left;, as .floated shows, but why and how does it work? What exactly does the float do? A new BFC? But if I change float to display: flow-root; which also creates a new BFC, it still doesn't work.

Thanks in advance for your help!

div {
  border: 1px solid red;
  width: 100px;
  overflow: auto;
}

section {
  background-color: teal;
}

span {
  white-space: pre;
}

.floated {
  float: left;
}

      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.
      Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!
      Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!
      Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.
      Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.

      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.
      Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!
      Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!
      Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.
      Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.

Online Demo

Body:
My understanding is that the width of a block with width: auto; depends on its contents.

It doesn't. The width of a block level element should respect this formula:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

As you can see, the content play no role in defining the width of your element and it will end with a width equal to its containing block (parent element). That's why you have the logical result of 100px. After defining the width, the content should try to fit that width but you have disabled line breaks with white-space: pre so all you will get is an overflow.

When, you make the div floated you need to consider another part of the Specification that describe the width of floating elements and you can read:

If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.

Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).

The content is considered in the "shrink-to-fit" algorithm.

In your case, since you are using white-space: pre you are not allowing any  line break so the "preferred minimum width" will be the winner and you will end have a width equal to the longest sentence

If you disable the white-space, you will force line breaks and your content will try to fit the "available space" and both cases will give the same result even if we have different algorithm involved

div {
  border: 1px solid red;
  width: 100px;
  overflow: auto;
}

section {
  background-color: teal;
}

.floated {
  float: left;
}

<div>
    <section>
      <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.</span>
      <span>Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!</span>
      <span>Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!</span>
      <span>Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.</span>
      <span>Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.</span>
    </section>
  </div>

  <div>
    <section class="floated">
      <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis quis earum totam sequi, optio iusto neque sed! Reiciendis fugit, dolor.</span>
      <span>Molestias consequuntur ipsam quod eligendi, temporibus a quos accusamus aliquid molestiae est blanditiis voluptatibus minus ipsum nisi odio tempora sed!</span>
      <span>Suscipit, similique. Dolor possimus non doloribus voluptatibus necessitatibus, quas, consequatur hic provident quo neque sequi? Nesciunt, ratione laudantium rem quis!</span>
      <span>Voluptate delectus, quis laboriosam animi esse, et perspiciatis, cupiditate, porro itaque officiis laudantium quidem. Quos culpa facilis, nesciunt itaque officiis.</span>
      <span>Expedita ex error a explicabo deserunt, consectetur illum quod veritatis. Odio pariatur quae minima quasi, minus itaque architecto illo delectus.</span>
    </section>
  </div>


问:
How to make ActionView use the color of the MenuItem
I have added a TextView as an ActionView to the menu items of my NavigationView. I use this TextView to show how many unread elements there are. I followed this article for the implementation: https://medium.com/android-news/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9

Now I want to make sure the text color of this ActionView always matches the tint of the MenuItem it is attached to.

I have currently implemented it like this:

```<code>        navController.addOnDestinationChangedListener { _, destination, _ ->
            updateBadgesTextColor(destination)
        }

// some other code

    private fun updateBadgesTextColor(currentDestination: NavDestination) {
        val menu = binding.mainNavView.menu
        val currentMenuGraph = getMenuParentGraph(currentDestination, menu)

        val defaultColor = ContextCompat.getColor(this, R.color.drawer_layout_default_tint_color)
        val selectedColor = ContextCompat.getColor(this, R.color.drawer_layout_selected_tint_color)

        menu.forEach { menuItem ->
            (menuItem.actionView as? TextView)?.setTextColor(
                if (menuItem.itemId == currentMenuGraph?.id) {
                    selectedColor
                } else {
                    defaultColor
                }
            )
        }
    }

    private fun getMenuParentGraph(destination: NavDestination, menu: Menu): NavGraph? {
        var currentGraph: NavGraph? = destination.parent

        while (currentGraph != null && menu.findItem(currentGraph.id) == null) {
            /*
            note: In my app the menu item and the navGraph that are linked always have the same id.
            In an app where this isn't the case, this function won't work correctly.
            */
            currentGraph = currentGraph.parent
        }

        return currentGraph
    }
</code>```

While this does do what I want it to do, it isn't at all efficient because it iterates through the entire list of MenuItems every single time the NavDestination changes, even when the NavDestination change doesn't result in a change of selected MenuItem.

Is there a more efficient way to solve this?

答:
You can track the previous selected destination Id and reset it for a new call to addOnDestinationChangedListener callback.

Normally in navigation components, the destination ids should be the same as thoses correspond to the navView menu Ids.

```<code>var previousId = -1

navController.addOnDestinationChangedListener { _, destination, _ ->

        if (previousId != -1) {
            val previous = binding.mainNavView.menu.findItem(previousId).actionView as TextView?
            previous?.setTextColor(ResourcesCompat.getColor(resources, R.color.drawer_layout_default_tint_color, null))
        }

        val current = binding.mainNavView.menu.findItem(destination.id).actionView as TextView?
        current.setTextColor(ResourcesCompat.getColor(resources, R.color.drawer_layout_selected_tint_color, null))
}
</code>```

Make sure to handle saving the previousId permanently to avoid losing it in configuration changes.

Body:
I have added a TextView as an ActionView to the menu items of my NavigationView. I use this TextView to show how many unread elements there are. I followed this article for the implementation: https://medium.com/android-news/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9

Now I want to make sure the text color of this ActionView always matches the tint of the MenuItem it is attached to.

I have currently implemented it like this:

        navController.addOnDestinationChangedListener { _, destination, _ ->
            updateBadgesTextColor(destination)
        }

// some other code

    private fun updateBadgesTextColor(currentDestination: NavDestination) {
        val menu = binding.mainNavView.menu
        val currentMenuGraph = getMenuParentGraph(currentDestination, menu)

        val defaultColor = ContextCompat.getColor(this, R.color.drawer_layout_default_tint_color)
        val selectedColor = ContextCompat.getColor(this, R.color.drawer_layout_selected_tint_color)

        menu.forEach { menuItem ->
            (menuItem.actionView as? TextView)?.setTextColor(
                if (menuItem.itemId == currentMenuGraph?.id) {
                    selectedColor
                } else {
                    defaultColor
                }
            )
        }
    }

    private fun getMenuParentGraph(destination: NavDestination, menu: Menu): NavGraph? {
        var currentGraph: NavGraph? = destination.parent

        while (currentGraph != null && menu.findItem(currentGraph.id) == null) {
            /*
            note: In my app the menu item and the navGraph that are linked always have the same id.
            In an app where this isn't the case, this function won't work correctly.
            */
            currentGraph = currentGraph.parent
        }

        return currentGraph
    }

While this does do what I want it to do, it isn't at all efficient because it iterates through the entire list of MenuItems every single time the NavDestination changes, even when the NavDestination change doesn't result in a change of selected MenuItem.

Is there a more efficient way to solve this?

Body:
You can track the previous selected destination Id and reset it for a new call to addOnDestinationChangedListener callback.

Normally in navigation components, the destination ids should be the same as thoses correspond to the navView menu Ids.

var previousId = -1

navController.addOnDestinationChangedListener { _, destination, _ ->

        if (previousId != -1) {
            val previous = binding.mainNavView.menu.findItem(previousId).actionView as TextView?
            previous?.setTextColor(ResourcesCompat.getColor(resources, R.color.drawer_layout_default_tint_color, null))
        }

        val current = binding.mainNavView.menu.findItem(destination.id).actionView as TextView?
        current.setTextColor(ResourcesCompat.getColor(resources, R.color.drawer_layout_selected_tint_color, null))
}

Make sure to handle saving the previousId permanently to avoid losing it in configuration changes.


问:
Column style UISplitViewController not working properly when added to a Tab bar controller
I tried adding a split view controller with triple column style to a UITabBarController and it shows up in collapsed state. The same code works fine when I use the older style of the split view controller. How do I get the 3-column split view controller to show up correctly on a tab bar controller?

```<code>class TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

//        This works fine ♂
        let splitViewController = SplitViewController()
        splitViewController.viewControllers = [ UINavigationController(rootViewController: PrimaryViewController()) , UINavigationController(rootViewController: SecondaryViewController())]

//        let splitViewController = SplitViewController(style: .tripleColumn)
//        splitViewController.setViewController(UINavigationController(rootViewController: PrimaryViewController()), for: .primary)
//        splitViewController.setViewController(UINavigationController(rootViewController: SecondViewController()), for: .secondary)
//        splitViewController.setViewController(UINavigationController(rootViewController: SupplementaryViewController()), for: .supplementary)
//        splitViewController.show(.primary)
//        splitViewController.show(.secondary)
//        splitViewController.show(.supplementary)

        splitViewController.title = "First"

        let secondViewController = SecondViewController()
        secondViewController.title = "Second"

        setViewControllers([
            splitViewController,
            secondViewController
        ], animated: false)
    }
}
</code>```

here is the link to the project: https://github.com/anirudhbandi96/SplitViewTest

This is how the new three column split view controller looks

This is how the old 2-column split view controller looks

答:
I couldn't even get the 2 column one to work inside a UITabBarController. But, if I just make a new UIViewController, that adds as a childViewController a UISplitViewController, then everything works just fine.</p>
```<code>class MyViewController: UIViewController {

    let split = UISplitViewController(style: .doubleColumn)

    override func viewDidLoad() {
        super.viewDidLoad()
        addChild(split)
        view.addSubview(split.view)
        // add in your constraints to fix to same size here
        // -- here --
        split.didMove(toParent: self)
    }
}

</code>```

Body:
I tried adding a split view controller with triple column style to a UITabBarController and it shows up in collapsed state. The same code works fine when I use the older style of the split view controller. How do I get the 3-column split view controller to show up correctly on a tab bar controller?

class TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

//        This works fine ♂
        let splitViewController = SplitViewController()
        splitViewController.viewControllers = [ UINavigationController(rootViewController: PrimaryViewController()) , UINavigationController(rootViewController: SecondaryViewController())]

//        let splitViewController = SplitViewController(style: .tripleColumn)
//        splitViewController.setViewController(UINavigationController(rootViewController: PrimaryViewController()), for: .primary)
//        splitViewController.setViewController(UINavigationController(rootViewController: SecondViewController()), for: .secondary)
//        splitViewController.setViewController(UINavigationController(rootViewController: SupplementaryViewController()), for: .supplementary)
//        splitViewController.show(.primary)
//        splitViewController.show(.secondary)
//        splitViewController.show(.supplementary)

        splitViewController.title = "First"

        let secondViewController = SecondViewController()
        secondViewController.title = "Second"

        setViewControllers([
            splitViewController,
            secondViewController
        ], animated: false)
    }
}

here is the link to the project: https://github.com/anirudhbandi96/SplitViewTest

This is how the new three column split view controller looks

This is how the old 2-column split view controller looks

Body:
I couldn't even get the 2 column one to work inside a UITabBarController. But, if I just make a new UIViewController, that adds as a childViewController a UISplitViewController, then everything works just fine.

class MyViewController: UIViewController {

    let split = UISplitViewController(style: .doubleColumn)

    override func viewDidLoad() {
        super.viewDidLoad()
        addChild(split)
        view.addSubview(split.view)
        // add in your constraints to fix to same size here
        // -- here --
        split.didMove(toParent: self)
    }
}


问:
What are practical uses of applicative style?
I am a Scala programmer, learning Haskell now. It's easy to find practical use cases and real world examples for OO concepts, such as decorators, strategy pattern etc. Books and interwebs are filled with it.

I came to the realization that this somehow is not the case for functional concepts. Case in point: applicatives.

I am struggling to find practical use cases for applicatives. Almost all of the tutorials and books I have come across so far provide the examples of [] and Maybe. I expected applicatives to be more applicable than that, seeing all the attention they get in the FP community.

I think I understand the conceptual basis for applicatives (maybe I am wrong), and I have waited long for my moment of enlightenment. But it doesn't seem to be happening. Never while programming, have I had a moment when I would shout with a joy, "Eureka! I can use applicative here!" (except again, for [] and Maybe).

Can someone please guide me how applicatives can be used in a day-to-day programming? How do I start spotting the pattern? Thanks!

答:
Coming at Applicative from "Functor" it generalizes "fmap" to easily express acting on several arguments (liftA2) or a sequence of arguments (using <*>).

Coming at Applicative from "Monad" it does not let the computation depend on the value that is computed.  Specifically you cannot pattern match and branch on a returned value, typically all you can do is pass it to another constructor or function.

Thus I see Applicative as sandwiched in between Functor and Monad.  Recognizing when you are not branching on the values from a monadic computation is one way to see when to switch to Applicative.


问:
Xcode 7.2 no matching provisioning profiles found
Before upgrading Xcode to 7.2, I was using Xcode 7.1.1 to build and distribute apps. I have upgraded to Xcode 7.2 and none of my provisioning profiles (matched to that particular app's bundle ID) match my installed certificates that were working in Xcode 7.1.1.

I only get:

Your build settings specify a provisioning profile with the UUID “some_number”, however, no such provisioning profile was found.

I have tried regenerating a .certSigningRequest to generate a new Certificate and Profile and made sure the Team in the General tab of the target is correct. Whenever I select a Provision Profile, all of my Code Signing Identities appear in the Identities in Keychain, but none of them will pair correctly.

It seems setting the Provision Profile to Automatic and the Code Signing Identity to iOS Developer will resolve this error, but the advantage of managing my Provisioning Profiles is gone as I believe Xcode then manages these.

Any thoughts on why setting my Provisioning Profiles and Code Signing Identities to anything but Automatic and iOS Developer produces this error?

答:
After I have a few hours searching and trying I have two solutions
1- run the app using IOS real device.
2- turn off the automatically manage signing, go to https://developer.apple.com/account/resources/profiles/, and create a profile now on the Provisioning Profile import it and done.</p>