PhotoPicker发现错误:Error Domain = PlugInKit Code = 13


118

我正在尝试在UIImageView中显示照片库中的图像

完整的错误是:

2017-06-09 21:55:59.063307 + 0200 firstapp2.0 [12873:1120778] PhotoPicker发现错误:Error Domain = PlugInKit Code = 13“查询已取消” UserInfo = {NSLocalizedDescription =查询已取消}

我的代码如下:

import UIKit

class ViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate{

    @IBOutlet weak var pic: UIImageView!
    @IBOutlet weak var text: UILabel!

    var chosenImage : UIImage!

    override func viewDidLoad() {
        super.viewDidLoad()        
        pic.isUserInteractionEnabled = true;
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [AnyHashable: Any]) {
        var chosenImage = info[UIImagePickerControllerEditedImage]
        self.pic!.image = chosenImage as! UIImage
        picker.dismiss(animated: true, completion: nil)
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }

    @IBAction func tap(_ sender: Any) {        
        self.text.text = "Kreason"
        let imagePicker = UIImagePickerController()    
        imagePicker.delegate = self        
        imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
        imagePicker.allowsEditing = false    
        self.present(imagePicker, animated: true, completion: nil)
    }
}

11
我遇到了同样的错误。您正在使用Xcode 9 beta,iOS 11吗?
约翰·约翰(John

4
这曾经可以工作...然后iOS 11 Beta 4突然给了我这个错误。太奇怪了。
user2153553

2
我遇到同样的错误,我的实现在obj-c中。此错误消息与在Objective-c的UIImagePicker委托方法中返回的信息字典的类型转换无关:- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info字典值在obj-c中被转换为id。我还实现了访问用户照片库的授权请求和处理:仍然收到错误消息。我在info.plist文件中添加了隐私条目供用户的照片库使用。
valeCocoa

2
我收到了当前的错误,但是它并不能阻止我从库中获取图像并在以后使用它
。.– shokuroff

3
我尝试了所有答案中的所有建议,但无济于事。
Nicolas Miari

Answers:


39

您需要明确的Objective-C参考: @objc

@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    image = chosenImage
    self.performSegue(withIdentifier: "ShowEditView", sender: self)
    dismiss(animated: true, completion: nil)
}

6
为我工作。我最近更新了Swift 4和Xcode 9,并解决了它。
user3144836

3
为我工作。迁移到Swift 4.0后需要。
mayankk2308 '17

4
不起作用 我打电话后发生了这个错误dismiss
Kimi Chiu

