#StackBounty: #ios #swift #avfoundation What AVCaptureDevice does Camera.app use?

Bounty: 50

I have a camera in my app. It’s been carefully implemented following a lot of documentation, but it still has a major annoyance; the field of view is significantly smaller than the stock camera app. Here’s two screenshots taken at approx the same distance for reference. My app is on the right, showing the entire preview stream from the camera.

enter image description here

Apple docs suggest using AVCaptureDevice.default or AVCaptureDevice.DiscoverySession, and my app uses the former;

AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)

I’ve tried many of the different capture devices, and none of them give me the same wide preview as the stock Camera app.

What am I doing wrong?


Get this bounty!!!

#StackBounty: #swift #agora.io Mixing Audio without ducking audio

Bounty: 50

I’m trying to mix audio sources such that there is no audio ducking. I’m using Agora, and the use case I’m trying to solve is having an audio call ongoing in the background while also playing music and/or listening to app audio, without any audio ducking. Audio ducking is when the audio is lowered and distorted slightly to help with the listening of another audio session. Can I have unducked audio and audio mixing with Agora (or iOS for that matter)?

I have tried the following code after beginning an Agora audio session. I have also tried wrapping it in a DispatchQueue.main.async closure, but still no luck.


// I have also tried this code with this block uncommented
// do {
//     try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
//
// } catch let activationError {
//     print(activationError)
//     print(activationError.localizedDescription)
// }


let audioSession = AVAudioSession.sharedInstance()
do {
    try audioSession.setCategory(
        AVAudioSession.Category.playAndRecord,
        mode: AVAudioSession.Mode.voiceChat,
        options: [.allowBluetoothA2DP, .allowBluetooth, .mixWithOthers, .allowAirPlay]
    )
} catch let setCategoryError {
    print(setCategoryError)
    print(setCategoryError.localizedDescription)
}

do {
    try audioSession.setActive(true, options: .notifyOthersOnDeactivation)

} catch let activationError {
    print(activationError)
    print(activationError.localizedDescription)
}


Get this bounty!!!

#StackBounty: #ios #swift #uitextview UITextView – Enable dictation alert disappears quickly

Bounty: 50

I’ve text view. When keyboard is showing and I tap on dictation icon it shows Enable Dictation window and then disappears quickly on a device. On simulator it works on some and not on others. I’m not sure why it’s happening. I’ve searched but can’t find any single result with similar issue.

It’s not just with text view, it also happens on search bar.

This issue doesn’t happen on iPhone X device.

Any clue on why it’s happening and how to fix it or what to look for?

I also see following error:

[Utility] +[AFAggregator logDictationFailedWithError:] Error Domain=kAFAssistantErrorDomain Code=221 "(null)" UserInfo={NSUnderlyingError=0x2832cf8a0 {Error Domain=NSOSStatusErrorDomain Code=561017449 "(null)"}}
!!! _NSLayoutTreeGetBaselineOffsetForGlyphAtIndex invalid glyph index 


Get this bounty!!!

#StackBounty: #ios #swift #xcode #uitableview #uicollectionview Passing information from a collection view to a tableview

Bounty: 50

Right now I have a table view that is an extension of a collection view.

Here is a picture of the storyboard.
enter image description here

The main premise of the app is similar to Apple Maps. I would like for a collectionView cell to be selected and then for the viewController to display a tableView that has all of the respected items from that category.

Here is my code for the collectionView.

 class ContentViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

let imageArray = [UIImage(named: "image 1"), UIImage(named: "image 2"), UIImage(named: "image 3")]

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return imageArray.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
    cell.mapIconImage.image = imageArray[indexPath.row]
    cell.mapIconLabel.text! = imageNameArray[indexPath.row]
    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    performSegue(withIdentifier: "ShowTableViewPlaces", sender: self)
}

class CustomCell: UICollectionViewCell {

@IBOutlet weak var mapIconImage: UIImageView!
@IBOutlet weak var mapIconLabel: UILabel!

}

Here is the code so far for the tableView.

import UIKit

struct PlacesInTableView {
var name: String

init(name: String) {
    self.name = name
}
}

