lt

Nearly $17 million invested in research to fast-track studies on health impacts of e-cigarettes and nicotine on youth




lt

Patient groups urge court to reject rule weakening health insurance standards

Washington, D.C.—March 20, 2020—Patient groups representing millions of people with serious health conditions are urging a U.S. Court of Appeals for the D.C. Circuit to reject a federal rule expanding the availability of short-term limited-duration...




lt

Leading Health Care Groups Issue Urgent Call for Federal Action to Address Medical Equipment Shortages

  WASHINGTON, D.C., March 30, 2020 — As longstanding organizations representing and supporting those on the front lines who are risking their lives caring for the world’s most vulnerable patients, we stand united in voicing our concern over the ...




lt

28 Patient and consumer groups urge the administration to implement a special enrollment period for Healthcare.gov

WASHINGTON, D.C., April 1, 2020 – 28 patient and consumer groups representing millions of people nationwide with pre-existing health conditions issued the following statement regarding the administration’s decision not to initiate a special enrollment...




lt

28 grupos de pacientes y consumidores instan a la administración a implementar un período de inscripción especial para Healthcare.gov

WASHINGTON, D.C., 1 de abril del 2020 – 28 grupos de pacientes y consumidores que representan a millones de personas en todo el país con afecciones de salud preexistentes emitieron la siguiente declaración sobre la decision de la administración de no...




lt

Public health CEOs: Open health care enrollment to save lives

AHA COVID-19 newsroom DALLAS, April 10, 2020 — Nancy Brown, CEO of the American Heart Association, the world’s leading voluntary organization focused on heart and brain health, joined the chief executives of other leading national public...




lt

21 health and medical groups speak out against EPA finalizing a rule that could undermine the Mercury and Air Toxics Standards

Today, the U.S. Environmental Protection Agency (EPA) announced a final rule that threatens to undermine the Mercury and Air Toxics Standards. The American Lung Association, Allergy & Asthma Network, Alliance of Nurses for Healthy Environments, American...




lt

Es menos probable que quienes comienzan a fumar en la infancia o adolescencia dejen el hábito cuando son adultos

Puntos destacados de la investigación: Mientras más joven comience a fumar, es más probable que fume diariamente cuando sea adulto y es menos probable que haya dejado el hábito a los 40 años, según un estudio internacional que incluye a EE. UU. Los ...




lt

Higher economic status does not always translate to better heart health

Research Highlights: Upward income mobility is associated with a trade-off between well-being and cardiometabolic health. Reaching a higher income status is not always beneficial for cardiometabolic health, even if it improves economic standing and...




lt

Las dos nuevas declaraciones de la AHA se centran en la insuficiencia cardíaca: cómo pueden afectar los determinantes sociales a los resultados clínicos, y el impacto en los cuidadores

Aspectos destacados de las declaraciones: Los factores sociales adversos, como el estado de los seguros, la inseguridad alimentaria, la falta de fondos para medicamentos y otros, pueden causar resultados clínicos negativos de la insuficiencia...




lt

COVID-19 has unmasked significant health disparities in the U.S.; essay on behalf of the Association of Black Cardiologists suggests solutions




lt

For older adults, more physical activity could mean longer, healthier lives




lt

Eating more plant protein and dairy instead of red meat may improve heart health




lt

Super Bowl multimedia

This is our multimedia site for Super Bowl XLV. It includes videos, panoramic images and a photo feed. It may not be up long in this form. The NFL has a time limit on how long we can post images of its official events.




lt

El nuevo registro de datos de pacientes con COVID-19 proporcionará perspectivas sobre la atención y los resultados cardiovasculares adversos

DALLAS, 3 de abril del 2020 – Debido al esfuerzo de médicos, científicos e investigadores de todo el mundo por comprender la pandemia del coronavirus (COVID-19), la American Heart Association está desarrollando un nuevo registro para agregar datos y...




lt

New oxygenation and ventilation management training for health care providers

DALLAS, April 3, 2020 — With the COVID-19 pandemic, more patients are having difficulty breathing and requiring ventilators to help them breathe. As hospital and intensive care unit (ICU) volumes increase with COVID-19 patients, health care ...




lt

Free, online health lessons available for all faith communities

DALLAS, April 8, 2020 – Approximately 120 million people in the United States have one or more cardiovascular conditions that may increase their risk for COVID-19 complications and those with hypertension, diabetes or cardiovascular disease are...




lt

12 scientific teams redefining fast-tracked heart and brain health research related to COVID-19




lt

Students receive scholarships to help address health disparities

DALLAS, May 5, 2020 — Ten college students are receiving $10,000 scholarships from the American Heart Association for their work to help close health disparity gaps – which appear to contribute to disproportionately high rates of sickness and death among...




lt

Alternatives to NOAH AMS (Association Management System)

Some might tell you the only way to manage your association is through a “one size fits all” Association Management System like NOAH. While these tools have their place, they are not the best solution in all situations. In this article, we’ll discuss benefits towards assembling a custom Association Management System using open source tools […]

The post Alternatives to NOAH AMS (Association Management System) appeared first on Psychology of Web Design | 3.7 Blog.




lt

5 Tips To Improve Your Geo-Targeted Local SEO Services For Multiple Locations

As we all know, SEO is a broad-spectrum umbrella term that is used to describe the measures taken to improve your website and help it to rank higher in search engine results for keywords and phrases related to your business. Local SEO is an effective way to optimize a business for the local audience while...




lt

The Ultimate Cold Email Outreach Guide

Email marketing is great for staying in touch with your existing customers and attracting new ones. Also, it’s a very effective method of selling your products. According to email marketing stats, 60% of consumers say they’ve made a purchase as the result of an email marketing message they received. There are certain types of emails...




lt

Health Problems Precede Traumatic Brain Injury in Older Adults

Traumatic brain injury (TBI) is a leading cause of death and disability. Older adults are more likely than younger individuals to sustain TBIs and less likely to survive them. TBI has been called the “silent epidemic,” and older adults are the “silent population” within this epidemic. This study evaluates whether indicators of preinjury health and functioning are associated with risk of incident traumatic brain injury (TBI) with loss of consciousness (LOC) and to evaluate health‐related factors associated with mortality in individuals with incident TBI.




lt

This Bakery Turns Internet Trolls’ Insults Into Delicious Cakes, And Sends Them Back To Trolls

The New York City-based company Troll Cakes touts itself as a bakery/detective agency that can not only bake a chocolate...




lt

Artist Makes Cardboard Cutouts With Pandemic Jokes To Lighten This Difficult Time

Gotcha! According to John Marshall: “I draw on sheets of cardboard and pose with them at sunset. I call them...




lt

Why universal basic health care is both a moral and economic imperative

Several hundred cars were parked outside a food bank in San Antonio on Good Friday — the food bank fed 10,000 people that day. Such scenes, increasingly common across the nation and evocative...




lt

Many anticipated arts, cultural events delayed or canceled

Summer is going to look a bit different in the Corridor this year as many, long-cherished events are being canceled or postponed. And the organizations that run those events want you to know they...




lt

Marion coronavirus recovery task force wants residents to come out of this healthy and to ‘a vibrant economy’

MARION — Marion’s 14-member COVID-19 Economic Recovery Task Force is beginning to work on recommendations of how to get people back to work, while keeping everyone...




lt

Campgrounds reopen in Iowa Friday, see takers despite some health limitations

Some Eastern Iowans are ready to go camping. With Gov. Kim Reynolds allowing campgrounds across the state to open Friday, some people wasted little time in heading outdoors. “They’re...




lt

Mary Jane Felton

MARY JANE FELTON
Cascade

Mary Jane Felton, 93, of Cascade, Iowa, passed away peacefully on Wednesday, May 6, 2020, at Shady Rest Care Center in Cascade, Iowa.
Because of the unprecedented conditions in our country right now because of the
COVID-19 virus, private family visitation will be held for Mary Jane on Saturday. Private family burial also will be held at Calvary Cemetery, with the Rev. Douglas Loecke presiding. A Celebration of Life for Mary Jane will be held at a later date to be announced.
Anyone interested in sending memorials may send them to the Reiff Funeral Home, Attention: Mary Jane Felton Family, P.O. 430, Cascade, IA 52033.
She was born Oct. 6, 1926, in Worthington, Iowa, daughter of Nicolas and Mary (Krogman) Lahr. She received her education in the rural Brooks Country School. On Jan. 16, 1947, she was united in marriage to Joseph C. Felton at the Immaculate Conception Church in Sand Springs, Iowa. He preceded her in death on July 16, 2001.
She was a member of St. Matthias Parish in Cascade. Mary Jane was a past president of the Cascade Legion Auxiliary from 1993-95.
She is survived by seven children, Patti Volk of Cascade, Don (Jenna Mae) Felton of Hopkinton, Dennis (Gladys) Felton of Dyersville, Sharon Spear (Ed Groth) of North Liberty, Lester (Susan) Felton of Monticello, Jean (Vic) Thier of Bernard and Jim (Sue) Felton of Cascade; 20 grandchildren; 46 great-grandchildren; one great-great-grandchild with another one arriving in November; one sister-in-law, Irene Dement of Dubuque; and one special nephew, Anthony Russ of Manchester.
She is preceded in death by her parents; her husband; one son, LeRoy Felton; one grandson, David Felton; one great-grandson, Ian Felton; son-in-law, Larry Volk; siblings, Veronica (Henry) Russ, Margaret (Tom) Oehler, Loretta Lahr, Rose (Wallace) Nehl, Joe (Isabelle) Lahr, Al (Germaine) Lahr, Nick (Mary Jane) Lahr, John Lahr, Theresa (Gerald) Goedken, Alvin Lahr and Clarence (Adele) Lahr; and brothers- and sisters-in-law, Mary (Willie) Duffy, Hilda (Bill) Macomber, Geraldine (Orville) Offerman, Jack (Mary) Felton, Nick (Irene) Felton, Ed (Mary) Felton, Margaret (Al) Demmer and Harold Dement.
Online condolences may be sent to the family at www.reifffuneralhomeinc.com.




lt

Fear: Focus on substance abuse, mental health and human trafficking

I am a longtime resident of Johnson County, currently in my 25th year of law enforcement. I worked for the Coralville Police Department in the late 1990’s and transferred to the Cedar Rapids Police Department in 1999 where I am a sergeant of the patrol division. I have degrees in criminal justice and organizational leadership and have advanced leadership training from Northwestern University in the School of Police Staff and Command.

Working in the second-largest city in the state has offered me many opportunities to lead. I have taught in the police academy and defensive tactics and as a field training instructor. I was the director of the Eastern Iowa Heroin Initiative, where I founded CRUSH of Iowa (Community Resources United to Stop Heroin). CRUSH is a community-based, grassroots organization helping all those affected by substance abuse disorder.

