UIDocumentPicker function for under IOS.14 - swift

I'm beginner in Swift. I have made a document picker at my task. But I see the documentation it was deprecated to used open var documentPickerMode: UIDocumentPickerMode { get }. While the project in my task runs with minimum deployment of IOS13.
Is there a solution for this feature that can be used on IOS14 and below? Or is this normal, where users need to update IOS?. Forgive me for my ignorance, as I'm new to swift world.

If you look at the docs:
https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller
...you'll see the list of four initializers introduced in iOS 14. Each one configures the picker for one specific type of task. There is no need for a "mode" because you cannot not know how your picker is configured, because you configured it. That is the modern architecture.
At the bottom of the same page you will see the three deprecated initializers from iOS 13 and before, each of which takes a "mode" as a parameter. That is what you must use if you insist upon supporting iOS 13, even though they are deprecated in later systems. And that's fine. "Deprecated" means discouraged and superseded; it does not mean illegal. What you're getting is just a warning, not (as your title wrongly stated) an error.

just try this one code
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
guard url.startAccessingSecurityScopedResource() else {
return
}
defer { url.stopAccessingSecurityScopedResource() }
var error: NSError? = nil
NSFileCoordinator().coordinate(readingItemAt: url, error: &error) { (url) in
let _ : [URLResourceKey] = [.nameKey, .isDirectoryKey]
let documentFileData = NSData(contentsOf: (url)) as Data?
pickImageCallback?(nil, url.lastPathComponent, documentFileData)
}
}

Related

Contextual closure type firebase / swift