class MapItemsTableViewController: UITableViewController {

var image1InTableView = [PlacesInTableView(name: "place 1"),
    PlacesInTableView(name: "place 2"),
    PlacesInTableView(name: "place 3")
]

var image2InTableView = [PlacesInTableView(name: "place 1")
]

var image3InTableView = [PlacesInTableView(name: "place 1"),
    PlacesInTableView(name: "place 2")
]

When a collection view is selected, I would like all of the locations in that respected category to occupy the contents of the tableview. How would I go about passing data from the collection view cell to a new tableView?


Get this bounty!!!

#StackBounty: #swift MVVM-C Swift with Dependency injection

Bounty: 50

I want to create a MVVM-C project, but also adequately test it. Naturally I want to create such a project that can access a Network Service.

I’ve written the whole thing (and have tests in this GitHub Repo https://github.com/stevencurtis/MVVM-CDependency)

Any comments or thoughts on this approach?

DependencyFactory:

protocol Factory {
    var networkManager: HTTPManagerProtocol { get }
    func makeInitialViewModel(coordinator: Coordinator) -> InitialViewModel
    func makeInitialView(viewModel: InitialViewModel) -> InitialView
    func makeDetailView(viewModel: DetailViewModel) -> DetailView
    func makeDetailViewModel(coordinator: Coordinator) -> DetailViewModel
}

// replace the DependencyContainer for tests
class DependencyFactory: Factory {
    var networkManager: HTTPManagerProtocol = HTTPManager()

    // should not return an optional at the end of this project
    func makeInitialCoordinator() -> ProjectCoordinator {
        let coordinator = ProjectCoordinator(factory: self)
        return coordinator
    }

    func makeInitialView(viewModel: InitialViewModel) -> InitialView {
        let view = InitialView()
        return view
    }

    func makeInitialViewModel(coordinator: Coordinator) -> InitialViewModel {
        let viewModel = InitialViewModel(coordinator: coordinator, networkManager: networkManager)
        return viewModel
    }

    func makeDetailView(viewModel: DetailViewModel) -> DetailView {
        let view = DetailView()
        return view
    }

    func makeDetailViewModel(coordinator: Coordinator) -> DetailViewModel {
        let viewModel = DetailViewModel(coordinator: coordinator, networkManager: networkManager)
        return viewModel
    }
}

A basic HTTPManager (that doesn’t really touch the network, but you get the point!)

protocol HTTPManagerProtocol {
    func get(url: URL, completionBlock: @escaping (Result<Data, Error>) -> Void)
}

class HTTPManager: HTTPManagerProtocol {
    public func get(url: URL, completionBlock: @escaping (Result<Data, Error>) -> Void) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            let data = Data("The Data from HTTPManager".utf8)
            completionBlock(.success(data))
        }
    }
}

Project Coordinator

protocol Coordinator: class {
    func start(_ navigationController: UINavigationController)
    func moveToDetail()
}

class ProjectCoordinator: Coordinator {
    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController?

    private var factory: Factory

    init(factory: Factory) {
        self.factory = factory
    }

    func start(_ navigationController: UINavigationController) {
        let vc = InitialViewController(factory: factory, coordinator: self)
        self.navigationController = navigationController
        navigationController.pushViewController(vc, animated: true)
    }

    func moveToDetail() {
        let vc = DetailViewController(factory: factory, coordinator: self)
        navigationController?.pushViewController(vc, animated: true)
    }
}

InitialModel

struct InitialModel : Codable {
    let dataString : String
}

InitialView

final class InitialView: UIView {

    let traverseButton = UIButton(type: .custom)
    let networkButton = UIButton(type: .custom)
    let networkLabel = UILabel()
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setup() {
        self.backgroundColor = .red
        traverseButton.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
        traverseButton.setTitle("Go to Detail", for: .normal)
        traverseButton.setTitleColor(.black, for: .normal)
        traverseButton.isUserInteractionEnabled = true

        self.addSubview(traverseButton)
        traverseButton.translatesAutoresizingMaskIntoConstraints = false
        traverseButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        traverseButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

        networkButton.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
        networkButton.setTitle("Make Network Call", for: .normal)
        networkButton.setTitleColor(.black, for: .normal)
        networkButton.isUserInteractionEnabled = true

        self.addSubview(networkButton)
        networkButton.translatesAutoresizingMaskIntoConstraints = false
        networkButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        networkButton.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 100).isActive = true

        networkLabel.text = "No network calls made"
        networkLabel.backgroundColor = .purple
        self.addSubview(networkLabel)

        networkLabel.translatesAutoresizingMaskIntoConstraints = false
        networkLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        networkLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 200).isActive = true
        networkLabel.widthAnchor.constraint(equalToConstant: 300).isActive = true
        networkLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true
    }

    func setNetworkLabel(text: String){
        networkLabel.text = text
    }

}

InitialViewController

class InitialViewController: UIViewController {
    private var coordinator: Coordinator?
    private var factory: Factory?

    var intialView: InitialView?

    lazy var viewModel: InitialViewModel? = {
        return factory?.makeInitialViewModel(coordinator: coordinator!)
    }()