My passion has been community outreach. Currently I am a member of the Johnson County Human Trafficking Coalition and the Johnson County Prevention Partnership. Through these partnerships I will create a criminal interdiction team to fight the trafficking of humans, weapons and narcotics.

As sheriff, my top three concerns are substance abuse, mental health and human trafficking. I believe in creating long-lasting relationships with the community. I believe in common sense solutions without the haze of political bias. I believe that every citizen has a voice and should be heard. I believe in building a proactive and progressive law enforcement agency that serves with professionalism, compassion and dedication to the citizens. I believe we need to place the community back into community policing.

I am ready to be sheriff of Johnson County. I am a proven leader who is determined to build bridges with the citizens of the county and lead with accountability, trust and transparency. I will fight for all of Johnson County as sheriff because I have done so all of my life. This election is not just about me, it is about us. We, together, will make a positive impact on Johnson County. The status quo is not working. It’s time for change!

I would love to have your vote on June 2. We work better when we work together. People before politics!

Al Fear is a candidate in the Democratic primary for Johnson County sheriff. alfearforsheriff.com




lt

Iowa’s health care system is not overwhelmed. Why is our economy still closed?

In response to the coronavirus, Americans were told by their federal and state governments to shut down their businesses, stop going to church, work, school or out to eat, travel only when necessary and hunker down at home. Originally, Americans were led to believe this was for a two- or three-week period, in order to flatten the curve and not overwhelm our health care system.

At seven weeks and counting, with staggering economic loss that will leave families and thousands of small businesses and farmers with profound devastation, the question must be asked, are we trying to flatten the curve or flatten our country?

The initial models that pointed to staggering loss of life from the coronavirus have proved wildly inaccurate. As of May 2, the CDC placed the number of deaths in the U.S. from the virus at 66,746. While all loss of life is deeply regrettable, these numbers cannot be considered in a vacuum. For perspective, deaths from pneumonia in the U.S. during the same period were 64,382, with average yearly deaths from influenza in the same range.

The original goal of closing much of the U.S. economy and staying at home was to flatten the curve of new coronavirus cases so that our hospital systems would not be overwhelmed. Hospitals built by the Army Corps of Engineers to handle the increased volume have mostly been taken down. Except for a few spots in the U.S. the health care system was not overwhelmed. As the medical models of casualties from the coronavirus continue to be adjusted down, it is clear the curve has been flattened, so why do we continue to stay closed and worsen the economic devastation that tunnel vision has thus far kept many of our leaders from acknowledging?

Many health experts say 80 percent of Americans will get the coronavirus and experience only mild symptoms. The curve has been flattened. Our health care system is not overwhelmed. Why is our economy, for the most part, still closed?

A University of Washington study recently revised the projected number of deaths from the coronavirus in Iowa from 1,367 to a much lower estimate of 365. While all loss of life is horrific, we must also consider the devastation being done to our economy, our families and our way of life by actions taken to combat the coronavirus.

It must be noted that 578 Iowans died from the flu and pneumonia in 2017, a greater number than are likely to pass away from the coronavirus. We also know that many who die from the virus are elderly with underlying health conditions, increasing the likelihood that any serious illness could result in their death. Are draconian government restrictions in response to the coronavirus still needed and economically sustainable? The data shows that the answers to both questions is no. We are no longer flattening the curve; we are flattening our state and nation.

We have seen the medical data. What has been less visible in news conferences and in the overall reporting of the coronavirus and our response to it, are the economic and human costs of what we are doing:

• 30 million Americans are out of work and the number grows daily.

• Dairy farmers are pouring out milk they have no market for.

• Pork producers are euthanizing hogs they have no market for.

• According to a study by Iowa State University, the losses to Iowa Agriculture are at a staggering $6.7 billion and growing, with the largest losses in pork production and ethanol.

• In Iowa, the economic loss for corn is estimated to be $788 million, $213 million for soybean and $34 million for cattle.

• The Iowa Restaurant Association estimates that between 10 & 25% of Iowa’s restaurants will not reopen.

• Iowa’s public universities are predicting a $187 million loss.

• Iowa is spending $200 million or more per month on unemployment claims, with over 171,000 Iowans unemployed.

• 29 percent of the U.S. economy is frozen as a result of government action, with U.S. economic output down 29 percent.

• U.S. unemployment could soon hit 47 million.

• Losses to U.S. tourism are predicted to top $910 billion.

• Retirement plans for millions of Americans are being decimated, with recent reports projecting the average 401(k) loss at 19 percent.

• Drug and alcohol addiction and relapse are increasing.

• Testing for chronic diseases such as high blood pressure, diabetes and heart disease are being delayed, which could lead to increasing health problems and life-threatening illnesses in the future.

• Economic damage to rural hospitals could lead to hospital closures and less access to health care in some areas.

• Warnings of a possible meat shortage in the U.S. have been issued by executives of Farmland and Tyson, with reports that the food supply chain is under stress. Several grocery store chains are now limiting meat purchases and some national restaurant chains are no longer offering certain meat products on their menus. Higher meat prices are almost certain in the months to come.

• Huge U.S. debt increases unlike anything seen since World War II, to the tune of over $3 trillion and counting, are adding to the already monstrous $22 trillion in U.S. debt. This does not bode well for our children or future economic stability.

The list of consequences goes on and on, and behind each of the statistics is a family struggling to survive, a father and mother fearful of how they will care for their children, a small-business owner seeing their dreams and hard work destroyed overnight by draconian government mandates, a restaurant owner deciding never to reopen, a dairy farmer throwing in the towel and a business owner postponing indefinitely plans for expanding.

Behind these numbers is an economy greatly impacted by the government response to the coronavirus, with implications for our economic well-being profound and long lasting. Expansion projects delayed, business closures, layoffs and contraction for many businesses will likely keep unemployment numbers high and depress economic expansion for an unknown amount of time.

Let us be clear, it grows worse every day we remain closed.

Steve Holt represents District 18 in the Iowa House.




lt

Graham: Health care is a human right

Canusa Street in Vermont is the border between the United States and Canada. Roughly 200 years ago, when the border was decided, no one could have imagined that breaking your leg on one side of that street would have vastly different consequences than breaking it on the other.

I’m Kimberly Graham. I’m an advocate and attorney for abused kids and for parents in Iowa’s juvenile courts. I’m also a Democratic candidate for U.S. Senate in Iowa.

On one side of Canusa Street, that nation has a universal single-payer health insurance system. For 20 years, I’ve been friends with an international circle of moms who met in an online mommies group when our kids were infants. Some of us have had medical events requiring expensive care.

To this day, my Canadian (and Australian and British) friends are shocked when we American moms talk about $5,000 or $10,000 deductibles, plus astronomical premiums. We talk about medical debt and how we put off or avoid medical care. We talk about how our child’s broken leg and the resulting deductible has set us behind financially and will take years to pay off.

A poll commissioned in 2018 by West Health Institute and the University of Chicago showed that 40 percent of Americans are more frightened by the cost of health care than getting sick.

Are Canadians, Brits and Australians more deserving of health care without premiums, copays and deductibles than Americans?

Of course not.

In a moral and wealthy nation, health care should be a fundamental human right.

Human rights are not for sale.

Human rights are not commodities to be marketed, bought and sold.

We need a universal, single-payer health care system (Medicare for All) that covers everyone. It should work like a public library. We value libraries and all of us can use them. But libraries aren’t free, so we all pitch in and pay for them. When I want a book, I go to the library, hand them my library card, check out the book and never hand them a debit card or receive a bill in the mail.

Health care should work like that in a moral and wealthy nation. Please join me in working for the day when all of us truly have the health insurance system we deserve. You can learn more at www.kimberlyforiowa.com Onward to justice for all, Kimberly

Kimberly Graham is a candidate in the Democratic primary for U.S. Senate.




lt

Lensing: Leadership on education funding, mental health and accessible voting

Serving as state representative of House District 85 for the past few years has been a privilege and an honor. I have worked hard to stand for the people of my district fighting for issues that are important to them and to the voters of Iowa City. I want to continue that advocacy and am running for another term in the Iowa House and ask for your vote.

I vigorously support adequate funding for education from pre-school to our community colleges and universities. Our young people are Iowa’s future and deserve the best start available through our excellent education system in Iowa. But we need to provide the dollars necessary to keep our teachers in the classroom so our children are prepared for whatever may lie ahead of them.

I have advocated for the fair treatment of workers in Iowa and support their right to organize. I have worked on laws for equal pay for equal work and whistle blower protection.

I am for essential funding for mental health services for Iowans of all ages. Children and adults who are struggling with mental health issues should have services available to them no matter where they live in this state.

I have fought to keep government open and accessible to Iowans. I support open records and open meetings laws to ensure that availability and transparency to all Iowans.

Keeping voting easy and accessible to voters has been a priority of mine. I support a fair and balanced redistricting system for voting in Iowa.

I have advocated to keep the bottle deposit law in place and expand it to cover the many new types of containers available.

I have worked on oversight legislation after several investigations into defrauding government which involved boarding homes, government agencies and pharmacy benefit managers (the “middleman” between pharmacies/Medicaid and the healthcare insurance companies.)

I cannot avoid mentioning the challenge of the coronavirus in Iowa. It has impacted our health, jobs, families and businesses. No one could have predicted this pandemic but as Iowans, we need to do our best to limit contact and the spread of this disease. My sincere appreciation goes to those workers on the frontlines of this crisis: the healthcare workers, store owners, businesses, farmers, teachers and workers who show up every day to keep this state moving forward. Thank you all!

There is still much work to be done to keep Iowa the great place where we live, work and raise our families. I am asking for your vote to allow me the privilege of continuing that work.

Vicki Lensing is a candidate in the Democratic primary for Iowa House District 85.




lt

Why universal basic health care is both a moral and economic imperative

Several hundred cars were parked outside a food bank in San Antonio on Good Friday — the food bank fed 10,000 people that day. Such scenes, increasingly common across the nation and evocative of loaves and fish, reflect the cruel facts about the wealthiest nation in the world: 80 percent of Americans live paycheck to paycheck, and 100 percent of Americans were unprepared for the COVID-19 pandemic. People are hungry due to macroeconomic and environmental factors, not because they did something wrong. Although everyone is at risk in this pandemic, the risk is not shared equally across socioeconomic classes. Universal basic health care could resolve this disparity and many of the moral and economic aspects associated with the pandemic.

Increases in the total output of the economy, or the gross domestic product (GDP), disproportionately benefit the wealthy. From 1980 to 2020, the GDP increased by 79 percent. Over that same time, the after-tax income of the top 0.01 percent of earners increased by 420 percent, while the after-tax income of the middle 40 percent of earners increased by only 50 percent, and by a measly 20 percent for the bottom 50 percent of earners. At present, the top 0.1 percent of earners have the same total net worth as the bottom 85 percent. Such income inequality produces poverty, which is much more common in the U.S. than in other developed countries. Currently 43 million Americans, or 12.7 percent of the population, live in poverty.