Somewhat confused by this error, very new to Firebase but I think this is more a swift programming issue on my part. A lot of the swift coding I'm trying to implement with firebase is new to me.
"Contextual closure type '(Result<StorageListResult, any Error>) -> Void' expects 1 argument, but 2 were used in closure body"
Starting with:
textRef.listAll { (result, error) in
for item in result!.items {
If I use 'item' within this closure alone such as:
let downloadTask = item.write(toFile: localURL) { url, error in
if let error = error {
print ("UNABLE TO DOWNLOAD FILES")
} else {
print("NEW FILE DOWNLOADED")
print(item)
}
}
Works perfectly.
But if I try and use item a 2nd time within the closure, such as:
let serverTimestamp = dateFormatter.string(from: itemTemp.getMetadata.updated())
I get the above error.
The aim of my code is to gain a list all items on my Firebase storage, then against each storage item firstly check its metadata updated date before deciding whether to download or not. However within the closure I can't seem to use item more than once. I either check its metadata or download...not both.
I've tried looking at closures, but struggling to see how I could potential expand the closure to incorporate what I want.
Any advice apprecaited

Download Data in Background URLSession in watchOS 7

I am trying to follow the WWDC20 session "Keep your complications up to date", WWDC20-10049. In trying to follow with the code, I have gotten stuck on the schedule function:
func schedule(_ first: Bool) {
if backgroundTask == nil { //Issue is here
if let url = self.currentWeatherURLForLocation(delegate.currentLocationCoordinate)
{
let bgTask = backgroundURLSession.downloadTask(with: url)
bgTask.earliestBeginDate = Date().addingTimeInterval(first ? 60 : 15*60)
bgTask.countOfBytesClientExpectsToSend = 200
bgTask.countOfBytesClientExpectsToReceive = 1024
bgTask.resume()
backgroundTask = bgTask //Issue is here
}
}
}
}
The issue I am having, since the session only provided snippets, is where the var backgroundTask is defined. This function is declared in the data model, in this case WeatherDataProvider. It is obviously a backgroundURLSession.downloadTask, but it is not identified as self so it should be local to the function, but it is not shown in the snippet. I would expect it to be either sent in as a parameter to the function, or declared in the data model itself. If it is declared there, how is it declared as, according to the talk, it has access to prior background requests as the snippet is checkin to see if there is a background request in the queue so the function doesn't schedule another one. I have searched for the last couple of days, but can find nothing that implements this that I can use to understand where Apple is coming from in this session.
I have checked out this answer, as well as this overview of the session, but I haven't figured this out.
Thanks.

Developing assistive application for macOS, apiDisabled

I am trying to use the Accessibility API using Swift, but am getting a consistent apiDisabled error.
When I go into the System Prefs to disable/enable my app in the Privacy > Accessibility section, I get a "success" result, but once I change the code, it goes back to the error.
Mind you this is a hodge-podge of references based on reading up on this functionality and APIs, I just can't seem to get over this apiDisabled error. Here's my code:
func getWindow() {
let appBundleIdentifier = "com.AppIdentifier"
let myApp: NSRunningApplication? = NSRunningApplication
.runningApplications(withBundleIdentifier: appBundleIdentifier).last as NSRunningApplication?
if let pid = myApp?.processIdentifier {
let axuiApp = AXUIElementCreateApplication(pid)
// List the windows.
var value: AnyObject?
let result: AXError = AXUIElementCopyAttributeValue(axuiApp, kAXWindowsAttribute as CFString, &value)
print(result)
}
}
I'm expecting at least the apiDisabled error to go away so I can start digging into how to access the data I need.
Try manually adding your application to the Accessibility section.
If you use the automated discovery for the Accessibility apps (and not the + button) it might detect a new app every time you build the app as it is not signed.

Having trouble with MusicKit sample app provided by Apple

I am trying to build "Adding Content to Apple Music”, Music Kit sample app provided by Apple, on Xcode 9 beta 3. However I am having 4 errors like this : three “Ambiguous use of 'play()’” errors and one “Ambiguous use of 'pause()’”
Please tell me how to fix this if you already solved this problem.
func beginPlayback(itemCollection: MPMediaItemCollection) {
musicPlayerController.setQueue(with: itemCollection)
//Ambiguous use of 'play()’
musicPlayerController.play()
}
func beginPlayback(itemID: String) {
musicPlayerController.setQueue(with: [itemID])
//Ambiguous use of 'play()’
musicPlayerController.play()
}
// MARK: Playback Control Methods
func togglePlayPause() {
if musicPlayerController.playbackState == .playing {
//Ambiguous use of 'pause()’
musicPlayerController.pause()
} else {
//Ambiguous use of 'play()’
musicPlayerController.play()
}
}
I have found a similar question in the Apple's Dev Forums:
MPMusicPlayerController Swift4 - Ambiguous Use of Play
According to an entry writing a fix to work around the issue, you need to change this line in MusicPlayerManager.swift:
let musicPlayerController = MPMusicPlayerController.systemMusicPlayer
(musicPlayerController's type becomes MPMusicPlayerController & MPSystemMusicPlayerController with this code.)
To:
let musicPlayerController: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
(musicPlayerController is explicitly annotated as MPMusicPlayerController.)
In my opinion this is a bug of Swift related to SE-0156 Class and Subtype existentials and you should better send a bug report to Apple or swift.org.

Winter 2015 / Lecture 10 - Broken Twitter Package

Trying to follow along and code the Smashtag project while watching the Lecture 10 iTunes video.
When I add the dowloaded Twitter package to my Smashtag project, XCode couldn't find the Tweet class when I made reference to it in the TweetTableViewController.
Because of the problem described above, I added the four classes belonging to the Twitter package individually to the project. XCode found the four classes but adding them in this manner generated 11 compile errors.
I'm using XCode Version 6.3 (6D570) which is subsequent to the iOS 8.3 release.
Has anyone else encountered this issue?
Thank you for reading my question.
~ Lee
Possibly not the most-correct (read: best practice) way to do this, but I'm going to chalk it up to doing what it takes to finish the course.
I just went through the list of compile errors and changed the relevant properties to var instead of let. Constants can't be changed and in the new version of Swift they can only be instantiated once. So for the sake of not rewriting too much code, I chose to make certain properties vars instead of lets.
Other bugs I found following the iTunes U course:
The named ‘handler:’ argument needs the name explicitly in a few places.
The simulator will show "TwitterRequest: Couldn\'t discover Twitter account type.” until you go to Settings (inside the simulator) and set the Twitter account. At this point I had to reboot the device, as the call is made in the ViewDidLoad, and thus is only called the first time the view loads. (Alternatively, you could close out the app from the app switcher in the simulator and relaunch that way.)
Here is a gist with corrected code that you can use as a Twitter package that will work with the course and has fixes for the aforementioned bugs, minus the Twitter account setting:
https://gist.github.com/mattpetters/ccf87678ccce0c354398
As Christian R. Jimenez said, "I went to Settings in the Simulated iphone and add my Twitter Account. And everything works perfect." in http://cs193p.m2m.at/cs193p-lecture-10-table-view-winter-2015/. I just added my Twitter Account and tested it, it works!
I had similar problems with the Twitter packages using Swift 2.0 and Xcode 7.2
I'm very new to Swift, so there is a good chance the changes I made are not best practices, but the updated files do work: https://gist.github.com/awaxman11/9c48c0b4c622bffb879f.
For the most part I used Xcode's suggested changes. The two larger changes I made were:
In Tweet.swift I updated the the IndexedKeyword struct's init method to use advanceBy() instead of advance()
In TwitterRequest.swift I updated the signature of NSJSONSerialization to conform to the new error handling system
I've just had a big session fixing the Twitter package files for this same version of Xcode.
It seems that what has broken is that in this version of Swift, constants ('let x...') may only be initialized once, so if a constant is given a value in the declaration ('let x = false'), it may not be changed in the init() function. The Twitter package gives some constants initial values, but then changes the values in the init() function.
My solution to this was to follow the styles suggested in the current version of the Apple Swift language book: declare (many of) the constants as implicitly unwrapped optionals, unconditionally assign a value to them in the init() function (which value may be nil), then test whether any of them are nil, and, if so, return nil from init().
See https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html, click "On This Page" and choose "Failable Initializers"
Also, in TwitterRequest.swift, I needed to add the parameter name 'handler:' in a couple of calls to performTwitterRequest(request, handler: handler).
As an example of constant initialization, in MediaItem.swift:
<< Original Code >>
...
public let aspectRatio: Double = 0
...
init?(data: NSDictionary?) {
var valid = false
if let urlString = data?.valueForKeyPath(TwitterKey.MediaURL) as? NSString {
if let url = NSURL(string: urlString) {
self.url = url
let h = data?.valueForKeyPath(TwitterKey.Height) as? NSNumber
let w = data?.valueForKeyPath(TwitterKey.Width) as? NSNumber
if h != nil && w != nil && h?.doubleValue != 0 {
aspectRatio = w!.doubleValue / h!.doubleValue
valid = true
}
}
}
if !valid {
return nil
}
}
...
<< Updated code >>
...
public let aspectRatio: Double
...
init?(data: NSDictionary?) {
if let urlString = data?.valueForKeyPath(TwitterKey.MediaURL) as? NSString {
if let url = NSURL(string: urlString as String) {
self.url = url
let h = data?.valueForKeyPath(TwitterKey.Height) as? NSNumber
let w = data?.valueForKeyPath(TwitterKey.Width) as? NSNumber
if h != nil && w != nil && h?.doubleValue != 0 {
aspectRatio = w!.doubleValue / h!.doubleValue
return
}
}
}
return nil
}
...