I wonder if the UICR can be erased and writed by application code, or only can be programmed by nrfutil tool.
The short answer is "no", but it is actually possible.
Each register in UICR can only be written to once, like the rest of the flash. If you want to write to it again, you need to erase the UICR flash page. The UICR holds some important information, such as the reset pin configuration, and the bootloader address, in addition to the customer registers (which I assume you intend to use).
This means that if you want to update the UICR during runtime, you need to erase the UICR. If you loose power at the wrong time, this means that your device may be bricked. Therefore it is not recommended to update UICR during runtime, although it is physically possible.
If you enable readback protection (APPROTECT), then it is not possible to update the UICR during runtime, because this register is part of the UICR, so you can't turn it off without erasing the entire flash of the nRF.
So what do you intend to use the UICR for? Do you intend to write to it once, or do you intend to update it during the lifetime of the product? If you intend to write to it once, it may be suitable, but if you intend to update it during the runtime, then I would suggest looking into the FDS module instead of using the UICR.