At the same time, 30 million Americans are uninsured and many more are underinsured with poorly designed insurance plans. The estimated total of uninsured and underinsured Americans exceeds 80 million. In addition, most of the 600,000 homeless people and 11 million immigrants in the U.S. lack health care coverage. Immigrants represent an especially vulnerable population, since many do not speak English and cannot report hazardous or unsafe work conditions. Furthermore, many immigrants avoid care due to fear of deportation even if they entered the country through legal channels.

Most people in poverty and many in the middle class obtain coverage from federal programs. On a national level, Medicaid is effectively a middle-class program and covers those living in poverty, 30 percent of adults and 60 percent of children with disabilities as well as about 67 percent of people in nursing homes. In Iowa, 37 percent of children and 48 percent of nursing home residents use Medicaid. Medicaid also finances up to 20 percent of the care provided in rural hospitals. Medicare, Medicaid and the Children’s Hospital Insurance Program (CHIP) together cover over 40 percent of Americans.

In addition to facilitating care, health care policy must also address the “social determinants of health,” since the conditions in which people live, work, and play dictate up to 80 percent of their health risks and outcomes. This means that health care reform requires programs in all facets of society. Winston Churchill first conceptualized such an idea in the early 20th century as a tool to prevent the expansion of socialism, arguing that inequality could persist indefinitely without social safety nets. Since that time most developed countries have implemented such social programs, but not the US.

All developed countries except the U.S. provide some type of universal basic health care for their residents. Universal basic health care refers to a system that provides all people with certain essential benefits, such as emergency services (including maternity), inpatient hospital and physician care, outpatient services, laboratory and radiology services, treatment of mental illness and substance abuse, preventive health services (including vaccinations), rehabilitation, and medications. Providing access to these benefits, along with primary care, dramatically improves the health of the community without imposing concerns regarding payment. Perhaps not coincidentally, the U.S. reports a lower life expectancy and higher rates of infant mortality, suicide and homicide compared to other developed countries.

Countries such as Canada, Great Britain, Denmark, Germany, Switzerland, Australia, and Japan all produce better health care outcomes than the U.S. at a much lower cost. In fact the U.S. spends about twice the percentage of its GDP on health care compared to these countries. With that being said, the Affordable Care Act of 2010 (ACA), which facilitated a decrease in the rate of the uninsured in the U.S. from 20 percent to 12 percent, also decreased the percentage of the GDP spent on health care from 20.2 percent to 17.9 percent in just 10 years. For this reason, most economists agree that universal basic health care would not cost more than the current system, and many would also argue that the total costs of the health care system cannot be further reduced unless everyone has access to basic care.

Achieving successful universal basic health care requires a serious long-term commitment from the federal government — contributing to Medicaid and financing its expansion are not enough. It requires courage from our elected leaders. The ACA took several important steps toward this goal by guaranteeing coverage for preexisting conditions, banishing lifetime maximums for essential services, and mandating individual coverage for everyone, though Congress repealed this final provision in 2017. At present, the ACA requires refinement and a public option, thereby preserving private and employer-based plans for those who want them.

Without universal basic health care the people living at the margins of society have no assurances that they will have access to basic health care services, especially during times of pandemic. Access to food and medications is less reliable, large families live together in small spaces, and public transportation facilitates frequent exposure to others. Childhood diseases such as asthma, chronic diseases such as diabetes, and diseases related to smoking such as COPD and cancer are all likely to worsen. Quarantine protocols also exacerbate the mental health crisis, further increasing rates of domestic violence, child abuse, substance abuse, depression, and suicide. In the last six weeks over 30 million Americans have applied for unemployment benefits, and as people become unemployed, many will lose health insurance.

Access to basic health care without economic or legal consequences would greatly enhance all aspects of pandemic management and response, from tracing contacts and quarantining carriers to administering tests and reinforcing supply chains. The COVID-19 pandemic has disproportionately affected minorities and the impoverished in both mortality and livelihood. Universal basic health care helps these vulnerable populations the most, and by reducing their risk it reduces the risk for everyone. In this way, universal basic health care supports the best interests of all Americans.

Like a living wage, universal basic health care aligns with the Christian tradition of social justice and is a moral and economic imperative for all Americans. Nurses, doctors, and other health care providers often observe a sharp contrast between the haves and have-nots when seeing patients. The homeless, the hungry, the unemployed, the working poor, the uninsured; people without families, patients with no visitors, those who live alone or lack support systems; refugees and immigrants — all of these people deserve the fairness and dignity provided by universal basic health care and programs which improve the social determinants of their health. The ACA moved U.S. toward this goal, but now it requires refinement and a public option. The COVID-19 pandemic highlights the urgency of this imperative by demonstrating how universal basic health care could decrease the risks to those less fortunate, thus significantly decreasing the risks to everyone.

James M. Levett, MD, serves on the board of Linn County Public Health and is a practicing cardiothoracic surgeon with Physicians’ Clinic of Iowa. Pramod Dwivedi, MS, DrPH (c), is the health director of Linn County Public Health.




lt

How to Use apply_filters() and do_action() to Create Extensible WordPress Plugins

How does a single plugin become the basis of a thriving technology ecosystem? Partly by leveraging the extensibilitythat WordPress’s event-driven Hooks system makes possible.




lt

WordPress Multisite Masterclass: Getting Started

Multisite is a powerful tool that will help you create a network of sites to fulfill a variety of purposes, and which you can customize to make life easier for your users and help your network run more efficiently and make you money.




lt

Marvelous Aerial Pictures of Salt Pans in Australia

En Australie, les paysages photographiés sont toujours un régal pour les yeux. Le photographe allemand Tom Hegen nous offre des clichés aériens à couper le souffle. Il nous emmène en Australie occidentale à la découverte des lacs salés. Ses plans d’eaux suivent en réalité les traces des anciens systèmes fluviaux. La région a été façonnée par le climat […]




lt

Hongo – The Ultimate WooCommerce WordPress Theme

Hongo is a creative and responsive, search engine optimised and fast loading, highly flexible and powerful, feature-rich and easy to use WooCommerce WordPress theme which comes with all necessary settings and tools which will help you to create a great … Continued

The post Hongo – The Ultimate WooCommerce WordPress Theme appeared first on WeLoveWP.




lt

Many anticipated arts, cultural events delayed or canceled

Summer is going to look a bit different in the Corridor this year as many, long-cherished events are being canceled or postponed. And the organizations that run those events want you to know they aren’t any more happy about it than you are.

The organizers of these events are having to make unprecedented, tough decisions.

“Cancellation is not a good word in our business,” said Chuck Swanson, Building a Legacy executive director of Hancher. “It is something that we really don’t want to do and it takes a lot for us to come to that.

“We live for the live performance and bringing the artists and audiences together. That’s the happiest time for me, so none of these decisions have been easy.”

Hancher has had to cancel numerous upcoming events in the past few months that would have brought to Iowa City in artists from all over the country and the world. It also is holding off announcing its upcoming season — which it typically would be doing at this time of year.

this isn’t something the staff has faced since the floods of 2008 and because they book events so far in advance they are confronting additional challenges.

“You know there’s so much that goes into a show before it happens,” Swanson said. “I just think of all the anticipation, booking the artists, advancing the show, setting ticket prices, advertising and then ticket sales.

“It’s like a farmer who does all this work to get his crops ready and then at the end of the season ends up with nothing to harvest.”

He noted Hancher has been reaching out to its booked performers and, in some cases, have had performers reach out to them to cancel upcoming shows.

The significant time and resources that go into planning large-scale events is the main factor in necessitating cancellation discussions and decisions at many organizations.

“Many logistical items have to be coordinated, from renting shuttles to scheduling volunteers and staff. Initial planning for some events begins as early as 12 to 18 months in advance and proceeds all the way up to the day of the event,” said John Myers, Indian Creek Nature Center executive director.

Citing the center’s annual Maple Syrup Festival, he noted food represents a significant cost and often cannot be saved or reused.

“We have had to be mindful of the financial resources available to us and ensure that we wisely manage those to ensure (the center) can emerge from this pandemic as a functioning and healthy organization,” he said.

“None of the decisions to cancel events or how to handle subsequent financial losses are easy and they challenge everyone,” Myers added. “As our whole lives have been upended, it makes even the simplest of decisions harder and that takes an impact on morale.”

He acknowledged staff members aren’t the only ones feeling the strain.

“We have a significant core of volunteers who are no longer able to give their time, which also creates a strain on morale and increases the amount of work that needs to be done when we return,” he pointed out.

Another primary factor is what is allowed and considered safe by the city, state and Iowa Department of Public Health.

“At this point, only allowing groups of 10 or less is a far cry from the thousands or people we usually see at the Iowa Arts Festival,” said Lisa Barnes, executive director of Summer of the Arts in Iowa City, which produces the Iowa Arts Festival.

“The governor has announced that reopening the state will be done in stages, and based on what we’ve found from other events around the country, concerts and large festivals will be the last to open,” he noted.

Summer of the Arts announced just last week that the Iowa Arts Festival would not take place this year, a month in advance of the event.

“We needed to make a decision so that we can move forward with alternative plans,” Barnes said, noting the organization has had questions about the Iowa City Jazz Festival, scheduled for July 3 through 5 and added a decision regarding that festival and July programming will be made by mid-late May.

“We also needed to make the decision far enough out to be able to work with our performers and cancel the agreements,” she said.

On Wednesday, Gov. Kim Reynolds loosened some but not all of the social-distancing restrictions for the remaining 22 counties she had put in place.

Heartbroken

Discussions about the future of these events have been happening for weeks for many organizations, highlighting they are not taken lightly.

Carissa Johnson, executive director of the Cedar Rapids Freedom Festival, said conversations about the future of this year’s event started in mid-March, right around the time the Cedar Rapids SaPaDaPaSo Parade announced its cancellation for 2020.

“We plan year ’round for the two- to three-week festival,” Johnson explained.

“Our planning really ramps up in April and May, and we have many more costs associated with producing the festival the closer we get to the start. In order to protect our time and resources, we elected to cancel before we had more costs and variables to consider.”

As for who is making the final decision, organizations said many stakeholders are involved. Barnes said the decision on the Iowa City Arts Festival, for example, included staff, the board of directors, festival planning committees, the city of Iowa City and Johnson County Public Health, along with input from some of the vendors, artists and performers.

Tapping into experts in those public health field has been key as well.

“We have these assets, people, at the University (of Iowa), that have been really helpful as we make these decisions about canceling and as we prepare to think about reopening,” Hancher’s Swanson said.

The Freedom Festival include staff and board members in discussions, with recommendations from Linn County Public Health and the city of Cedar Rapids, factoring in the health, safety and well-being of the community.

