Post

Replies

Boosts

Views

Activity

Reply to How to load mp3 on Library Folder and play it.
Thanks for showing your code. The critical thing in your code is this part: do { let audioPlayer = try AVAudioPlayer(contentsOf: storedURL, fileTypeHint: AVFileType.mp3.rawValue) audioPlayer.play() print("sound is playing") } catch let error { print("Sound Play Error.lDescription -> \(error.localizedDescription)") print("Sound Play Error -> \(error)") } (As was shown in your first post, nice guess!) The problem is that the variable audioPlayer is local to the do-catch block. So, it will be lost immediately after print("sound is playing"). With audioPlayer.play(), playing the audio is just started but not finished. The instance of AVAudioPlayer needs to be held while playing. Please try something like this: struct ContentView: View { let playerManager = AudioPlayerManager.shared //<- @State var message: String = "Test Message2" @State var storedURL: URL? var body: some View { Text(message) .onTapGesture { guard let path = Bundle.main.path(forResource: "selectSE", ofType: "mp3") else { print("Sound file not found") return } let url = URL(fileURLWithPath: path) do { let fileData = try Data(contentsOf: url) storedURL = saveDataFile(data: fileData, fileName: "test.mp3", folderName: "testFolder") print("File Writing on View -> Success \(storedURL?.absoluteString ?? "nil") ") } catch { print("Data.init(contentsOf:) failed: \(error)") } playerManager.play(url: storedURL!) //<- print("end of code") } } //... } class AudioPlayerManager { static let shared = AudioPlayerManager() var audioPlayer: AVAudioPlayer? func play(url: URL) { do { audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue) //<- No `let` audioPlayer?.play() print("sound is playing") } catch let error { print("Sound Play Error -> \(error)") } } } You have no need to copy the sound file each time onTapGesture, but it is not critical and you may improve it later.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’21
Reply to How to Handle NULL in Swift?
An interesting example. As you already know, a value that can be NULL would usually be imported into Swift as Optional and you use nil in Swift. But in the example you have referred, the Swift version of the function signature shows the return value as non-Optional: func CGColorSpaceCreateDeviceRGB() -> CGColorSpace Interestingly, the original C-declaration in CGColorSpace.h is marked with cg_nullable: /* Create a DeviceRGB color space. */ CG_EXTERN CGColorSpaceRef cg_nullable CGColorSpaceCreateDeviceRGB(void) CG_AVAILABLE_STARTING(10.0, 2.0); You can find some functions in CGColorSpace.h are marked with cg_nullable and imported as non-Optional in Swift, and some others marked with __nullable (which is a standard way to tell it is nullable to Swift importer) and imported as Optional. I'm not sure if this usage was intentional to distinguish nullable, but should be imported as Optional into Swift cases and simply nullable. But, in fact, when I use CGColorSpaceCreateDeviceRGB() in Swift, I do expect this would never return nil. When some functions may return NULL, but only in cases where continuing execution is not practical, such as Out of Memory, the imported type might be non-Optional in Swift. It would be better if this sort of mismatching was clearly documented. You can send a bug report using Apple's Feedback Assistant.
Topic: Programming Languages SubTopic: Swift Tags:
Jul ’21
Reply to Async Sequence
These things are not intuitive and i cant find good resources explaining them. Have you ever tried to make your custom type conform to Sequence? Making AsyncSequence is very similar to Sequence. And as explained in the session video you referred, Swift compiler compiles for-(try)-await as: var iterator = quakes.makeAsyncIterator() while let quake = await iterator.next() { //... } You need to implement what compiler demands. (typealias is a thing needed for making types conform to some protocol. Better read the Swift book carefully.)
Topic: Programming Languages SubTopic: Swift Tags:
Jul ’21
Reply to Async Sequence
As far as I read the proposal SE-0298Async/Await: Sequences, implementing AsyncSequence is far from intuitive. You may need to write something like this: func fetchAsyncImage(request: URLRequest) -> AsyncPhotos { return AsyncPhotos(request: request) } struct AsyncPhotos: AsyncSequence { typealias Element = UIImage let request: URLRequest struct AsyncIterator: AsyncIteratorProtocol { let request: URLRequest var photosIterator: Array<Photo>.Iterator? mutating func next() async throws -> UIImage? { if photosIterator == nil { let (data, response) = try await URLSession.shared.data(for: request) guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badRequest } let photos = try JSONDecoder().decode([Photo].self, from: data) photosIterator = photos.makeIterator() } guard let photo = photosIterator?.next() else { return nil } do { guard let imageURL = URL(string: photo.urlPath) else { throw FetchError.noURL } let (imageData, imageResponse) = try await URLSession.shared.data(from: imageURL) guard (imageResponse as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.invalidImageURL } guard let image = UIImage(data: imageData) else { throw FetchError.badImage } return image } catch { throw FetchError.invalidImageURL } } } func makeAsyncIterator() -> AsyncIterator { AsyncIterator(request: request) } } (Not tested. You may need to fix many parts.) I'm not sure if AsyncStream/AsyncThrowingStream can improve the way implementing AsyncSequence.
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to valid replacement for kUTTypeJPEG which is deprecated
Seems the deprecation message is meant for Objective-C code. (You can send a bug report to Apple using Feedback Assistant.) In Swift, Uniform Type Identifiers are wrapped into static members of UTType. System Declared Uniform Type Identifiers Can you try UTType.jpeg.identifier as CFString instead? (You may need import UniformTypeIdentifiers if your source code does not have it yet.)
Topic: Media Technologies SubTopic: Audio Tags:
Jun ’21
Reply to How can I identify and group data in a JSON file?
I've googled around about top level arrays and nested JSON info but can't figure out what my next step is. Seems your Googling ability is not good enough. You can find bunch of articles searching with swift searching one element in an array. You should show your code enough to test instantly, especially when you show some code in a method, you should show at least the whole method. Partially shown code might often lead to an unexpected and unusable answers. I needed to guess what was the header of the method and some other things. And I assumed something as follows: @IBOutlet weak var targetAreaField: UITextField! func apiCall(callCompletionHandler: @escaping([ReceivedAPIData])->Void) { guard let apiUrl = URL(string: "https://cadatacatalog.state.gov/dataset/4a387c35-29cb-4902-b91d-3da0dc02e4b2/resource/299b3b67-3c09-46a3-9eb7-9d0086581bcb/download/countrytravelinfo.json") else { print("Error: cannot create URL.") return } let session = URLSession(configuration: .default) let task = session.dataTask(with: apiUrl) { [self] data, response, error in if let error = error { print(error) return } guard let safeData = data else { print("Couldn't get data back from url."); return } let decoder = JSONDecoder() let safeDecodeData: [ReceivedAPIData] do { safeDecodeData = try decoder.decode([ReceivedAPIData].self, from: safeData) } catch { fatalError("Couldn't decode data.") } self.delegate?.didUpdateAPIResults(returnedResult: safeDecodeData) //let jsonStringData = data?.prettyPrintedJSONString ?? "**data cannot be prity-printed**" //print("Pretty JSON from server ----- \(jsonStringData)") //... callCompletionHandler(safeDecodeData) } task.resume() } (I have corrected some bad practices in your code, but there is still one unrecommended thing: You should better call completion handler in case of errors. But that is another issue.) When I searched with swift searching one element in an array, this Apple' doc showed in the top page: first(where:) | Apple Developer Documentation. You can use it like this: guard let targetArea = targetAreaField.text, !targetArea.isEmpty else { return } apiCall { result in //print(result.count) guard let targetResult = result.first(where: {$0.geopoliticalarea == targetArea}) else { print("NO data for \(targetArea)") return } print(targetResult) //... }
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to Nil
I guess, you are using asynchronous methods incorrectly. Anyway, avoid using forced unwrapping. By the way, don't you think you should respond when you get comments and answers?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to Type 'DefaultNavigationViewStyle' has no member 'automatic'
How can I set up my navigationViewStyle to be StackNavigationStyle and the default elsewhere ? The modifier navigationViewStyle requires a value of one concrete type conforming to NavigationViewStyle. So, even when DefaultNavigationViewStyle.automatic is valid there, you cannot use the ternary operator which may return two different types -- StackNavigationViewStyle or DefaultNavigationViewStyle. One possible solution would be using a custom modifier: struct ContentView: View { //... var body: some View { ZStack { NavigationView { List { //... } }.navigationTitle("Options") } .modifier(MyNavigationViewStyle()) } } struct MyNavigationViewStyle: ViewModifier { func body(content: Content) -> some View { if UIDevice.current.model == "iPad" { content.navigationViewStyle(StackNavigationViewStyle()) } else { content.navigationViewStyle(DefaultNavigationViewStyle()) } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to What is the syntax for "if not" in Swift?
But this would then go when all I really want is the not part if let twinkling = getHighGem() as? MyGem { } else { ..... } Sorry, I wanted the NOT (!) equivalent to : if let twinkling = getHighGem() as? MyGem I cannot be sure if I would be interpreting what you mean correctly, but you want to find some sort of better alternative for this? if let twinkling = getHighGem() as? MyGem { /* Do nothing */ } else { ..... } As this type of code: if someCondition { /* Do nothing */ } else { ..... } can be re-written using not ! operator: if !someCondition { ..... } If you want to do something like above, you need to think what if-else would do on true-case and false-case: The if-let first checks the Optional value of the right hand side if it is nil or not: And if it is not nil, it does a little more Unwrap the Optional value and retrieve the non-Optional value Create a new binding to the unwrapped value as a local constant Execute the true-case code block And if the checked value is nil Execute the false-case code block So, if you just want a false-case execution, you just need a nil checking: if (getHighGem() as? MyGem) == nil { ..... } In this case, it can be rewritten as: if !(getHighGem() is MyGem) { ..... } But, as you can see in the answer of Graphics and Games Engineer, using guard-let-else would be a better alternative in various cases. If you had shown enough context, you would have been shown which is better.
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21