Swift: netServiceBrowser didRemoveService MacOSX 10.13 - swift

I am trying to run a NetServiceBrowser. It will detect a new ZeroConf device as soon as it appears on the network. It doesn't however detect when the device is removed from the network.
netServiceBrowser(aNetServiceBrowser: NetServiceBrowser!, didRemoveService aNetService: NetService!, moreComing: Bool) is never called.
Am I missing something?
class BonjourDiscovery: NSObject, NetServiceBrowserDelegate, NetServiceDelegate
{
var browser: NetServiceBrowser
var services = [NetService]()
static let instance = BonjourDiscovery()
override init()
{
browser = NetServiceBrowser()
services = []
}
func startDiscovery()
{
browser.delegate = self
browser.searchForServices(ofType: "_smb._tcp.", inDomain: "")
}
func stopDiscovery()
{
browser.stop()
}
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool)
{
print ("Found:" + service.name)
self.services.append(service)
}
func netServiceBrowser(aNetServiceBrowser: NetServiceBrowser!, didRemoveService aNetService: NetService!, moreComing: Bool)
{
print ("Removed:" + aNetService.name)
if let index = services.index(of: aNetService)
{
services.remove(at: index)
}
}
}

For completeness I have posted the full answer, correcting the didRemoveService function definition (Thanks to Martin R):
class BonjourDiscovery: NSObject, NetServiceBrowserDelegate, NetServiceDelegate
{
var browser: NetServiceBrowser
var services = [NetService]()
static let instance = BonjourDiscovery()
override init()
{
browser = NetServiceBrowser()
services = []
}
func startDiscovery()
{
browser.delegate = self
browser.searchForServices(ofType: "_smb._tcp.", inDomain: "")
}
func stopDiscovery()
{
browser.stop()
}
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool)
{
print ("Found:" + service.name)
self.services.append(service)
}
func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool)
{
print ("Removed:" + service.name)
if let index = services.index(of: service)
{
services.remove(at: index)
}
}
}

Related

IGListKitSections doesn't get deallocated