“We are just as heartbroken as the rest of the community, but this decision was to protect our community as much as possible,” Swanson said.

“This community is a family and we will all get through this together and come back stronger next year.”

Myers noted organizations such as the Indian Creek Nature Center are also rely on advice from national associations, such as the American Alliance of Museums, and discussions among the leadership of many local cultural groups.

“For many events, we have also reached out to participants to gather their input and comfort level of attending once we are able to reopen,” Myers said.

The financial effects of having to cancel is stressful for organizations, too.

“Financially, this has been a hard time for the Nature Center to endure,” Myers pointed out. “We’ve had over 100 different programs, events and facility rentals canceled between March 15 and April 30, and our losses are currently over $250,000. As we approach the summer, there are a number of other events we continue to review, including our popular summer camps.”

The Nature Center has postponed a national conference to be held there in September — due to indications of low participation — for peers from around the nation who run not-for-profit and government nature centers.

“We are losing thousands of dollars in vendor fees and sales receipts because we had to cancel,” said Barnes, of Summer of the Arts.

“We have sponsors tied to certain events, like the Iowa Arts Festival, that in some cases want to carry over their support to next year, which impacts our fundraising for this year and next.”

She noted her group already has been made aware of funding that won’t be coming in from some sponsors next year due to the financial impact those organizations are facing as well.

And that can be tough.

“When we cancel, our whole staff is involved — from the box audience and public engagement folks to the technical production team and our front-of-house staff,” Swanson said.

“Our communication is key in talking through it all and then sharing clear messages with our audiences, especially in terms of refunds. But we’ve been encouraged by so many generous friends of Hancher donating their ticket purchase price back to us.”

While disappointment still is thick in the air, organizations don’t plan to abandon their missions and is keeping an eye on serving the public.

“This is a challenging time for everyone, and our board and staff is committed to finding creative and non-traditional solutions to ensure the Freedom Festival’s return,” Johnson said. “The community and our stakeholders have been tremendous supports of the Freedom Festival and we believe they will continue to do so in the future.

“We ask for understanding and patience as we try to navigate this crisis and what we can still provide for our community.”

Freedom Festival buttons will be sold this year as they’ve already been made, and “It’s a way the community can show their support,” Johnson said.

Barnes agreed and noted the Iowa Arts Festival committee is working on ways to support the performers, artists and vendors they had scheduled by trying to develop some virtual opportunities for engagement.

While the show, or events, might not go on, organizers said they very much want to remain connected to their audiences and attendees.

“I want to make sure everybody knows we care about them and that we’re trying to find ways to stay connected because I think we’re all in this together and the arts are one of the best ways for people to get through difficult times,” Swanson said.

Myers agreed.

“Indian Creek Nature Center will be ready to welcome guests and visitors back to our events as soon as we are able to do so safely,” he said.

“In the meantime, we hope everyone finds peace in nature by taking a hike or bike ride, having a picnic or just enjoying time outside.”




lt

Marion coronavirus recovery task force wants residents to come out of this healthy and to ‘a vibrant economy’

MARION — Marion’s 14-member COVID-19 Economic Recovery Task Force is beginning to work on recommendations of how to get people back to work, while keeping everyone safe.

“It’s hard to know right now at the beginning the various outcomes that are going to come out of this,” Marion Mayor Nick AbouAssaly told task force members in a meeting held this week via Zoom.

“Community sectors will work independently and report to the steering committee with ideas, strategies or policy recommendations,” he said.

In turn, the task force will consider recommendations to the Marion City Council, and AbouAssaly said he will update the council on the task force meetings.

“Unfortunately, we have to accept that the virus is here to stay,” AbouAssaly said. “It’s part of our life for the time being. We have to be able to plan for getting back to doing things and leading our lives in a way that allows us to exist with the virus in our community.”

Elizabeth Cwik, a Marion resident who works for the Greater Cedar Rapids Community Foundation, said there’s a “strong interest” among task force members to provide accurate information to the public about the virus.

“I see clear, consistent messaging from a variety of sectors from the schools, government, businesses and nonprofits. Then that message gets through,” Cwik said. “If that message is, ‘We care, and we want you to come out whole, and we want there to be a vibrant economy to be continued with every citizen’s effort,’ I think that’s a valuable contribution to the recovery.”

In joining the task force, Dr. Jaclyn Price said she hopes to dispel inaccurate information about the coronavirus and help businesses find ways to safely bring their employees back to work.

“I anticipate businesses will be operating at reduced capacities,” she said. “Maybe doing appointments rather than walk-in business, and cleaning more routinely.”

If businesses require employees and customers to wear masks, it will protect others from asymptomatic spread of the virus, she said.

“We will still see virus activity until we get a vaccine or herd immunity,” Price said. “This is going to be a problem for months to come. We’re trying to find ways to open slowly, but also understanding if we reopen everything and have to close it again, that could be more detrimental to people’s psychology or finances of businesses.”

The Rev. Mike Morgan of Marion United Methodist Church said “greater conversation” with government, business, education and health care leaders will help.

“Marion has become a town that is proactive,” Morgan said. “We really seek to have good things happen to our citizenry rather than let things happen and we react to them. ... As a person in the faith community, it’s important for us to be tending to people’s emotional, psychological, spiritual and, to some degree, physical needs.”

Comments: (319) 368-8664; grace.king@thegazette.com

MARION TASK FORCE

Those serving on the Marion COVID-19 Economic Recovery Task Force, all Marion residents and volunteers, are:

• Nick AbouAssaly, Marion mayor

• Jill Ackerman, president, Marion Chamber of Commerce

• Shannon Bisgard, Linn-Mar schools superintendent

• Amber Bisinger, communications officer for the city

• Elizabeth Cwik, Greater Cedar Rapids Community Foundation

• Lee Eilers, executive committee member, Marion Economic Development Corp.

• Nick Glew, president, Marion Economic Development Corp.

• Amber Hoff, marriage and family therapist

• Steve Jensen, Marion City Council member

• Mike Morgan, pastor, Marion United Methodist Church

• Brent Oleson, Linn County supervisor

Lon Pluckhahn, Marion city manager

• Jaclyn Price, M.D., Mercy Clinic-Marion

• Brooke Prouty, program director, Marion Chamber of Commerce




lt

Second high-speed chase results in prison for Cedar Rapids man

CEDAR RAPIDS — A 32-year-old Cedar Rapids man, who received probation for a high-speed chase that he bragged about as “fun” and attempted to elude again in March, is heading to prison.

Sixth Judicial District Judge Lars Anderson on Friday revoked probation for Travis McDermott on the eluding charge from June 9, 2019, and sentenced him to five years in prison.

McDermott was convicted Tuesday for attempting to elude in March and was sentenced to 90 days in jail, which was run concurrently to the five-year prison sentence.

First Assistant Linn County Attorney Nick Maybanks told the judge that McDermott has a “significant violent history,” including assaults, assault on a peace officer, domestic assault, interference with official acts and child endangerment with bodily injury.

He continues to assault others and “show blatant disregard for authority figures,” the prosecutor noted.

In the eluding incident from last June, McDermott “risked lives” in a southwest neighborhood leading police on chase that began on when police saw his vehicle speeding on Rockford Road SW and run a stop sign at Eighth Avenue SW, Maybanks said Friday. McDermott drove 107 mph in a 30 mph zone and drove the wrong way on a one-way street at Third Street and Wilson Avenue SW.

McDermott ran into a pile of dirt at a dead end, jumped out of his car and led officers on a foot chase, Maybanks said. He wouldn’t stop, and officers used a Taser to subdue him.

McDermott was laughing when police arrested him, saying “how much fun” he had and appearing to be under the influence of drugs or alcohol, Maybanks said.

McDermott demanded a speedy trial, but the officer who conducted the sobriety test wasn’t available for trial. A plea was offered, and the drunken driving charge was dropped.

Maybanks also pointed out McDermott wouldn’t cooperate with the probation office on a presentencing report, which was ordered by a judge. He picked up an assault charge last November and was convicted before his eluding sentencing in January.

Maybanks said after McDermott received probation, he didn’t show up at the probation office for his appointment, didn’t get a substance abuse test as ordered and reported an invalid address to community corrections.

McDermott also has a pending charge in Dubuque County for driving while barred March 3, according to court documents.

Comments: (319) 398-8318; trish.mehaffey@thegazette.com




lt

Campgrounds reopen in Iowa Friday, see takers despite some health limitations

Some Eastern Iowans are ready to go camping.

With Gov. Kim Reynolds allowing campgrounds across the state to open Friday, some people wasted little time in heading outdoors.

“They’re already starting to fill up,” said Ryan Schlader of Linn County Conservation. “By about 7 this morning, we had a dozen at Squaw Creek Park. People were coming in bright and early to camp. We’re not surprised.”

Schlader said Linn County Conservation tried to have the campgrounds open at the county’s Squaw Creek, Morgan Creek and Pinicon Ridge parks at 5 a.m. Friday. He expected all of them would be busy.

“I think people were ready to go,” he said.

Lake Macbride State Park in Johnson County didn’t see quite as much of a rush for campsites, park manager Ron Puettmann reported Friday morning, saying he’d had six walk-ins for the park’s 42 campsites.

Camping this weekend will be done on a first-come, first-served basis. Sites won’t be available for reservations until next week, though online reservations can be made now, Puettmann said.

“I’m quite sure people were waiting anxiously to get on,” he said.

While Reynolds’ campground announcement came Wednesday, Schlader and Puettmann said they had no issues having the campgrounds ready for Friday.

Schlader said county staff have been in touch with the Iowa Department of Natural Resources and other county conservation boards to discuss protocols for reopening to ensure a safe experience for campers and employers.

“We anticipated at some point the order would be lifted,” Schlader said. “We were anticipating maybe May 15. The campgrounds were in good shape and ready to go.”

For now, camping comes with some limitations:

• Campers can camp only in a self-contained unit with a functioning restroom, such as a recreational vehicle.

• Shower houses with restrooms will remain closed for the time being.

• Campsites are limited to six people unless they are from the same household.

• No visitors are allowed at the campsites.

Puettmann said staffers and a DNR officer will be on hand to make sure guidelines are followed, but he didn’t anticipate enforcement would be an issue.

“For the most part, we’re going to allow people to police themselves,” he said.

It’s hard to gauge demand, Schlader said.

The weather isn’t yet deal for camping, and some people might not be ready to camp, given the continuing coronavirus.

“There is a lot of uncertainty,” he said. “Do people feel like they need to get out and enjoy a camping experience within their own campsite, or do people still feel under the weather and think it’s not a good idea for my family to go right now? ... We just want this to be an option for people.”

Comments: (319) 339-3155; lee.hermiston@thegazette.com




lt

Preset (Everyday) + transform + exposure + graduated filter +...