    init(factory: Factory, coordinator: Coordinator) {
        self.factory = factory
        self.coordinator = coordinator
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        if let initialView = factory?.makeInitialView(viewModel: viewModel!) {
            initialView.traverseButton.addTarget(self, action: #selector(traverseButton(_:)), for: .touchDown)
            initialView.networkButton.addTarget(self, action: #selector(networkButton), for: .touchDown)
            self.intialView = initialView
            self.view = initialView
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func traverseButton(_ sender: UIButton) {
        coordinator?.moveToDetail()
    }

    @IBAction func networkButton(_ sender: UIButton) {
        viewModel?.fetchData(completion: { data in
            switch data {
            case .failure: fatalError()
            case .success(let data):
                if let data = data.first {
                    self.intialView?.setNetworkLabel(text: data.dataString)
                }
            }
        })
    }

}

InitialViewModel

class InitialViewModel {
    private var networkManager: HTTPManagerProtocol?
    init(coordinator: Coordinator?, networkManager: HTTPManagerProtocol) {
        self.networkManager = networkManager
    }

    func fetchData(completion: @escaping (Result<[InitialModel], Error>) -> Void) {
        networkManager?.get(url: URL(string: "NOURL")!, completionBlock: { result in
            DispatchQueue.main.async {
                switch result {
                case .failure:
                    completion(.failure(NSError()))
                case .success(let data):
                    if let str = String(data: data, encoding: .utf8) {
                        let model = InitialModel(dataString: str)
                        completion(.success([model]))
                    }
                }
            }
        })
    }
}

DetailViewController

class DetailViewController: UIViewController {
    weak var coordinator: Coordinator?
    private var factory: Factory?

    var detailView: DetailView?

    lazy var viewModel: DetailViewModel? = {
        return factory?.makeDetailViewModel(coordinator: coordinator!)
    }()

    init(factory: Factory, coordinator: Coordinator) {
        self.factory = factory
        self.coordinator = coordinator
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        if let detailView = factory?.makeDetailView(viewModel: viewModel!) {
            self.detailView = detailView
            self.view = detailView
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

DetailViewModel

class DetailViewModel {
    private var networkManager: HTTPManagerProtocol?
    init(coordinator: Coordinator?, networkManager: HTTPManagerProtocol) {
        self.networkManager = networkManager
    }
}

DetailView

final class DetailView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setup() {
        self.backgroundColor = .blue
    }
}

The whole thing is on GitHub – all suggestions welcome! https://github.com/stevencurtis/MVVM-CDependency


Get this bounty!!!

#StackBounty: #ios #swift #autofill #aswebauthenticationsession How to get Password AutoFill to work with ASWebAuthenticationSession?

Bounty: 200

I have a sample HTML form that follows the password auto-fill requirements. When navigating to the web page without the app, using the built-in Safari app, the native Password AutoFill dialogs for the login and signup forms correctly show:

enter image description here

However, when viewed within the app, the same flow does not trigger the dialog in neither the login or signup submission. It simply dismisses the login/signup screen without any error.

This is how my view controller looks like:

class ViewController: UIViewController {

    @IBAction func didTapLoginButton() {
        let session = ASWebAuthenticationSession(
            url: URL(string: "https://example.com/login.html")!,
            callbackURLScheme: "customscheme") {
                print($0, $1)
        }

        session.prefersEphemeralWebBrowserSession = true
        session.presentationContextProvider = self
        session.start()
    }
}

extension ViewController: ASWebAuthenticationPresentationContextProviding {

    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        view.window!
    }
}

Is there a way to make the Password AutoFill to work with the mobile app via ASWebAuthenticationSession? I also tried SFSafariViewController but same issue. I have a sample iOS app here. Any help or experience is greatly appreciated!


Get this bounty!!!

#StackBounty: #ios #swift #mux How to upload video file on Mux

Bounty: 50

I’m trying to upload a recorded video file and regular video file from the photos gallery on Mux server. I am receiving this error message:

Error:
The input file was not a valid video or audio file [error type: invalid_input] all the time.

I tried uploading via a raw request and Alamofire. Also, I tried encoding the file to MP4 before sending it.

The code looks something like this:

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

  let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as! URL
  AF.upload(multipartFormData: { (multipartFormData) in
    multipartFormData.append(videoURL, withName: "video", fileName: "video.mov", mimeType: "video/mov")
  }, with: urlRequest).response { (response) in

  }
}

I tried converting videoURL to data using:

Data(url: videoURL)
InputStream(url: videoURL)

I know that in cURL I should have --data-binary 'Video.mp4', which, on Android works, but I don’t know how to convert the file to data-binary (byte) on iOS.


Get this bounty!!!

#StackBounty: #swift #macos #datepicker #maccatalyst DatePicker on Mac not saving date until return key is pressed

Bounty: 50

I’m adapting my iPad app to Mac with Mac Catalyst and am having a problem with the datePicker (it has a datePickerMode of time). On iPad the datePicker is a wheel and whenever the user scrolls on the date picker the dateChanged action is fired. But on Mac the date picker is not a scroller and is instead a type of text input. I can type and change all the time values on Mac, but the dateChanged action won’t be fired until I press the return key.

I would like to get the dateChange action fired whenever a user is entering in a time. How can I do this? I tried adding different targets to the datePicker but nothing work.

I actually prefer to have the date scroller on the Mac so if anyone knows how to do this instead I would greatly appreciate it (I looked all over the internet for this and found nothing)!

Here’s my code:

class DateVC: UIViewController {
     @IBOutlet weak var datePicker: UIDatePicker!

     override func viewDidLoad() {
          super.viewDidLoad()

          //Just show the time
          datePicker.datePickerMode = .time
    }

     //Action connected to datePicker. This is not called until I press enter on Mac
     @IBAction func datePickerChanged(_ sender: Any) {
        //do actions
     }

}


Get this bounty!!!