I have a problem with IGListKit sections deallocating. Trying to debug the issue with Xcode memory graph.
My setup is AuthController -> AuthViewModel -> AuthSocialSectionController -> AuthSocialViewModel and some other sections.
AuthController gets presented from several parts of the app if user is not logged in. When I tap close, AuthViewModel and AuthController gets deallocated, but it's underlying sections does not. Memory graph shows nothing leaked in this case, but deinit methods doesn't get called.
But when I'm trying to authorize with social account (successfully) and then look at the memory graph, it shows that sections, that doesn't get deallocated like this:
In this case AuthViewModel doesn't get deallocated either, but after some time it does, but it can happen or not.
I checked every closure and delegate for weak reference, but still no luck.
My code, that I think makes most sense:
class AuthViewController: UIViewController {
fileprivate let collectionView: UICollectionView = UICollectionView(frame: .zero,
collectionViewLayout: UICollectionViewFlowLayout())
lazy var adapter: ListAdapter
= ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0)
fileprivate lazy var previewProxy: SJListPreviewProxy = {
SJListPreviewProxy(adapter: adapter)
}()
fileprivate let viewModel: AuthViewModel
fileprivate let disposeBag = DisposeBag()
init(with viewModel: AuthViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
hidesBottomBarWhenPushed = true
setupObservers()
}
private func setupObservers() {
NotificationCenter.default.rx.notification(.SJAProfileDidAutoLogin)
.subscribe(
onNext: { [weak self] _ in
self?.viewModel.didSuccessConfirmationEmail()
self?.viewModel.recoverPasswordSuccess()
})
.disposed(by: disposeBag)
}
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
// MARK: - Private
#objc private func close() {
dismiss(animated: true, completion: nil)
}
/// Метод настройки экрана
private func setup() {
if isForceTouchEnabled() {
registerForPreviewing(with: previewProxy, sourceView: collectionView)
}
view.backgroundColor = AppColor.instance.gray
title = viewModel.screenName
let item = UIBarButtonItem(image: #imageLiteral(resourceName: "close.pdf"), style: .plain, target: self, action: #selector(AuthViewController.close))
item.accessibilityIdentifier = "auth_close_btn"
asViewController.navigationItem.leftBarButtonItem = item
navigationItem.titleView = UIImageView(image: #imageLiteral(resourceName: "logo_superjob.pdf"))
collectionViewSetup()
}
// Настройка collectionView
private func collectionViewSetup() {
collectionView.keyboardDismissMode = .onDrag
collectionView.backgroundColor = AppColor.instance.gray
view.addSubview(collectionView)
adapter.collectionView = collectionView
adapter.dataSource = self
collectionView.snp.remakeConstraints { make in
make.edges.equalToSuperview()
}
}
}
// MARK: - DataSource CollectionView
extension AuthViewController: ListAdapterDataSource {
func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
return viewModel.sections(for: listAdapter)
}
func listAdapter(_: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
return viewModel.createListSectionController(for: object)
}
func emptyView(for _: ListAdapter) -> UIView? {
return nil
}
}
// MARK: - AuthViewModelDelegate
extension AuthViewController: AuthViewModelDelegate {
func hideAuth(authSuccessBlock: AuthSuccessAction?) {
dismiss(animated: true, completion: {
authSuccessBlock?()
})
}
func reload(animated: Bool, completion: ((Bool) -> Void)? = nil) {
adapter.performUpdates(animated: animated, completion: completion)
}
func showErrorPopover(with item: CommonAlertPopoverController.Item,
and anchors: (sourceView: UIView, sourceRect: CGRect)) {
let popover = CommonAlertPopoverController(with: item,
preferredContentWidth: view.size.width - 32.0,
sourceView: anchors.sourceView,
sourceRect: anchors.sourceRect,
arrowDirection: .up)
present(popover, animated: true, completion: nil)
}
}
class AuthViewModel {
fileprivate let assembler: AuthSectionsAssembler
fileprivate let router: AuthRouter
fileprivate let profileFacade: SJAProfileFacade
fileprivate let api3ProfileFacade: API3ProfileFacade
fileprivate let analytics: AnalyticsProtocol
fileprivate var sections: [Section] = []
weak var authDelegate: AuthDelegate?
weak var vmDelegate: AuthViewModelDelegate?
var authSuccessBlock: AuthSuccessAction?
private lazy var socialSection: AuthSocialSectionViewModel = { [unowned self] in
self.assembler.socialSection(delegate: self)
}()
init(assembler: AuthSectionsAssembler,
router: AuthRouter,
profileFacade: SJAProfileFacade,
api3ProfileFacade: API3ProfileFacade,
analytics: AnalyticsProtocol,
delegate: AuthDelegate? = nil,
purpose: Purpose) {
self.purpose = purpose
authDelegate = delegate
self.assembler = assembler
self.router = router
self.profileFacade = profileFacade
self.api3ProfileFacade = api3ProfileFacade
self.analytics = analytics
sections = displaySections()
}
private func authDisplaySections() -> [Section] {
let sections: [Section?] = [vacancySection,
authHeaderSection,
socialSection,
authLoginPasswordSection,
signInButtonSection,
switchToSignUpButtonSection,
recoverPasswordSection]
return sections.compactMap { $0 }
}
}
class AuthSocialSectionController: SJListSectionController, SJUpdateCellsLayoutProtocol {
fileprivate let viewModel: AuthSocialSectionViewModel
init(viewModel: AuthSocialSectionViewModel) {
self.viewModel = viewModel
super.init()
minimumInteritemSpacing = 4
viewModel.vmDelegate = self
}
override func cellType(at _: Int) -> UICollectionViewCell.Type {
return AuthSocialCell.self
}
override func cellInitializationType(at _: Int) -> SJListSectionCellInitializationType {
return .code
}
override func configureCell(_ cell: UICollectionViewCell, at index: Int) {
guard let itemCell = cell as? AuthSocialCell else {
return
}
let item = viewModel.item(at: index)
itemCell.imageView.image = item.image
}
override func separationStyle(at _: Int) -> SJCollectionViewCellSeparatorStyle {
return .none
}
}
extension AuthSocialSectionController {
override func numberOfItems() -> Int {
return viewModel.numberOfItems
}
override func didSelectItem(at index: Int) {
viewModel.didSelectItem(at: index)
}
}
// MARK: - AuthSocialSectionViewModelDelegate
extension AuthSocialSectionController: AuthSocialSectionViewModelDelegate {
func sourceViewController() -> UIViewController {
return viewController ?? UIViewController()
}
}
protocol AuthSocialSectionDelegate: class {
func successfullyAuthorized(type: SJASocialAuthorizationType)
func showError(with error: Error)
}
protocol AuthSocialSectionViewModelDelegate: SJListSectionControllerOperationsProtocol, ViewControllerProtocol {
func sourceViewController() -> UIViewController
}
class AuthSocialSectionViewModel: NSObject {
struct Item {
let image: UIImage
let type: SJASocialAuthorizationType
}
weak var delegate: AuthSocialSectionDelegate?
weak var vmDelegate: AuthSocialSectionViewModelDelegate?
fileprivate var items: [Item]
fileprivate let api3ProfileFacade: API3ProfileFacade
fileprivate let analyticsFacade: SJAAnalyticsFacade
fileprivate var socialButtonsDisposeBag = DisposeBag()
init(api3ProfileFacade: API3ProfileFacade,
analyticsFacade: SJAAnalyticsFacade) {
self.api3ProfileFacade = api3ProfileFacade
self.analyticsFacade = analyticsFacade
items = [
Item(image: #imageLiteral(resourceName: "ok_icon.pdf"), type: .OK),
Item(image: #imageLiteral(resourceName: "vk_icon.pdf"), type: .VK),
Item(image: #imageLiteral(resourceName: "facebook_icon.pdf"), type: .facebook),
Item(image: #imageLiteral(resourceName: "mail_icon.pdf"), type: .mail),
Item(image: #imageLiteral(resourceName: "google_icon.pdf"), type: .google),
Item(image: #imageLiteral(resourceName: "yandex_icon.pdf"), type: .yandex)
]
if analyticsFacade.isHHAuthAvailable() {
items.append(Item(image: #imageLiteral(resourceName: "hh_icon"), type: .HH))
}
}
// MARK: - actions
func didSelectItem(at index: Int) {
guard let vc = vmDelegate?.sourceViewController() else {
return
}
let itemType: SJASocialAuthorizationType = items[index].type
socialButtonsDisposeBag = DisposeBag()
api3ProfileFacade.authorize(with: itemType, sourceViewController: vc)
.subscribe(
onNext: { [weak self] _ in
self?.delegate?.successfullyAuthorized(type: itemType)
},
onError: { [weak self] error in
if case let .detailed(errorModel)? = error as? ApplicantError {
self?.vmDelegate?.asViewController.showError(with: errorModel.errors.first?.detail ?? "")
} else {
self?.vmDelegate?.asViewController.showError(with: "Неизвестная ошибка")
}
})
.disposed(by: socialButtonsDisposeBag)
}
}
// MARK: - DataSource
extension AuthSocialSectionViewModel {
var numberOfItems: Int {
return items.count
}
func item(at index: Int) -> Item {
return items[index]
}
}
// MARK: - ListDiffable
extension AuthSocialSectionViewModel: ListDiffable {
func diffIdentifier() -> NSObjectProtocol {
return ObjectIdentifier(self).hashValue as NSObjectProtocol
}
func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
return object is AuthSocialSectionViewModel
}
}
Where assembler is responsible for creating everyting, for example AuthSocialSection:
func socialSection(delegate: AuthSocialSectionDelegate?) -> AuthSocialSectionViewModel {
let vm = AuthSocialSectionViewModel(api3ProfileFacade: api3ProfileFacade,
analyticsFacade: analyticsFacade)
vm.delegate = delegate
return vm
}
How can I properly debug this issue? Any advice or help is really appreciated
Found an issue in AuthSocialSectionController. Somehow passing viewController from IGList context through delegates caused memory issues. When I commented out the viewModel.vmDelegate = self the issue was gone.
That explains why the AuthViewModel was deallocating properly when I hit close button without attempting to authorize. Only when I hit authorize, that viewController property was called.
Thanks for help #vpoltave
This lines from your AuthViewController can this cause leaks?
// adapter has viewController: self
lazy var adapter: ListAdapter
= ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0)
fileprivate lazy var previewProxy: SJListPreviewProxy = {
// capture self.adapter ?
SJListPreviewProxy(adapter: adapter)
}()
I'm not sure, but at least you can try :)
UPDATE
I was wondering about this lazy closures and self inside, it won't create retain cycle because lazy initialization are #nonescaping.

AVCaptureMetadataObjectDelegate not receiving callback

I am making QR scanner. My code is working when all of it written in one place inside ViewController but when I modularised it then I am not getting callback inside AVCaptureMetadataOutputObjectsDelegate.
import Foundation
import UIKit
import AVFoundation
class CameraSource : NSObject {
private var session : AVCaptureSession?
private var inputDevice : AVCaptureDeviceInput?
private var videoPreviewLayer : AVCaptureVideoPreviewLayer?
private var captureMetadataOutput : AVCaptureMetadataOutput?
func setCaptureMetadataOutput() {
self.captureMetadataOutput = nil
self.captureMetadataOutput = AVCaptureMetadataOutput()
}
func getCaptureMetadataOutput() -> AVCaptureMetadataOutput? {
return self.captureMetadataOutput
}
func setInputDevice(inputDevice : AVCaptureDeviceInput?) {
self.inputDevice = inputDevice
}
func getInputDevice() -> AVCaptureDeviceInput? {
return self.inputDevice
}
func setSession(session : AVCaptureSession?) {
self.session = session
}
func getSession() -> AVCaptureSession? {
return self.session
}
func setMetadataObjects(metaObjects : [AVMetadataObject.ObjectType], delegate : AVCaptureMetadataOutputObjectsDelegate) {
assert(self.captureMetadataOutput != nil)
self.captureMetadataOutput!.setMetadataObjectsDelegate(delegate, queue: DispatchQueue.main)
self.captureMetadataOutput!.metadataObjectTypes = metaObjects
}
func initViewoPreviewLayer(videoGravity : AVLayerVideoGravity, orientation : AVCaptureVideoOrientation) {
assert(session != nil)
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session!)
videoPreviewLayer!.videoGravity = videoGravity
videoPreviewLayer!.connection!.videoOrientation = orientation
}
func addVideoLayerToImageView(imageView : UIImageView) {
assert(self.videoPreviewLayer != nil)
imageView.layer.addSublayer(self.videoPreviewLayer!)
self.videoPreviewLayer!.frame = imageView.bounds
}
func startSession() {
assert(session != nil)
self.session!.startRunning()
}
/*==========================================================================
STATIC FUNCTIONS
==========================================================================*/
static func getBackCamera() -> AVCaptureDevice {
return AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)!
}
static func getFrontCamera() -> AVCaptureDevice {
return AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .front)!
}
static func isCameraAvailable() -> Bool {
if #available(iOS 10.0, *) {
let count : Int = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera],
mediaType: AVMediaType.video,
position: .unspecified).devices.count
if count > 0 { return true }
}
else {
let count = AVCaptureDevice.devices(for: AVMediaType.video).count
if count > 0 { return true }
}
return false
}
/*==========================================================================
CAMERA BUILDER CLASS
==========================================================================*/
class Builder {
var cameraSource : CameraSource
init() {
cameraSource = CameraSource()
}
func createSession() -> Builder {
if (cameraSource.getSession() != nil) {
cameraSource.setSession(session: nil)
}
cameraSource.setSession(session: AVCaptureSession())
return self
}
func setSessionPreset(preset : AVCaptureSession.Preset) -> Builder {
assert(cameraSource.getSession() != nil)
cameraSource.getSession()!.sessionPreset = preset
return self
}
func attachInputDevice(camera : AVCaptureDevice) throws -> Builder {
try self.prepareInputDevice(camera: camera)
try self.addInputToSession()
assert(cameraSource.inputDevice != nil)
return self
}
func addOutputToSessionForMetaData() throws -> CameraSource {
cameraSource.setCaptureMetadataOutput()
assert(cameraSource.getSession() != nil && cameraSource.getCaptureMetadataOutput() != nil)
if !cameraSource.getSession()!.canAddOutput(cameraSource.getCaptureMetadataOutput()!) {
throw AppErrorCode.cameraError("Unable to attach output to camera session")
}
cameraSource.getSession()!.addOutput(cameraSource.getCaptureMetadataOutput()!)
return self.cameraSource
}
/*==========================================================================
BUILDER PRIVATE FUNCTIONS
==========================================================================*/
private func prepareInputDevice(camera : AVCaptureDevice) throws {
do {
let inputDevice = try AVCaptureDeviceInput(device: camera)
cameraSource.setInputDevice(inputDevice: inputDevice)
} catch let error as NSError {
print(error.localizedDescription)
throw AppErrorCode.cameraError("Unable to attach input to camera session")
}
}
private func addInputToSession() throws {
if(cameraSource.getSession() == nil) {
throw AppErrorCode.cameraError("Unable to create camera session")
}
assert(cameraSource.getInputDevice() != nil && cameraSource.getSession()!.canAddInput(cameraSource.getInputDevice()!))
cameraSource.getSession()!.addInput(cameraSource.getInputDevice()!)
}
}
}
My QR scanner Code looks like
import UIKit
import Foundation
import AVFoundation
protocol QRScannerDelegate {
func scannedData(_ scannedString : String)
}
class QRScanner : NSObject {
private var cameraSource : CameraSource?
var delegate : QRScannerDelegate?
func prepareCamera (delegate : QRScannerDelegate) throws -> QRScanner {
do {
self.delegate = delegate
self.cameraSource = try CameraSource
.Builder()
.createSession()
.setSessionPreset(preset: .photo)
.attachInputDevice(camera: CameraSource.getBackCamera())
.addOutputToSessionForMetaData()
self.cameraSource!.setMetadataObjects(metaObjects: [.qr], delegate: self as AVCaptureMetadataOutputObjectsDelegate)
} catch let err as NSError {
print(err.localizedDescription)
self.cameraSource = nil
throw AppErrorCode.cameraError("Unable to process camera with one or more issue")
}
return self
}
func initViewoPreviewLayer(videoGravity : AVLayerVideoGravity, orientation : AVCaptureVideoOrientation) -> QRScanner{
assert(cameraSource != nil)
self.cameraSource!.initViewoPreviewLayer(videoGravity: videoGravity, orientation: orientation)
return self
}
func addVideoLayerToImageView(imageView : UIImageView) -> QRScanner{
assert(cameraSource != nil)
self.cameraSource!.addVideoLayerToImageView(imageView: imageView)
return self
}
func startSession() {
assert(cameraSource != nil)
self.cameraSource!.startSession()
}
}
extension QRScanner : AVCaptureMetadataOutputObjectsDelegate {
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
print("Delegate called")
if metadataObjects.count == 0 {
self.delegate?.scannedData("No Data")
} else {
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if metadataObj.type == AVMetadataObject.ObjectType.qr {
if metadataObj.stringValue != nil {
print("Scanner Getting data: \(metadataObj.stringValue!)")
self.delegate?.scannedData(metadataObj.stringValue!)
}
}
}
}
}
I have implemented the QRScannerDelegate in my ViewController but I am not getting anything in there. Moreover I am not getting callback inside AVCaptureMetadataOutputObjectsDelegate even.
I tried passing the ViewController instance as AVCaptureMetadataOutputObjectsDelegate then I was getting callback with the scanned info.
So My question is why is this happening?
1) When I am passing normal class as AVCaptureMetadataOutputObjectsDelegate I am not getting callback. But.
2) Whe I am passing UIViewController instance as AVCaptureMetadataOutputObjectsDelegate then I am able to get callback.
UPDATE
This is how I am calling prepareCamera from my View Controller
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
do {
try QRScanner().prepareCamera(delegate: self)
.initViewoPreviewLayer(videoGravity: .resizeAspectFill, orientation: .portrait)
.addVideoLayerToImageView(imageView: self.qrScannerImageView)
.startSession()
} catch {
print("Some Camera Error")
}
self.createOverlay()
}
Its hard to say for sure without knowing how you called prepareCamera as this is what triggers setMetadataObjectsDelegate but to me it looks like you may not be keeping a strong reference to QRScanner in your ViewController (instantiating it as in instance variable) Which could explain why the callback is getting hit when your ViewController is your AVCaptureMetadataOutputObjectsDelegate as the ViewController is still in memory.
It's also worth noting that if the ViewController is your QRScannerDelegate you will want to define delegate as weak var delegate : QRScannerDelegate? to prevent a memory leak.
EDIT:
Change
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
do {
try QRScanner().prepareCamera(delegate: self)
.initViewoPreviewLayer(videoGravity: .resizeAspectFill, orientation: .portrait)
.addVideoLayerToImageView(imageView: self.qrScannerImageView)
.startSession()
} catch {
print("Some Camera Error")
}
self.createOverlay()
}
to
var qrScanner = QRScanner()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
do {
try self.qrScanner.prepareCamera(delegate: self)
.initViewoPreviewLayer(videoGravity: .resizeAspectFill, orientation: .portrait)
.addVideoLayerToImageView(imageView: self.qrScannerImageView)
.startSession()
} catch {
print("Some Camera Error")
}
self.createOverlay()
}
and change
protocol QRScannerDelegate {
func scannedData(_ scannedString : String)
}
to
protocol QRScannerDelegate: class {
func scannedData(_ scannedString : String)
}
To Allow a weak delegate
AVCaptureMetadataOutputObjectsDelegate is tough, but you can do some really cool stuff with it! So keep at it.
I pulled some QRScanner code I wrote a while ago and put it into a gist for you if you want to check it out. Its a bit more stripped down than what you have, but you may find it helpful.
https://gist.github.com/aChase55/733ea89af1bfa80c65971d3bc691f0b2