Preset (Everyday) + transform + exposure + graduated filter + radial filter. If shots like this take more than 2 minutes to edit, it’s probably not worth editing. ⏱

Boxing Day will be the last day to get my Lightroom presets discounted, which leaves you only 3 more days! Get on it! ???? (at Toronto, Ontario)




lt

Auphonic Leveler 1.8 and Auphonic Multitrack 1.4 Updates

Today we released free updates for the Auphonic Leveler Batch Processor and the Auphonic Multitrack Processor with many algorithm improvements and bug fixes for Mac and Windows.

Changelog

  • Linear Filtering Algorithms to avoid Asymmetric Waveforms:
    New zero-phase Adaptive Filtering Algorithms to avoid asymmetric waveforms.
    In asymmetric waveforms, the positive and negative amplitude values are disproportionate - please see Asymmetric Waveforms: Should You Be Concerned?.
    Asymmetrical waveforms are quite natural and not necessarily a problem. They are particularly common on recordings of speech, vocals and can be caused by low-end filtering. However, they limit the amount of gain that can be safely applied without introducing distortion or clipping due to aggressive limiting.
  • Noise Reduction Improvements:
    New and improved noise profile estimation algorithms and bug fixes for parallel Noise Reduction Algorithms.
  • Processing Finished Notification on Mac:
    A system notification (including a short glass sound) is now displayed on Mac OS when the Auphonic Leveler or Auphonic Multitrack has finished processing - thanks to Timo Hetzel.
  • Improved Dithering:
    Improved dithering algorithms - using SoX - if a bit-depth reduction is necessary during file export.
  • Auphonic Multitrack Fixes:
    Fixes for ducking and background tracks and for very short music tracks.
  • New Desktop Apps Documentation:
    The documentation of our desktop apps is now integrated in our new help system:
    see Auphonic Leveler Batch Processor and Auphonic Multitrack Processor.
  • Bug Fixes and Audio Algorithm Improvements:
    This release also includes many small bug fixes and all audio algorithms come with improvements and updated classifiers using the data from our Web Service.

About the Auphonic Desktop Apps

We offer two desktop programs which include our audio algorithms only. The algorithms will be computed offline on your device and are exactly the same as implemented in our Web Service.

The Auphonic Leveler Batch Processor is a batch audio file processor and includes all our (Singletrack) Audio Post Production Algorithms. It can process multiple productions at once.

Auphonic Multitrack includes our Multitrack Post Production Algorithms and requires multiple parallel input audio tracks, which will be analyzed and processed individually as well as combined to create one final mixdown.

Upgrade now

Everyone is encouraged to download the latest binaries:

Please let us know if you have any questions or feedback!






lt

Advanced Multitrack Audio Algorithms Release (Beta)

Last weekend, at the Subscribe10 conference, we released Advanced Audio Algorithm Parameters for Multitrack Productions:

We launched our advanced audio algorithm parameters for Singletrack Productions last year. Now these settings (and more) are available for Multitrack Algorithms as well, which gives you detailed control for each track of your production.

The following new parameters are available:

Please join our private beta program and let us know how you use these new features or if you need even more control!

Fore/Background Settings

The parameter Fore/Background controls whether a track should be in foreground, in background, ducked, or unchanged, which is especially important for music or clip tracks.
For more details, please see Automatic Ducking, Foreground and Background Tracks .

We now added the new option Unchanged and a new parameter to set the level of background segments/tracks:
Unchanged (Foreground):
We sometimes received complaints from users, which produced very complex music or clip tracks, that Auphonic changes the levels too hard.
If you set the parameter Fore/Background to the new option Unchanged (Foreground), Level relations within this track won’t be changed at all. It will be added to the final mixdown so that foreground/solo parts of this track will be as loud as (foreground) speech from other tracks.
Background Level:
It is now possible to set the level of background segments/tracks (compared to foreground segments) in background and ducking tracks. By default, background and ducking segments are 18dB softer than foreground segments.

Leveler Parameters

Similar to our Singletrack Advanced Leveler Parameters (see this previous blog post), we also released leveling parameters for Multitrack Productions now.
The following advanced parameters for our Multitrack Adaptive Leveler can be set for each track and allow you to customize which parts of the audio should be leveled, how much they should be leveled, how much dynamic range compression should be applied and to set the stereo panorama (balance):

Leveler Preset:
Select the Speech or Music Leveler for this track.
If set to Automatic (default), a classifier will decide if this is a music or speech track.
Dynamic Range:
The parameter Dynamic Range controls how much leveling is applied: Higher values result in more dynamic output audio files (less leveling). If you want to increase the dynamic range by 3dB (or LU), just increase the Dynamic Range parameter by 3dB.
For more details, please see Multitrack Leveler Parameters.
Compressor:
Select a preset for Micro-Dynamics Compression: Auto, Soft, Medium, Hard or Off.
The Compressor adjusts short-term dynamics, whereas the Leveler adjusts mid-term level differences.
For more details, please see Multitrack Leveler Parameters.
Stereo Panorama (Balance):
Change the stereo panorama (balance for stereo input files) of the current track.
Possible values: L100, L75, L50, L25, Center, R25, R50, R75 and R100.

If you understand German and want to know more about our Advanced Leveler Parameters and audio dynamics in general, watch our talk at the Subscribe10 conference:
Video: Audio Lautheit und Dynamik.

Better Hum and Noise Reduction Controls

We now offer three parameters to control the combination of our Multitrack Noise and Hum Reduction Algorithms for each input track:
Noise Reduction Amount:
Maximum noise and hum reduction amount in dB, higher values remove more noise.
In Auto mode, a classifier decides if and how much noise reduction is necessary (to avoid artifacts). Set to a custom (non-Auto) value if you prefer more noise reduction or want to bypass our classifier.
Hum Base Frequency:
Set the hum base frequency to 50Hz or 60Hz (if you know it), or use Auto to automatically detect the hum base frequency in each speech region.
Hum Reduction Amount:
Maximum hum reduction amount in dB, higher values remove more noise.
In Auto mode, a classifier decides how much hum reduction is necessary in each speech region. Set it to a custom value (> 0), if you prefer more hum reduction or want to bypass our classifier. Use Disable Dehum to disable hum reduction and use our noise reduction algorithms only.

Behavior of noise and hum reduction parameter combinations:

Noise Reduction Amount Hum Base Frequency Hum Reduction Amount
Auto Auto Auto Automatic hum and noise reduction
Auto or > 0 * Disabled No hum reduction, only denoise
Disabled 50Hz Auto or > 0 Force 50Hz hum reduction, no denoise
Disabled Auto Auto or > 0 Automatic dehum, no denoise
12dB 60Hz Auto or > 0 Always do dehum (60Hz) and denoise (12dB)

Maximum True Peak Level

In the Master Algorithm Settings of your multitrack production, you can set the maximum allowed true peak level of the processed output file, which is controlled by the True Peak Limiter after our Loudness Normalization algorithms.

If set to Auto (which is the current default), a reasonable value according to the selected loudness target is used: -1dBTP for 23 LUFS (EBU R128) and higher, -2dBTP for -24 LUFS (ATSC A/85) and lower loudness targets.

Full API Support

All advanced algorithm parameters, for Singletrack and Multitrack Productions, are available in our API as well, which allows you to integrate them into your scripts, external workflows and third-party applications.

Singletrack API:
Documentation on how to use the advanced algorithm parameters in our singletrack production API: Advanced Algorithm Parameters
Multitrack API:
Documentation of advanced settings for each track of a multitrack production:
Multitrack Advanced Audio Algorithm Settings

Join the Beta and Send Feedback

Please join our beta and let us know your case studies, if you need any other algorithm parameters or if you have any questions!

Here are some private beta invitation codes:

8tZPc3T9pH VAvO8VsDg9 0TwKXBW4Ni kjXJMivtZ1 J9APmAAYjT Zwm6HabuFw HNK5gF8FR5 Do1MPHUyPW CTk45VbV4t xYOzDkEnWP
9XE4dZ0FxD 0Sl3PxDRho uSoRQxmKPx TCI62OjEYu 6EQaPYs7v4 reIJVOwIr8 7hPJqZmWfw kti3m5KbNE GoM2nF0AcN xHCbDC37O5
6PabLBRm9P j2SoI8peiY olQ2vsmnfV fqfxX4mWLO OozsiA8DWo weJw0PXDky VTnOfOiL6l B6HRr6gil0 so0AvM1Ryy NpPYsInFqm
oFeQPLwG0k HmCOkyaX9R G7DR5Sc9Kv MeQLSUCkge xCSvPTrTgl jyQKG3BWWA HCzWRxSrgW xP15hYKEDl 241gK62TrO Q56DHjT3r4
9TqWVZHZLE aWFMSWcuX8 x6FR5OTL43 Xf6tRpyP4S tDGbOUngU0 5BkOF2I264 cccHS0KveO dT29cF75gG 2ySWlYp1kp iJWPhpAimF
We are happy to send further invitation codes to all interested users - please do not hesitate to contact us!

If you have an invitation code, you can enter it here to activate the Multitrack Advanced Audio Algorithm Parameters:
Auphonic Algorithm Parameters Private Beta Activation







lt

Concurrency & Multithreading in iOS

Concurrency is the notion of multiple things happening at the same time. This is generally achieved either via time-slicing, or truly in parallel if multiple CPU cores are available to the host operating system. We've all experienced a lack of concurrency, most likely in the form of an app freezing up when running a heavy task. UI freezes don't necessarily occur due to the absence of concurrency — they could just be symptoms of buggy software — but software that doesn't take advantage of all the computational power at its disposal is going to create these freezes whenever it needs to do something resource-intensive. If you've profiled an app hanging in this way, you'll probably see a report that looks like this:

Anything related to file I/O, data processing, or networking usually warrants a background task (unless you have a very compelling excuse to halt the entire program). There aren't many reasons that these tasks should block your user from interacting with the rest of your application. Consider how much better the user experience of your app could be if instead, the profiler reported something like this:

Analyzing an image, processing a document or a piece of audio, or writing a sizeable chunk of data to disk are examples of tasks that could benefit greatly from being delegated to background threads. Let's dig into how we can enforce such behavior into our iOS applications.


A Brief History

In the olden days, the maximum amount of work per CPU cycle that a computer could perform was determined by the clock speed. As processor designs became more compact, heat and physical constraints started becoming limiting factors for higher clock speeds. Consequentially, chip manufacturers started adding additional processor cores on each chip in order to increase total performance. By increasing the number of cores, a single chip could execute more CPU instructions per cycle without increasing its speed, size, or thermal output. There's just one problem...

How can we take advantage of these extra cores? Multithreading.