奇怪。这对我有用,但是xcode将其标记为警告,并期望签名:`实例方法'imagePickerController(:didFinishPickingMediaWithInfo :)'几乎与协议'UIImagePickerControllerDelegate'的可选要求'imagePickerController(:didFinishPickingMediaWithInfo :)' 相匹配使得'imagePickerController(_ :didFinishPickingMediaWithInfo :)'私有以将此警告静音
黑暗城堡

@DarkCastle您需要将函数写入extension [your class name]类之外的块中。
Prometheos II,

18

我找到了这个解决方案。由于以下两个原因,导致出现此错误。

  1. 首先,我们需要调用此方法进行授权

授权码

func checkPermission() {
  let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus() switch photoAuthorizationStatus {
    case .authorized: print("Access is granted by user")
    case .notDetermined: PHPhotoLibrary.requestAuthorization({
      (newStatus) in print("status is \(newStatus)") if newStatus == PHAuthorizationStatus.authorized { / do stuff here */ print("success") }
    })
    case .restricted: / print("User do not have access to photo album.")
    case .denied: / print("User has denied the permission.")
  }
}
  1. 正确的方法调用 didFinishPickingMediaWithInfo

错误:

private func imagePickerController( picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
} 

@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
} 

我希望此解决方案可以帮助您解决此错误。

如果对您有用,请别忘了将其标记为正确,这将有助于其他人找到正确的方法。


小白PSA:PHPhotoLibrary是斯威夫特的照片模块
布雷登霍尔特

不起作用 我致电后发生错误picker.dismiss(animated: true, completion: nil)
ForceBru

17

我找到了!它试图告诉您您没有“照片”的#import <Photos/Photos.h>授权。例如,需要在Objective-C中包含和请求这样的授权。

希望这可以节省您一些时间。我花了整整两天的时间进行调试!

[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    switch (status) {
        case PHAuthorizationStatusAuthorized:
            NSLog(@"PHAuthorizationStatusAuthorized");
            break;
        case PHAuthorizationStatusDenied:
            NSLog(@"PHAuthorizationStatusDenied");
            break;
        case PHAuthorizationStatusNotDetermined:
            NSLog(@"PHAuthorizationStatusNotDetermined");
            break;
        case PHAuthorizationStatusRestricted:
            NSLog(@"PHAuthorizationStatusRestricted");
            break;
    }
}];

我相信有人可以告诉您如何在Swift中执行相同的操作。


1
确保包括#import <Photos / Photos.h>
Robert Wohnoutka '17

6
这没有解决我的问题。
FI12

1
我在控制台中收到以下消息“从私人有效用户设置中读取。发现扩展时遇到错误:Error Domain = PlugInKit Code = 13“查询已取消” UserInfo = {NSLocalizedDescription =查询已取消}”。它没有解决问题。
Biranchi '18年

15

尝试了一些组合响应,但没有成功。

使用Swift 4,我发现我需要确保实现以下两项以确保选择了图像并将其放置到选择器中(请注意,发现扩展时遇到“ [发现]错误:

错误域= PlugInKit代码= 13“查询已取消” UserInfo = {NSLocalizedDescription =查询已取消}“

消息仍显示在控制台中,但不会阻止您添加图像。也许这是一条消息,导致选择器被解雇了?

1)的委托UIImagePickerController(UIImagePickerControllerDelegate & UINavigationControllerDelegate)?如此需要明确添加UINavigationControllerDelegate作为协议之一:

class ViewController:UIViewController, UIImagePickerControllerDelegate, 
    UINavigationControllerDelegate { .... }. 

2)确保info.plist设置了Privacy - Photo library Usage Description键和字符串值。

当然,你需要确保你创建UIImagePickerController并设置其委托等于selfViewDidLoad()

class ViewController:UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 
    let imagePickerController = UIImagePickerController()
    override func viewDidLoad() {
        super.viewDidLoad()
        imagePickerController.delegate = self
    }
    ...
}

4
我在我的项目中拥有所有这些..仍然行不通
Mohamed Lee

谢谢,我错过了viewDidLoad()中的设置委托
Arshad Shaik

11

我已解决此问题,将下面的函数调用到viewdidload或viewWillAppear或viewDidAppear中,以检查您的应用程序的权限。

func checkPermission() {
        let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
        switch photoAuthorizationStatus {
        case .authorized:
            print("Access is granted by user")
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization({
                (newStatus) in
                print("status is \(newStatus)")
                if newStatus ==  PHAuthorizationStatus.authorized {
                    /* do stuff here */
                    print("success")
                }
            })
            print("It is not determined until now")
        case .restricted:
            // same same
            print("User do not have access to photo album.")
        case .denied:
            // same same
            print("User has denied the permission.")
        }
    }

并且要使用上述方法,请不要忘记import Photos在类顶部添加。


11

XCODE 10.1 / SWIFT 4.2:

  1. 添加所需的权限(提到的其他权限)

  2. 实现此委托函数:

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
        if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            self.imgView.contentMode = .scaleAspectFit
            self.imgView.image = pickedImage
        }
    
        dismiss(animated: true, completion: nil)
    }

1
在Swift 4x上使用imagePickerController func的真实方法
Samet Sazak

10

*在Swift 3中缺少DELEGATE *

在我的情况下,所有设置都是正确的:
1-委托(UIImagePickerControllerDelegate,UINavigationControllerDelegate);
2-权限已验证;
3-Plist已经完成;
4-我读过《答案》中的所有内容;

但是我忘了实现pickerview.delegate = selfviewDidLoad 因为我从另一个viewController复制并粘贴了,忘记了!

希望对您有所帮助,请先查看您的复制/粘贴!!!


谢谢,我一直在努力挣扎,我错过了“ UINavigationControllerDelegate”,您终于保存了,谢谢
Sakthimuthiah 19-10-10

很高兴为您提供帮助:)
Daniel Arantes Loverde

8

这可能不是最直接有用的答案-但希望它将有所帮助!我有99%的把握确定此特定的错误消息实际上并未将您引向真正的问题。我花了几个小时才解决这个同样的问题。

1)启动选择器时,我已获得将照片打印到控制台的授权; 2)我可以足够轻松地导航和选择照片; 3)取消选择器后,我回到视图中时,按钮图像未使用新照片进行更新...,而我对问题的唯一提示是收到的消息完全相同。

原来我是在ViewWillAppear中而不是ViewDidLoad中对占位符图像进行硬编码。每次取消选择器时,都会调用ViewWillAppear并将我选择的图像替换为我的硬编码图像。我已经解决了这个问题,而且确实可以确定-一切现在都正常工作了。每次从选择器返回时,我仍然看到该错误消息。

我建议您在ImagePicker以外的地方寻找问题,您可能会找到它。


7

如果您尚未这样做,请尝试

产品>方案>编辑方案>环境变量 OS_ACTIVITY_MODE: disable

它解决了我的问题。


23
这样可以抑制错误消息,但不能解决其原因。它还会禁止其他系统消息以及来自的任何消息NSLog
约翰·蒙哥马利

6
这不会“解决”问题,只是使其不可见。非常不好的做法。
zeeshan

这等效于将污物藏在地毯下
shiv 19/09/17

7

这可以解决Swift 4中的问题:

更改下面的代码

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {}

对此:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {}


Swift 4.2 update:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){}

我的错误看起来像这样:发现扩展时遇到的错误:错误Domain = PlugInKit Code = 13“查询已取消” UserInfo = {NSLocalizedDescription =查询已取消}这解决了我的问题,尽管我不能说这是否有助于OP 。谢谢:)
阿格里帕

6

当我尝试从选择器回调中呈现另一个控制器时,我得到了相同的消息imagePickerController。对我有用的解决方案是将我的代码从picker dismiss方法中移到完成回调中

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        picker.dismiss(animated: true) {
            if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
                let cropController:CropViewController = CropViewController(croppingStyle: .circular, image: pickedImage)
                cropController.delegate = self
                self.present(cropController, animated: true, completion: nil)
            }
        }
    }

伟大的答案,你救了我的时间👍🏼
编码器ACJHP

工作出色!认为这是处理Swift 4.x中选择器错误的正确方法。
shiv

4

确保您同时继承了以下子类:UIImagePickerControllerDelegate, UINavigationControllerDelegate

另外,请记住设置委托:

let picker = UIImagePickerController()
picker.allowsEditing = true
picker.sourceType = .photoLibrary
picker.delegate = self  //Don't forget this line!
self.present(picker, animated: true, completion: nil)

对此来源表示感谢。


picker.delegate =自我-是我的情况!谢谢。
阿列克谢·切卡诺夫

4

找到解决此问题的方法使我永远受益。看来问题在于找不到UIImagePickerControllerDelegate的函数imagePickerController。如果您已经正确设置了委托,并且在升级到Swift 4之后它停止工作,则问题可能是您没有使用@objc使其无法被Objective-C访问,这是Swift 4之后所必需的。

它一定要是:

@objc func imagePickerController(...

代替

func imagePickerController(...

它会产生错误Objective-C method 'imagePickerController:didFinishPickingMediaWithInfo:' provided by method 'imagePickerController(_:didFinishPickingMediaWithInfo:)' conflicts with optional requirement method 'imagePickerController(_:didFinishPickingMediaWithInfo:)' in protocol 'UIImagePickerControllerDelegate'
Nico Neill

确实,这是解决问题的方法!
Maria Ortega,

@NicoNeill是否将功能添加到extension块中?
Prometheos II

4

设置图像时通过设置1秒延迟来解决此问题。

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {

        picker.dismiss(animated: false, completion: nil)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
            self.discussionImage.image = image
        })
    }
}

3

确保internal func在开头添加小写字母_ picker: UIImagePickerController…,然后在括号后面添加小写字母(然后从更改AnyObjectAny]。
请检查以下代码:

internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {

        userPhoto.image = pickedImage

    }

    self.dismiss(animated: true, completion: nil)
}

3

这让我很困惑,但是下面链接的答案对我有用。错误消失,图像按预期显示

像上面的答案之一一样,您必须在功能之前(_ picker...也必须具有@objc功能。

@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
...
}

https://forums.developer.apple.com/thread/82105


2

这解决了我的错误:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
    addPhotoBtn.setImage(pickedImage, for: .normal)
    dismiss(animated: true, completion: nil)


}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: nil)

}

2

请按以下步骤进行检查:

  1. 导入照片
  2. 可以访问相册:

    func authorizeToAlbum(completion:@escaping (Bool)->Void) {
    
    if PHPhotoLibrary.authorizationStatus() != .authorized {
        NSLog("Will request authorization")
        PHPhotoLibrary.requestAuthorization({ (status) in
            if status == .authorized {
                DispatchQueue.main.async(execute: {
                    completion(true)
                })
            } else {
                DispatchQueue.main.async(execute: {
                    completion(false)
                })
            }
        })
    
    } else {
        DispatchQueue.main.async(execute: {
            completion(true)
        })
    }
    }
  3. 目前的UIImagePickerController

    self.authorizeToAlbum { (authorized) in
        if authorized == true {
            let picker = UIImagePickerController()
            picker.delegate = self
            picker.allowsEditing = false
            picker.sourceType = .photoLibrary
    
            self.present(picker, animated: true, completion: nil)
        }
    }
  4. 关键步骤,确保委托方法严格遵循

    // MARK: - UIImagePickerControllerDelegate Methods
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
        self.pickedImage = pickedImage
        if let finalImage = handleImage(originalImage: self.pickedImage!, maskImage: self.maskImage!) {
            self.imageView.image = finalImage
        }
    }
    
    dismiss(animated: true, completion: nil)
    }

2

这就是我所做的,它解决了我的问题。

  • 添加@objc
  • 添加内部
  • 在imagePicker之前添加_
  • 确保您使用的是Any而不是AnyObject

希望这可以帮助!


嗯,internal是默认值;我想知道指定它有什么不同...
Nicolas Miari

2

在我的情况下,出现此错误是因为我在未首先验证用户是否允许访问图像的情况下提供了图像选择器控制器。在我的代码的其他地方,用户已授予许可,所以我认为我需要做的就是导入照片。但是,由于当时他们“可能”没有在应用程序中授予权限,就在我提出图像选择器控制器之前为我添加了此权限(也导入了Photos)。

// request photos permission if permission has not been granted
    if PHPhotoLibrary.authorizationStatus() != PHAuthorizationStatus.authorized {
        PHPhotoLibrary.requestAuthorization({ (status: PHAuthorizationStatus) in

        })
    }

如果这个答案似乎是多余的,我深表歉意,但是我不得不从几个不同的答案中拼凑起来,以使我的解决方案有效。也许这会帮助其他使用Swift 4的人。


2

使用此代码

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])

2

即使看起来像是无害的Apple调试消息,此“ Error Domain = PlugInKit Code = 13”错误也使很多人感到困惑。我在选择要在UI中设置的图像时遇到了麻烦,并以为该错误是问题所在,但是有些微妙。

我将图像选择器控制器放在与呈现它的视图控制器不同的文件中。

MyViewController.swift

class MyViewController: UIViewController {
    @IBOutlet weak var profileImage: UIImageView!

    ...
}

extension MyViewController: ImagePickerDelegate {
    func didSelect(image: UIImage?) {
        self.profileImage.image = image
    }
}

ImagePicker.swift

open class ImagePicker: NSObject {
    ...
    private func pickerController(_ controller: UIImagePickerController, didSelect image: UIImage?) {
        controller.dismiss(animated: true, completion: {self.delegate?.didSelect(image: image)}
        )
    }
}

大多数教程和答案的完成度都设置为零。但是,如果将补全设置为nil并分别调用委托的didSelect方法,则会调用该方法,但未设置图像,因此请确保使用dismiss补全。

再说一次,我知道这个答案可能与原始问题没有直接关系,但是我感觉很多人都来这里讨论这个问题,而且给定的解决方案也无济于事。原因是大多数给出答案的人都将其图像选择器控制器与主视图控制器放在同一类中,因此不需要使用补全。


这正是我所需要的。谢谢!
AJ Hernandez

1

当您尚未Info.plist文件中配置照片库的使用权限时,也会发生该错误。

您需要添加Privacy - Photo Library Usage DescriptionInfo.plist同一个字符串,当您的应用首次尝试访问该用户的图片库时将出现。

最终的Info.plist调整应如下所示: 在此处输入图片说明


1

我有相同的错误,并通过以下方式修复了它:

以不同的方式获取图像对象取决于UIImagePickerController allowEditing是true还是false

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    if isImagePickerAllowEditing {
        sourceImage = info[UIImagePickerControllerEditedImage] as? UIImage
    } else {
        sourceImage = info[UIImagePickerControllerOriginalImage] as? UIImage
    }

    ....

}

当然,请像上面的评论一样,先申请允许访问图片库。


1

在我这边,UINavigationControllerDelegate代表不见了。

class YourViewController:UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate


0

我遇到了同样的问题。上述建议对我没有任何帮助。但是,我通过明确地调用picker.dismiss并在此之后发布而解决了它。我不清楚为什么我要打这样的电话,但这对我有用。

   @objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        print("Image picked")
        picker.dismiss(animated: true, completion: nil)
        dismiss(animated: true) {
            print("dismissed")
             self.delegate?.presentEditor(img: (info[UIImagePickerControllerOriginalImage] as? UIImage)!, id: self.id!)
    }

}

0

我阅读了所有这些答案,并在这里做了一些修改,不需要删除,这对我有用,谢谢其他在这里回答的人。

    @objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

      print("########### media picked")
      picker.dismiss(animated: true, completion: nil)
      let img = (info[UIImagePickerControllerOriginalImage] as? UIImage)!
      //set img -picked image to "profileImage" UIimageView
      //use image here
       self.profileImage.image = img
       }
    }

0

我找到了IMage PickerView的解决方案。

@IBOutlet weak var myImageView: UIImageView!

var imagePicker = UIImagePickerController()


  @IBAction func selectImage(_ sender: Any) {

        let myPickerController = UIImagePickerController()
        myPickerController.delegate = self;
        myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary

        self.present(myPickerController, animated: true, completion: nil)

    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        print(info)

        var selectedImageFromPicker: UIImage?

        if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage
        {
            selectedImageFromPicker = editedImage as! UIImage


        }else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage{

            selectedImageFromPicker = originalImage as! UIImage


        }

        dismiss(animated: true, completion: nil)

        if var selectedImage = selectedImageFromPicker
        {
            myImageView.image = selectedImage
        }

    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }

0

单击imageView从照片库中加载图像,并在同一imageview上显示预览。迅速4

 let imagePicker = UIImagePickerController()
        @IBOutlet weak var userImage: UIImageView! 

     override func viewDidLoad() {
                super.viewDidLoad()
                 imagePicker.delegate = self
                let tap = UITapGestureRecognizer(target: self, action: #selector(SignUpViewController.click))
                userImage.addGestureRecognizer(tap)
                userImage.isUserInteractionEnabled = true
            }

            @objc func click()
            {
                imagePicker.allowsEditing = false
                imagePicker.sourceType = .photoLibrary
                present(imagePicker, animated: true, completion: nil)
            }


            @objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
                if  let chosenImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
                userImage.contentMode = .scaleAspectFit
                userImage.image = chosenImage
                }
                dismiss(animated: true, completion: nil)
            }

            func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
                dismiss(animated: true, completion: nil)
            }

0

Swift 4.2Xcode 10.0上也有同样的问题。尽管图像选择器工作正常,但Xcode在控制台上显示了此错误。要摆脱这种情况:

  • 在Xcode菜单上,产品>方案>编辑方案
  • 选择“运行”标签,然后选择“参数”
  • 在“环境变量”部分,添加名称为OS_ACTIVITY_MODE且值禁用的变量

好吧...不是真的...对我来说它显示了此错误,但是didFinishPickingMediaWithInfo方法未调用...所以我需要启用此值才能看到此错误
Mohamed Lee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.