diff --git a/AnimeGen.xcodeproj/project.pbxproj b/AnimeGen.xcodeproj/project.pbxproj index 92bce26a..5ec402c8 100644 --- a/AnimeGen.xcodeproj/project.pbxproj +++ b/AnimeGen.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 130A805C2B78C0300028985F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 130A805B2B78C0300028985F /* Assets.xcassets */; }; 130A805F2B78C0300028985F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 130A805D2B78C0300028985F /* LaunchScreen.storyboard */; }; 138661232B81216D0062AC91 /* Hmtai.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138661222B81216D0062AC91 /* Hmtai.swift */; }; + 138661252B8136DC0062AC91 /* nekosapi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138661242B8136DC0062AC91 /* nekosapi.swift */; }; 13910EBE2B80D380009BF17E /* ImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13910EBD2B80D380009BF17E /* ImageExtensions.swift */; }; 13910EC02B80D396009BF17E /* UIExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13910EBF2B80D396009BF17E /* UIExtensions.swift */; }; 13910EC52B80D5A6009BF17E /* pic-re.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13910EC42B80D5A6009BF17E /* pic-re.swift */; }; @@ -33,6 +34,7 @@ 130A805E2B78C0300028985F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 130A80602B78C0300028985F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 138661222B81216D0062AC91 /* Hmtai.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hmtai.swift; sourceTree = ""; }; + 138661242B8136DC0062AC91 /* nekosapi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = nekosapi.swift; sourceTree = ""; }; 13910EBD2B80D380009BF17E /* ImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageExtensions.swift; sourceTree = ""; }; 13910EBF2B80D396009BF17E /* UIExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIExtensions.swift; sourceTree = ""; }; 13910EC42B80D5A6009BF17E /* pic-re.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "pic-re.swift"; sourceTree = ""; }; @@ -93,6 +95,7 @@ 13910ECA2B80D5C8009BF17E /* waifu-pics.swift */, 13910EC82B80D5C2009BF17E /* nekos-best.swift */, 138661222B81216D0062AC91 /* Hmtai.swift */, + 138661242B8136DC0062AC91 /* nekosapi.swift */, ); path = APIs; sourceTree = ""; @@ -191,6 +194,7 @@ 138661232B81216D0062AC91 /* Hmtai.swift in Sources */, 13910EC52B80D5A6009BF17E /* pic-re.swift in Sources */, 13910EC02B80D396009BF17E /* UIExtensions.swift in Sources */, + 138661252B8136DC0062AC91 /* nekosapi.swift in Sources */, 13910EC92B80D5C2009BF17E /* nekos-best.swift in Sources */, 13910EBE2B80D380009BF17E /* ImageExtensions.swift in Sources */, ); diff --git a/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate b/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate index 275bc6f0..759f1cdf 100644 Binary files a/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate and b/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AnimeGen/APIs/Hmtai.swift b/AnimeGen/APIs/Hmtai.swift index 5a31583a..5dca0dd2 100644 --- a/AnimeGen/APIs/Hmtai.swift +++ b/AnimeGen/APIs/Hmtai.swift @@ -2,7 +2,7 @@ // Hmtai.swift // AnimeGen // -// Created by Francesco on 17/02/24. +// Created by cranci on 17/02/24. // import UIKit diff --git a/AnimeGen/APIs/nekosapi.swift b/AnimeGen/APIs/nekosapi.swift new file mode 100644 index 00000000..e52e98e9 --- /dev/null +++ b/AnimeGen/APIs/nekosapi.swift @@ -0,0 +1,84 @@ +// +// nekosapi.swift +// AnimeGen +// +// Created by cranci on 17/02/24. +// + +import UIKit + +extension ViewController { + + func loadImageAndTagsFromNekosapi() { + startLoadingIndicator() + + let rating = ["safe", "suggestive"] + let randomrating = rating.randomElement() ?? "safe" + + let apiEndpoint = "https://api.nekosapi.com/v3/images/random?limit=1&rating=\(randomrating)" + + guard let url = URL(string: apiEndpoint) else { + print("Invalid URL") + stopLoadingIndicator() + return + } + + var request = URLRequest(url: url) + request.httpMethod = "GET" + + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + DispatchQueue.main.async { + if let error = error { + print("Error: \(error)") + self.stopLoadingIndicator() + return + } + + guard let httpResponse = response as? HTTPURLResponse else { + print("Invalid HTTP response") + self.stopLoadingIndicator() + return + } + + guard httpResponse.statusCode == 200 else { + print("Invalid status code: \(httpResponse.statusCode)") + self.stopLoadingIndicator() + return + } + + do { + if let jsonData = data, + let jsonResponse = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any], + let items = jsonResponse["items"] as? [[String: Any]], + let firstItem = items.first, + let imageUrlString = firstItem["image_url"] as? String, + let imageUrl = URL(string: imageUrlString), + let tagsArray = firstItem["tags"] as? [[String: Any]] { + + self.currentImageURL = imageUrlString + + let tags = tagsArray.compactMap { $0["name"] as? String } + + if let data = try? Data(contentsOf: imageUrl), let newImage = UIImage(data: data) { + self.imageView.image = newImage + self.animateImageChange(with: newImage) + + self.updateUIWithTags(tags) + + self.stopLoadingIndicator() + } else { + print("Failed to load image data.") + self.stopLoadingIndicator() + } + } else { + print("Failed to parse JSON response or missing necessary data.") + self.stopLoadingIndicator() + } + } + } + } + + task.resume() + } + +} diff --git a/AnimeGen/ViewController.swift b/AnimeGen/ViewController.swift index d279756d..98804fa2 100644 --- a/AnimeGen/ViewController.swift +++ b/AnimeGen/ViewController.swift @@ -209,6 +209,8 @@ class ViewController: UIViewController { loadImageFromWaifuPics() case "Hmtai": loadImagesFromHmtai() + case "Nekos api": + loadImageAndTagsFromNekosapi() default: break } @@ -250,6 +252,9 @@ class ViewController: UIViewController { case "Hmtai": lastImage = imageView.image loadImagesFromHmtai() + case "Nekos api": + lastImage = imageView.image + loadImageAndTagsFromNekosapi() default: break } @@ -259,7 +264,7 @@ class ViewController: UIViewController { @objc func apiButtonTapped() { let alertController = UIAlertController(title: "Select API", message: nil, preferredStyle: .actionSheet) - let apiOptions = ["Hmtai", "waifu.pics", "nekos.best", "waifu.im", "pic.re"] + let apiOptions = ["Nekos api", "Hmtai", "waifu.pics", "nekos.best", "waifu.im", "pic.re"] for option in apiOptions { let action = UIAlertAction(title: option, style: .default) { _ in self.apiButton.setTitle(option, for: .normal) diff --git a/README.md b/README.md index 1b43fb95..fe5d0449 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,21 @@ # AnimeGen -AnimeGen is an app made in Swift. This app is developed using the [pic.re api](https://doc.pic.re/), [waifu.im api](https://docs.waifu.im/), [nekos.best api](https://docs.nekos.best/), [waifu.pics api](https://waifu.pics/docs), [Hmtai api](https://hmtai.hatsunia.cfd/endpoints), Its purpose is to save, generate, and share images. - ---- +AnimeGen is an app made in Swift. This app is developed using public APIs. The app purpose is to save, generate, and share images. ## Compatibility Its Made to support any iOS/iPadOS device running iOS 13+ +## Supported APIs + +- [pic.re api](https://doc.pic.re/) +- [waifu.im api](https://docs.waifu.im/) +- [nekos.best api](https://docs.nekos.best/) +- [waifu.pics api](https://waifu.pics/docs) +- [Hmtai api](https://hmtai.hatsunia.cfd/endpoints) +- [Nekos api](https://nekosapi.com/docs) + ## Third Party Softwares - [SDWebImage](https://github.com/SDWebImage/SDWebImage) (.gif images saves for the gallery) - [NineAnimator](https://github.com/SuperMarcus/NineAnimator) (Launchscreen Idea/Base) -- [Nekidev](https://github.com/Nekidev/anime-api) (Helped me finding the Htmai api) \ No newline at end of file +- [Nekidev](https://github.com/Nekidev/anime-api) (Helped me finding the Htmai api)