Multithreading is an implementation handled by the host operating system to allow the creation and usage of n amount of threads. Its main purpose is to provide simultaneous execution of two or more parts of a program to utilize all available CPU time. Multithreading is a powerful technique to have in a programmer's toolbelt, but it comes with its own set of responsibilities. A common misconception is that multithreading requires a multi-core processor, but this isn't the case — single-core CPUs are perfectly capable of working on many threads, but we'll take a look in a bit as to why threading is a problem in the first place. Before we dive in, let's look at the nuances of what concurrency and parallelism mean using a simple diagram:

In the first situation presented above, we observe that tasks can run concurrently, but not in parallel. This is similar to having multiple conversations in a chatroom, and interleaving (context-switching) between them, but never truly conversing with two people at the same time. This is what we call concurrency. It is the illusion of multiple things happening at the same time when in reality, they're switching very quickly. Concurrency is about dealing with lots of things at the same time. Contrast this with the parallelism model, in which both tasks run simultaneously. Both execution models exhibit multithreading, which is the involvement of multiple threads working towards one common goal. Multithreading is a generalized technique for introducing a combination of concurrency and parallelism into your program.


The Burden of Threads

A modern multitasking operating system like iOS has hundreds of programs (or processes) running at any given moment. However, most of these programs are either system daemons or background processes that have very low memory footprint, so what is really needed is a way for individual applications to make use of the extra cores available. An application (process) can have many threads (sub-processes) operating on shared memory. Our goal is to be able to control these threads and use them to our advantage.

Historically, introducing concurrency to an app has required the creation of one or more threads. Threads are low-level constructs that need to be managed manually. A quick skim through Apple's Threaded Programming Guide is all it takes to see how much complexity threaded code adds to a codebase. In addition to building an app, the developer has to:

  • Responsibly create new threads, adjusting that number dynamically as system conditions change
  • Manage them carefully, deallocating them from memory once they have finished executing
  • Leverage synchronization mechanisms like mutexes, locks, and semaphores to orchestrate resource access between threads, adding even more overhead to application code
  • Mitigate risks associated with coding an application that assumes most of the costs associated with creating and maintaining any threads it uses, and not the host OS

This is unfortunate, as it adds enormous levels of complexity and risk without any guarantees of improved performance.


Grand Central Dispatch

iOS takes an asynchronous approach to solving the concurrency problem of managing threads. Asynchronous functions are common in most programming environments, and are often used to initiate tasks that might take a long time, like reading a file from the disk, or downloading a file from the web. When invoked, an asynchronous function executes some work behind the scenes to start a background task, but returns immediately, regardless of how long the original task might takes to actually complete.

A core technology that iOS provides for starting tasks asynchronously is Grand Central Dispatch (or GCD for short). GCD abstracts away thread management code and moves it down to the system level, exposing a light API to define tasks and execute them on an appropriate dispatch queue. GCD takes care of all thread management and scheduling, providing a holistic approach to task management and execution, while also providing better efficiency than traditional threads.

Let's take a look at the main components of GCD:

What've we got here? Let's start from the left:

  • DispatchQueue.main: The main thread, or the UI thread, is backed by a single serial queue. All tasks are executed in succession, so it is guaranteed that the order of execution is preserved. It is crucial that you ensure all UI updates are designated to this queue, and that you never run any blocking tasks on it. We want to ensure that the app's run loop (called CFRunLoop) is never blocked in order to maintain the highest framerate. Subsequently, the main queue has the highest priority, and any tasks pushed onto this queue will get executed immediately.
  • DispatchQueue.global: A set of global concurrent queues, each of which manage their own pool of threads. Depending on the priority of your task, you can specify which specific queue to execute your task on, although you should resort to using default most of the time. Because tasks on these queues are executed concurrently, it doesn't guarantee preservation of the order in which tasks were queued.

Notice how we're not dealing with individual threads anymore? We're dealing with queues which manage a pool of threads internally, and you will shortly see why queues are a much more sustainable approach to multhreading.

Serial Queues: The Main Thread

As an exercise, let's look at a snippet of code below, which gets fired when the user presses a button in the app. The expensive compute function can be anything. Let's pretend it is post-processing an image stored on the device.

import UIKit

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        compute()
    }

    private func compute() -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

At first glance, this may look harmless, but if you run this inside of a real app, the UI will freeze completely until the loop is terminated, which will take... a while. We can prove it by profiling this task in Instruments. You can fire up the Time Profiler module of Instruments by going to Xcode > Open Developer Tool > Instruments in Xcode's menu options. Let's look at the Threads module of the profiler and see where the CPU usage is highest.

We can see that the Main Thread is clearly at 100% capacity for almost 5 seconds. That's a non-trivial amount of time to block the UI. Looking at the call tree below the chart, we can see that the Main Thread is at 99.9% capacity for 4.43 seconds! Given that a serial queue works in a FIFO manner, tasks will always complete in the order in which they were inserted. Clearly the compute() method is the culprit here. Can you imagine clicking a button just to have the UI freeze up on you for that long?

Background Threads

How can we make this better? DispatchQueue.global() to the rescue! This is where background threads come in. Referring to the GCD architecture diagram above, we can see that anything that is not the Main Thread is a background thread in iOS. They can run alongside the Main Thread, leaving it fully unoccupied and ready to handle other UI events like scrolling, responding to user events, animating etc. Let's make a small change to our button click handler above:

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
            self.compute()
        }
    }

    private func compute() -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

Unless specified, a snippet of code will usually default to execute on the Main Queue, so in order to force it to execute on a different thread, we'll wrap our compute call inside of an asynchronous closure that gets submitted to the DispatchQueue.global queue. Keep in mind that we aren't really managing threads here. We're submitting tasks (in the form of closures or blocks) to the desired queue with the assumption that it is guaranteed to execute at some point in time. The queue decides which thread to allocate the task to, and it does all the hard work of assessing system requirements and managing the actual threads. This is the magic of Grand Central Dispatch. As the old adage goes, you can't improve what you can't measure. So we measured our truly terrible button click handler, and now that we've improved it, we'll measure it once again to get some concrete data with regards to performance.

Looking at the profiler again, it's quite clear to us that this is a huge improvement. The task takes an identical amount of time, but this time, it's happening in the background without locking up the UI. Even though our app is doing the same amount of work, the perceived performance is much better because the user will be free to do other things while the app is processing.

You may have noticed that we accessed a global queue of .userInitiated priority. This is an attribute we can use to give our tasks a sense of urgency. If we run the same task on a global queue of and pass it a qos attribute of background , iOS will think it's a utility task, and thus allocate fewer resources to execute it. So, while we don't have control over when our tasks get executed, we do have control over their priority.

A Note on Main Thread vs. Main Queue

You might be wondering why the Profiler shows "Main Thread" and why we're referring to it as the "Main Queue". If you refer back to the GCD architecture we described above, the Main Queue is solely responsible for managing the Main Thread. The Dispatch Queues section in the Concurrency Programming Guide says that "the main dispatch queue is a globally available serial queue that executes tasks on the application’s main thread. Because it runs on your application’s main thread, the main queue is often used as a key synchronization point for an application."

The terms "execute on the Main Thread" and "execute on the Main Queue" can be used interchangeably.


Concurrent Queues

So far, our tasks have been executed exclusively in a serial manner. DispatchQueue.main is by default a serial queue, and DispatchQueue.global gives you four concurrent dispatch queues depending on the priority parameter you pass in.

Let's say we want to take five images, and have our app process them all in parallel on background threads. How would we go about doing that? We can spin up a custom concurrent queue with an identifier of our choosing, and allocate those tasks there. All that's required is the .concurrent attribute during the construction of the queue.

class ViewController: UIViewController {
    let queue = DispatchQueue(label: "com.app.concurrentQueue", attributes: .concurrent)
    let images: [UIImage] = [UIImage].init(repeating: UIImage(), count: 5)

    @IBAction func handleTap(_ sender: Any) {
        for img in images {
            queue.async { [unowned self] in
                self.compute(img)
            }
        }
    }

    private func compute(_ img: UIImage) -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

Running that through the profiler, we can see that the app is now spinning up 5 discrete threads to parallelize a for-loop.

Parallelization of N Tasks

So far, we've looked at pushing computationally expensive task(s) onto background threads without clogging up the UI thread. But what about executing parallel tasks with some restrictions? How can Spotify download multiple songs in parallel, while limiting the maximum number up to 3? We can go about this in a few ways, but this is a good time to explore another important construct in multithreaded programming: semaphores.

Semaphores are signaling mechanisms. They are commonly used to control access to a shared resource. Imagine a scenario where a thread can lock access to a certain section of the code while it executes it, and unlocks after it's done to let other threads execute the said section of the code. You would see this type of behavior in database writes and reads, for example. What if you want only one thread writing to a database and preventing any reads during that time? This is a common concern in thread-safety called Readers-writer lock. Semaphores can be used to control concurrency in our app by allowing us to lock n number of threads.

let kMaxConcurrent = 3 // Or 1 if you want strictly ordered downloads!
let semaphore = DispatchSemaphore(value: kMaxConcurrent)
let downloadQueue = DispatchQueue(label: "com.app.downloadQueue", attributes: .concurrent)

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        for i in 0..<15 {
            downloadQueue.async { [unowned self] in
                // Lock shared resource access
                semaphore.wait()

                // Expensive task
                self.download(i + 1)

                // Update the UI on the main thread, always!
                DispatchQueue.main.async {
                    tableView.reloadData()

                    // Release the lock
                    semaphore.signal()
                }
            }
        }
    }

    func download(_ songId: Int) -> Void {
        var counter = 0

        // Simulate semi-random download times.
        for _ in 0..<Int.random(in: 999999...10000000) {
            counter += songId
        }
    }
}

Notice how we've effectively restricted our download system to limit itself to k number of downloads. The moment one download finishes (or thread is done executing), it decrements the semaphore, allowing the managing queue to spawn another thread and start downloading another song. You can apply a similar pattern to database transactions when dealing with concurrent reads and writes.

Semaphores usually aren't necessary for code like the one in our example, but they become more powerful when you need to enforce synchronous behavior whille consuming an asynchronous API. The above could would work just as well with a custom NSOperationQueue with a maxConcurrentOperationCount, but it's a worthwhile tangent regardless.


Finer Control with OperationQueue

GCD is great when you want to dispatch one-off tasks or closures into a queue in a 'set-it-and-forget-it' fashion, and it provides a very lightweight way of doing so. But what if we want to create a repeatable, structured, long-running task that produces associated state or data? And what if we want to model this chain of operations such that they can be cancelled, suspended and tracked, while still working with a closure-friendly API? Imagine an operation like this:

This would be quite cumbersome to achieve with GCD. We want a more modular way of defining a group of tasks while maintaining readability and also exposing a greater amount of control. In this case, we can use Operation objects and queue them onto an OperationQueue, which is a high-level wrapper around DispatchQueue. Let's look at some of the benefits of using these abstractions and what they offer in comparison to the lower-level GCI API:

  • You may want to create dependencies between tasks, and while you could do this via GCD, you're better off defining them concretely as Operation objects, or units of work, and pushing them onto your own queue. This would allow for maximum reusability since you may use the same pattern elsewhere in an application.
  • The Operation and OperationQueue classes have a number of properties that can be observed, using KVO (Key Value Observing). This is another important benefit if you want to monitor the state of an operation or operation queue.
  • Operations can be paused, resumed, and cancelled. Once you dispatch a task using Grand Central Dispatch, you no longer have control or insight into the execution of that task. The Operation API is more flexible in that respect, giving the developer control over the operation's life cycle.
  • OperationQueue allows you to specify the maximum number of queued operations that can run simultaneously, giving you a finer degree of control over the concurrency aspects.

The usage of Operation and OperationQueue could fill an entire blog post, but let's look at a quick example of what modeling dependencies looks like. (GCD can also create dependencies, but you're better off dividing up large tasks into a series of composable sub-tasks.) In order to create a chain of operations that depend on one another, we could do something like this:

class ViewController: UIViewController {
    var queue = OperationQueue()
    var rawImage = UIImage? = nil
    let imageUrl = URL(string: "https://example.com/portrait.jpg")!
    @IBOutlet weak var imageView: UIImageView!

    let downloadOperation = BlockOperation {
        let image = Downloader.downloadImageWithURL(url: imageUrl)
        OperationQueue.main.async {
            self.rawImage = image
        }
    }

    let filterOperation = BlockOperation {
        let filteredImage = ImgProcessor.addGaussianBlur(self.rawImage)
        OperationQueue.main.async {
            self.imageView = filteredImage
        }
    }

    filterOperation.addDependency(downloadOperation)

    [downloadOperation, filterOperation].forEach {
        queue.addOperation($0)
     }
}

So why not opt for a higher level abstraction and avoid using GCD entirely? While GCD is ideal for inline asynchronous processing, Operation provides a more comprehensive, object-oriented model of computation for encapsulating all of the data around structured, repeatable tasks in an application. Developers should use the highest level of abstraction possible for any given problem, and for scheduling consistent, repeated work, that abstraction is Operation. Other times, it makes more sense to sprinkle in some GCD for one-off tasks or closures that we want to fire. We can mix both OperationQueue and GCD to get the best of both worlds.


The Cost of Concurrency

DispatchQueue and friends are meant to make it easier for the application developer to execute code concurrently. However, these technologies do not guarantee improvements to the efficiency or responsiveness in an application. It is up to you to use queues in a manner that is both effective and does not impose an undue burden on other resources. For example, it's totally viable to create 10,000 tasks and submit them to a queue, but doing so would allocate a nontrivial amount of memory and introduce a lot of overhead for the allocation and deallocation of operation blocks. This is the opposite of what you want! It's best to profile your app thoroughly to ensure that concurrency is enhancing your app's performance and not degrading it.

We've talked about how concurrency comes at a cost in terms of complexity and allocation of system resources, but introducing concurrency also brings a host of other risks like:

  • Deadlock: A situation where a thread locks a critical portion of the code and can halt the application's run loop entirely. In the context of GCD, you should be very careful when using the dispatchQueue.sync { } calls as you could easily get yourself in situations where two synchronous operations can get stuck waiting for each other.
  • Priority Inversion: A condition where a lower priority task blocks a high priority task from executing, which effectively inverts their priorities. GCD allows for different levels of priority on its background queues, so this is quite easily a possibility.
  • Producer-Consumer Problem: A race condition where one thread is creating a data resource while another thread is accessing it. This is a synchronization problem, and can be solved using locks, semaphores, serial queues, or a barrier dispatch if you're using concurrent queues in GCD.
  • ...and many other sorts of locking and data-race conditions that are hard to debug! Thread safety is of the utmost concern when dealing with concurrency.

Parting Thoughts + Further Reading

If you've made it this far, I applaud you. Hopefully this article gives you a lay of the land when it comes to multithreading techniques on iOS, and how you can use some of them in your app. We didn't get to cover many of the lower-level constructs like locks, mutexes and how they help us achieve synchronization, nor did we get to dive into concrete examples of how concurrency can hurt your app. We'll save those for another day, but you can dig into some additional reading and videos if you're eager to dive deeper.




lt

Concurrency & Multithreading in iOS

Concurrency is the notion of multiple things happening at the same time. This is generally achieved either via time-slicing, or truly in parallel if multiple CPU cores are available to the host operating system. We've all experienced a lack of concurrency, most likely in the form of an app freezing up when running a heavy task. UI freezes don't necessarily occur due to the absence of concurrency — they could just be symptoms of buggy software — but software that doesn't take advantage of all the computational power at its disposal is going to create these freezes whenever it needs to do something resource-intensive. If you've profiled an app hanging in this way, you'll probably see a report that looks like this:

Anything related to file I/O, data processing, or networking usually warrants a background task (unless you have a very compelling excuse to halt the entire program). There aren't many reasons that these tasks should block your user from interacting with the rest of your application. Consider how much better the user experience of your app could be if instead, the profiler reported something like this:

Analyzing an image, processing a document or a piece of audio, or writing a sizeable chunk of data to disk are examples of tasks that could benefit greatly from being delegated to background threads. Let's dig into how we can enforce such behavior into our iOS applications.


A Brief History

In the olden days, the maximum amount of work per CPU cycle that a computer could perform was determined by the clock speed. As processor designs became more compact, heat and physical constraints started becoming limiting factors for higher clock speeds. Consequentially, chip manufacturers started adding additional processor cores on each chip in order to increase total performance. By increasing the number of cores, a single chip could execute more CPU instructions per cycle without increasing its speed, size, or thermal output. There's just one problem...

How can we take advantage of these extra cores? Multithreading.

Multithreading is an implementation handled by the host operating system to allow the creation and usage of n amount of threads. Its main purpose is to provide simultaneous execution of two or more parts of a program to utilize all available CPU time. Multithreading is a powerful technique to have in a programmer's toolbelt, but it comes with its own set of responsibilities. A common misconception is that multithreading requires a multi-core processor, but this isn't the case — single-core CPUs are perfectly capable of working on many threads, but we'll take a look in a bit as to why threading is a problem in the first place. Before we dive in, let's look at the nuances of what concurrency and parallelism mean using a simple diagram:

In the first situation presented above, we observe that tasks can run concurrently, but not in parallel. This is similar to having multiple conversations in a chatroom, and interleaving (context-switching) between them, but never truly conversing with two people at the same time. This is what we call concurrency. It is the illusion of multiple things happening at the same time when in reality, they're switching very quickly. Concurrency is about dealing with lots of things at the same time. Contrast this with the parallelism model, in which both tasks run simultaneously. Both execution models exhibit multithreading, which is the involvement of multiple threads working towards one common goal. Multithreading is a generalized technique for introducing a combination of concurrency and parallelism into your program.


The Burden of Threads

A modern multitasking operating system like iOS has hundreds of programs (or processes) running at any given moment. However, most of these programs are either system daemons or background processes that have very low memory footprint, so what is really needed is a way for individual applications to make use of the extra cores available. An application (process) can have many threads (sub-processes) operating on shared memory. Our goal is to be able to control these threads and use them to our advantage.

Historically, introducing concurrency to an app has required the creation of one or more threads. Threads are low-level constructs that need to be managed manually. A quick skim through Apple's Threaded Programming Guide is all it takes to see how much complexity threaded code adds to a codebase. In addition to building an app, the developer has to:

  • Responsibly create new threads, adjusting that number dynamically as system conditions change
  • Manage them carefully, deallocating them from memory once they have finished executing
  • Leverage synchronization mechanisms like mutexes, locks, and semaphores to orchestrate resource access between threads, adding even more overhead to application code
  • Mitigate risks associated with coding an application that assumes most of the costs associated with creating and maintaining any threads it uses, and not the host OS

This is unfortunate, as it adds enormous levels of complexity and risk without any guarantees of improved performance.


Grand Central Dispatch

iOS takes an asynchronous approach to solving the concurrency problem of managing threads. Asynchronous functions are common in most programming environments, and are often used to initiate tasks that might take a long time, like reading a file from the disk, or downloading a file from the web. When invoked, an asynchronous function executes some work behind the scenes to start a background task, but returns immediately, regardless of how long the original task might takes to actually complete.

A core technology that iOS provides for starting tasks asynchronously is Grand Central Dispatch (or GCD for short). GCD abstracts away thread management code and moves it down to the system level, exposing a light API to define tasks and execute them on an appropriate dispatch queue. GCD takes care of all thread management and scheduling, providing a holistic approach to task management and execution, while also providing better efficiency than traditional threads.

Let's take a look at the main components of GCD:

What've we got here? Let's start from the left:

  • DispatchQueue.main: The main thread, or the UI thread, is backed by a single serial queue. All tasks are executed in succession, so it is guaranteed that the order of execution is preserved. It is crucial that you ensure all UI updates are designated to this queue, and that you never run any blocking tasks on it. We want to ensure that the app's run loop (called CFRunLoop) is never blocked in order to maintain the highest framerate. Subsequently, the main queue has the highest priority, and any tasks pushed onto this queue will get executed immediately.
  • DispatchQueue.global: A set of global concurrent queues, each of which manage their own pool of threads. Depending on the priority of your task, you can specify which specific queue to execute your task on, although you should resort to using default most of the time. Because tasks on these queues are executed concurrently, it doesn't guarantee preservation of the order in which tasks were queued.

Notice how we're not dealing with individual threads anymore? We're dealing with queues which manage a pool of threads internally, and you will shortly see why queues are a much more sustainable approach to multhreading.

Serial Queues: The Main Thread

As an exercise, let's look at a snippet of code below, which gets fired when the user presses a button in the app. The expensive compute function can be anything. Let's pretend it is post-processing an image stored on the device.

import UIKit

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        compute()
    }

    private func compute() -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

At first glance, this may look harmless, but if you run this inside of a real app, the UI will freeze completely until the loop is terminated, which will take... a while. We can prove it by profiling this task in Instruments. You can fire up the Time Profiler module of Instruments by going to Xcode > Open Developer Tool > Instruments in Xcode's menu options. Let's look at the Threads module of the profiler and see where the CPU usage is highest.

We can see that the Main Thread is clearly at 100% capacity for almost 5 seconds. That's a non-trivial amount of time to block the UI. Looking at the call tree below the chart, we can see that the Main Thread is at 99.9% capacity for 4.43 seconds! Given that a serial queue works in a FIFO manner, tasks will always complete in the order in which they were inserted. Clearly the compute() method is the culprit here. Can you imagine clicking a button just to have the UI freeze up on you for that long?

Background Threads