swift show QLPreviewPanel

I want to preview some files using a QLPreviewPanel.
I've included the following ViewController using a Storyboard
class ViewController: NSViewController, QLPreviewPanelDataSource, QLPreviewPanelDelegate {
override func viewDidAppear() {
super.viewDidAppear()
self.nextResponder = MainWindowController.testinstance!.nextResponder
}
#IBAction func btn(_ sender: Any) {
openPreview(url: URL(fileURLWithPath: "/Users/usr/Desktop/test.mp3"))
}
//preview for audio
private var previewURL : URL?
func openPreview(url: URL){
previewURL = url
if let sharedPanel = QLPreviewPanel.shared() {
sharedPanel.delegate = self
sharedPanel.dataSource = self
sharedPanel.makeKeyAndOrderFront(nil)
}
}
func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
return 1
}
func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
if previewURL == nil {
return nil
}
return previewURL as? QLPreviewItem
}
override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -> Bool {
return true
}
override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) {
panel.dataSource = self
panel.delegate = self
}
override func endPreviewPanelControl(_ panel: QLPreviewPanel!) {
panel.dataSource = nil
panel.delegate = nil
}}
Everything works fine - but i get the error
[QL] QLError(): -[QLPreviewPanel setDelegate:] called while the panel has no controller - Fix this or this will raise soon.
See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.
How do I solve that? Or is it save to just ignore that error?
Declare a QLPreviewController and then try to show items.
Here is an example for viewing and opening files with QLPreviewController
Example of QLPreviewController