How can we make this better? DispatchQueue.global() to the rescue! This is where background threads come in. Referring to the GCD architecture diagram above, we can see that anything that is not the Main Thread is a background thread in iOS. They can run alongside the Main Thread, leaving it fully unoccupied and ready to handle other UI events like scrolling, responding to user events, animating etc. Let's make a small change to our button click handler above:

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
            self.compute()
        }
    }

    private func compute() -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

Unless specified, a snippet of code will usually default to execute on the Main Queue, so in order to force it to execute on a different thread, we'll wrap our compute call inside of an asynchronous closure that gets submitted to the DispatchQueue.global queue. Keep in mind that we aren't really managing threads here. We're submitting tasks (in the form of closures or blocks) to the desired queue with the assumption that it is guaranteed to execute at some point in time. The queue decides which thread to allocate the task to, and it does all the hard work of assessing system requirements and managing the actual threads. This is the magic of Grand Central Dispatch. As the old adage goes, you can't improve what you can't measure. So we measured our truly terrible button click handler, and now that we've improved it, we'll measure it once again to get some concrete data with regards to performance.

Looking at the profiler again, it's quite clear to us that this is a huge improvement. The task takes an identical amount of time, but this time, it's happening in the background without locking up the UI. Even though our app is doing the same amount of work, the perceived performance is much better because the user will be free to do other things while the app is processing.

You may have noticed that we accessed a global queue of .userInitiated priority. This is an attribute we can use to give our tasks a sense of urgency. If we run the same task on a global queue of and pass it a qos attribute of background , iOS will think it's a utility task, and thus allocate fewer resources to execute it. So, while we don't have control over when our tasks get executed, we do have control over their priority.

A Note on Main Thread vs. Main Queue

You might be wondering why the Profiler shows "Main Thread" and why we're referring to it as the "Main Queue". If you refer back to the GCD architecture we described above, the Main Queue is solely responsible for managing the Main Thread. The Dispatch Queues section in the Concurrency Programming Guide says that "the main dispatch queue is a globally available serial queue that executes tasks on the application’s main thread. Because it runs on your application’s main thread, the main queue is often used as a key synchronization point for an application."

The terms "execute on the Main Thread" and "execute on the Main Queue" can be used interchangeably.


Concurrent Queues

So far, our tasks have been executed exclusively in a serial manner. DispatchQueue.main is by default a serial queue, and DispatchQueue.global gives you four concurrent dispatch queues depending on the priority parameter you pass in.

Let's say we want to take five images, and have our app process them all in parallel on background threads. How would we go about doing that? We can spin up a custom concurrent queue with an identifier of our choosing, and allocate those tasks there. All that's required is the .concurrent attribute during the construction of the queue.

class ViewController: UIViewController {
    let queue = DispatchQueue(label: "com.app.concurrentQueue", attributes: .concurrent)
    let images: [UIImage] = [UIImage].init(repeating: UIImage(), count: 5)

    @IBAction func handleTap(_ sender: Any) {
        for img in images {
            queue.async { [unowned self] in
                self.compute(img)
            }
        }
    }

    private func compute(_ img: UIImage) -> Void {
        // Pretending to post-process a large image.
        var counter = 0
        for _ in 0..<9999999 {
            counter += 1
        }
    }
}

Running that through the profiler, we can see that the app is now spinning up 5 discrete threads to parallelize a for-loop.

Parallelization of N Tasks

So far, we've looked at pushing computationally expensive task(s) onto background threads without clogging up the UI thread. But what about executing parallel tasks with some restrictions? How can Spotify download multiple songs in parallel, while limiting the maximum number up to 3? We can go about this in a few ways, but this is a good time to explore another important construct in multithreaded programming: semaphores.

Semaphores are signaling mechanisms. They are commonly used to control access to a shared resource. Imagine a scenario where a thread can lock access to a certain section of the code while it executes it, and unlocks after it's done to let other threads execute the said section of the code. You would see this type of behavior in database writes and reads, for example. What if you want only one thread writing to a database and preventing any reads during that time? This is a common concern in thread-safety called Readers-writer lock. Semaphores can be used to control concurrency in our app by allowing us to lock n number of threads.

let kMaxConcurrent = 3 // Or 1 if you want strictly ordered downloads!
let semaphore = DispatchSemaphore(value: kMaxConcurrent)
let downloadQueue = DispatchQueue(label: "com.app.downloadQueue", attributes: .concurrent)

class ViewController: UIViewController {
    @IBAction func handleTap(_ sender: Any) {
        for i in 0..<15 {
            downloadQueue.async { [unowned self] in
                // Lock shared resource access
                semaphore.wait()

                // Expensive task
                self.download(i + 1)

                // Update the UI on the main thread, always!
                DispatchQueue.main.async {
                    tableView.reloadData()

                    // Release the lock
                    semaphore.signal()
                }
            }
        }
    }

    func download(_ songId: Int) -> Void {
        var counter = 0

        // Simulate semi-random download times.
        for _ in 0..<Int.random(in: 999999...10000000) {
            counter += songId
        }
    }
}

Notice how we've effectively restricted our download system to limit itself to k number of downloads. The moment one download finishes (or thread is done executing), it decrements the semaphore, allowing the managing queue to spawn another thread and start downloading another song. You can apply a similar pattern to database transactions when dealing with concurrent reads and writes.

Semaphores usually aren't necessary for code like the one in our example, but they become more powerful when you need to enforce synchronous behavior whille consuming an asynchronous API. The above could would work just as well with a custom NSOperationQueue with a maxConcurrentOperationCount, but it's a worthwhile tangent regardless.


Finer Control with OperationQueue

GCD is great when you want to dispatch one-off tasks or closures into a queue in a 'set-it-and-forget-it' fashion, and it provides a very lightweight way of doing so. But what if we want to create a repeatable, structured, long-running task that produces associated state or data? And what if we want to model this chain of operations such that they can be cancelled, suspended and tracked, while still working with a closure-friendly API? Imagine an operation like this:

This would be quite cumbersome to achieve with GCD. We want a more modular way of defining a group of tasks while maintaining readability and also exposing a greater amount of control. In this case, we can use Operation objects and queue them onto an OperationQueue, which is a high-level wrapper around DispatchQueue. Let's look at some of the benefits of using these abstractions and what they offer in comparison to the lower-level GCI API:

  • You may want to create dependencies between tasks, and while you could do this via GCD, you're better off defining them concretely as Operation objects, or units of work, and pushing them onto your own queue. This would allow for maximum reusability since you may use the same pattern elsewhere in an application.
  • The Operation and OperationQueue classes have a number of properties that can be observed, using KVO (Key Value Observing). This is another important benefit if you want to monitor the state of an operation or operation queue.
  • Operations can be paused, resumed, and cancelled. Once you dispatch a task using Grand Central Dispatch, you no longer have control or insight into the execution of that task. The Operation API is more flexible in that respect, giving the developer control over the operation's life cycle.
  • OperationQueue allows you to specify the maximum number of queued operations that can run simultaneously, giving you a finer degree of control over the concurrency aspects.

The usage of Operation and OperationQueue could fill an entire blog post, but let's look at a quick example of what modeling dependencies looks like. (GCD can also create dependencies, but you're better off dividing up large tasks into a series of composable sub-tasks.) In order to create a chain of operations that depend on one another, we could do something like this:

class ViewController: UIViewController {
    var queue = OperationQueue()
    var rawImage = UIImage? = nil
    let imageUrl = URL(string: "https://example.com/portrait.jpg")!
    @IBOutlet weak var imageView: UIImageView!

    let downloadOperation = BlockOperation {
        let image = Downloader.downloadImageWithURL(url: imageUrl)
        OperationQueue.main.async {
            self.rawImage = image
        }
    }

    let filterOperation = BlockOperation {
        let filteredImage = ImgProcessor.addGaussianBlur(self.rawImage)
        OperationQueue.main.async {
            self.imageView = filteredImage
        }
    }

    filterOperation.addDependency(downloadOperation)

    [downloadOperation, filterOperation].forEach {
        queue.addOperation($0)
     }
}

So why not opt for a higher level abstraction and avoid using GCD entirely? While GCD is ideal for inline asynchronous processing, Operation provides a more comprehensive, object-oriented model of computation for encapsulating all of the data around structured, repeatable tasks in an application. Developers should use the highest level of abstraction possible for any given problem, and for scheduling consistent, repeated work, that abstraction is Operation. Other times, it makes more sense to sprinkle in some GCD for one-off tasks or closures that we want to fire. We can mix both OperationQueue and GCD to get the best of both worlds.


The Cost of Concurrency

DispatchQueue and friends are meant to make it easier for the application developer to execute code concurrently. However, these technologies do not guarantee improvements to the efficiency or responsiveness in an application. It is up to you to use queues in a manner that is both effective and does not impose an undue burden on other resources. For example, it's totally viable to create 10,000 tasks and submit them to a queue, but doing so would allocate a nontrivial amount of memory and introduce a lot of overhead for the allocation and deallocation of operation blocks. This is the opposite of what you want! It's best to profile your app thoroughly to ensure that concurrency is enhancing your app's performance and not degrading it.

We've talked about how concurrency comes at a cost in terms of complexity and allocation of system resources, but introducing concurrency also brings a host of other risks like:

  • Deadlock: A situation where a thread locks a critical portion of the code and can halt the application's run loop entirely. In the context of GCD, you should be very careful when using the dispatchQueue.sync { } calls as you could easily get yourself in situations where two synchronous operations can get stuck waiting for each other.
  • Priority Inversion: A condition where a lower priority task blocks a high priority task from executing, which effectively inverts their priorities. GCD allows for different levels of priority on its background queues, so this is quite easily a possibility.
  • Producer-Consumer Problem: A race condition where one thread is creating a data resource while another thread is accessing it. This is a synchronization problem, and can be solved using locks, semaphores, serial queues, or a barrier dispatch if you're using concurrent queues in GCD.
  • ...and many other sorts of locking and data-race conditions that are hard to debug! Thread safety is of the utmost concern when dealing with concurrency.

Parting Thoughts + Further Reading

If you've made it this far, I applaud you. Hopefully this article gives you a lay of the land when it comes to multithreading techniques on iOS, and how you can use some of them in your app. We didn't get to cover many of the lower-level constructs like locks, mutexes and how they help us achieve synchronization, nor did we get to dive into concrete examples of how concurrency can hurt your app. We'll save those for another day, but you can dig into some additional reading and videos if you're eager to dive deeper.




lt

Thunderbolting Your Video Card

When I wrote about The Golden Age of x86 Gaming, I implied that, in the future, it might be an interesting, albeit expensive, idea to upgrade your video card via an external Thunderbolt 3 enclosure.

I'm here to report that the future is now.

Yes, that's right, I paid $500




lt

Family Health Centers of Southwest Florida Website Design Launch

We recently completed a website design and development project for Family Health Centers of Southwest Florida. This National Health Service...continue reading