Bonjour Service Browser with Swift does not fetch serviceinfo

The service I want to connect to is published via Bonjour.
I can find all the info with the Bonjour Browser, however if I try to gather the data programmatically, the only value I get, is the name of the service.
The NetService delegate is set and the function netServiceWillPublish is called.
The functions DidNotPublish or DidPublish are not executed.
The function netServiceBrowser gets all published netServices, but all properties are set to the default value of the datatype.
import UIKit
class BMNSDelegate : NSObject, NetServiceDelegate {
func netServiceWillPublish(_ sender: NetService) {
print("netServiceWillPublish:\(sender)"); //This method is called
}
func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]){
print("didNotPublish:\(sender)");
}
func netServiceDidPublish(_ sender: NetService) {
print("netServiceDidPublish:\(sender)");
}
func netServiceWillResolve(_ sender: NetService) {
print("netServiceWillResolve:\(sender)");
}
func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
print("netServiceDidNotResolve:\(sender)");
}
func netServiceDidResolveAddress(_ sender: NetService) {
print("netServiceDidResolve:\(sender)");
}
func netService(_ sender: NetService, didUpdateTXTRecord data: Data) {
print("netServiceDidUpdateTXTRecordData:\(sender)");
}
func netServiceDidStop(_ sender: NetService) {
print("netServiceDidStopService:\(sender)");
}
func netService(_ sender: NetService,
didAcceptConnectionWith inputStream: InputStream,
outputStream stream: OutputStream) {
print("netServiceDidAcceptConnection:\(sender)");
}
}
class BMBrowserDelegate : NSObject, NetServiceBrowserDelegate, NetServiceDelegate {
func netServiceBrowser(_ netServiceBrowser: NetServiceBrowser,
didFind netService: NetService,
moreComing moreServicesComing: Bool) {
let nsnsdel = BMNSDelegate()
netService.delegate = nsnsdel
netService.resolve(withTimeout: 1)
print(netService.domain) // local.
print(netService.name) // This property is correct
print(netService.type) // _http._tcp.
print(netService.addresses) // Optional([])
print(netService.hostName) // nil
print(netService.port) // -1
print(moreServicesComing) //false
}
}
let SERVICE_TYPE = "_http._tcp."
let BM_DOMAIN = "local."
let browser = NetServiceBrowser()
let nsbdel = BMBrowserDelegate()
browser.delegate = nsbdel
browser.searchForServices(ofType: SERVICE_TYPE, inDomain: BM_DOMAIN)
RunLoop.current.run()
The error is that the services which are found in the ServiceBrowserDelegate function are not saved anywhere and therefore are discarded at the end of the function.
I found a working example here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/61f0c753a080040e4a74b912e6c18dd97fe8bcaa/bk2ch24p853bonjour/ch37p1101bonjour/ViewController.swift
class ViewController: UIViewController, NetServiceBrowserDelegate, NetServiceDelegate {
var nsb : NetServiceBrowser!
var services = [NetService]()
#IBAction func doButton (_ sender: Any!) {
print("listening for services...")
self.services.removeAll()
self.nsb = NetServiceBrowser()
self.nsb.delegate = self
self.nsb.searchForServices(ofType:"_daap._tcp", inDomain: "")
}
func updateInterface () {
for service in self.services {
if service.port == -1 {
print("service \(service.name) of type \(service.type)" +
" not yet resolved")
service.delegate = self
service.resolve(withTimeout:10)
} else {
print("service \(service.name) of type \(service.type)," +
"port \(service.port), addresses \(service.addresses)")
}
}
}
func netServiceDidResolveAddress(_ sender: NetService) {
self.updateInterface()
}
func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didFind aNetService: NetService, moreComing: Bool) {
print("adding a service")
self.services.append(aNetService)
if !moreComing {
self.updateInterface()
}
}
func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didRemove aNetService: NetService, moreComing: Bool) {
if let ix = self.services.index(of:aNetService) {
self.services.remove(at:ix)
print("removing a service")
if !moreComing {
self.updateInterface()
}
}
}
}

Given login/signUp code by Parse.com, has binary operator error

I am making SignUp/SignIn pages with watching youtube video.
He makes these pages with parseUI,
In his video, there is no error, but I get an error which is
"binary operator "|" cannot be applied to two 'PFLoginFields' operands" (It is checked where in my code down there. )
I checked in parse.com, parse example code is exactly same code with his.
So my Question is
How can I fix this code to work properly?
or Is there any other Binary operator I can use instead of ||?
import UIKit
import Parse
import ParseUI
class NewResisterVC: UIViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate {
var logInViewController : PFLogInViewController = PFLogInViewController()
var signUpViewController : PFSignUpViewController = PFSignUpViewController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if (PFUser.currentUser() == nil) {
/////////// HERE IS A PROBELM /////////////////
self.logInViewController.fields = (PFLogInFields.UsernameAndPassword | PFLogInFields.LogInButton | PFLogInFields.SignUpButton | PFLogInFields.PasswordForgotten | PFLogInFields.DismissButton)
//////////////////////////////////////////
var loginLogoTitle = UILabel()
loginLogoTitle.text = "bany"
self.logInViewController.logInView!.logo = loginLogoTitle
self.logInViewController.delegate = self
var signUpLogoTitle = UILabel()
signUpLogoTitle.text = "bany"
self.signUpViewController.signUpView!.logo = signUpLogoTitle
self.signUpViewController.delegate = self
self.logInViewController.signUpController = self.signUpViewController
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Parse Login
func logInViewController(logInController: PFLogInViewController, shouldBeginLogInWithUsername username: String, password: String) -> Bool {
if(!username.isEmpty || !password.isEmpty) {
return true
}else{
return false
}
}
func logInViewController(logInController: PFLogInViewController, didLogInUser user: PFUser) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func logInViewController(logInController: PFLogInViewController, didFailToLogInWithError error: NSError?) {
print("Fail to login")
}
//MARK: Parse Sign Up
func signUpViewController(signUpController: PFSignUpViewController, didSignUpUser user: PFUser) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func signUpViewController(signUpController: PFSignUpViewController, didFailToSignUpWithError error: NSError?) {
print("fail to sign up...")
}
func signUpViewControllerDidCancelSignUp(signUpController: PFSignUpViewController) {
print("User dismissed sign up")
}
// mark: Actions
#IBAction func simpleAction(send: AnyObject) {
self.presentViewController(self.logInViewController, animated: true, completion: nil)
}
}
The guy in video is using xcode 6 with swift 1.2, you are using xcode 7 with swift 2.0. Syntax has changed, you have to rewrite this line like this:
self.logInViewController.fields = [PFLogInFields.UsernameAndPassword,
PFLogInFields.LogInButton, PFLogInFields.SignUpButton,
PFLogInFields.PasswordForgotten, PFLogInFields.DismissButton]
Also note that you don't need to write typename prefix when assigning to variable:
self.logInViewController.fields = [.UsernameAndPassword, .LogInButton,
.SignUpButton, .PasswordForgotten, .DismissButton]