Export an UIImage as a sticker for Messages app - swift

I'm trying to export an UIImage as a sticker for Messages app, but I can't find any documentation about this.
I have my project with the Sticker Pack extension enabled and see that Xcode created a new Stickers.xcassets, every image that I add there manually appears on Messages app to use as a sticker, but how can I save an image programatically there, so the user can create stickers from any image ?
All I can find is information related to creating stickers without doing any code, just shipping an app with predefined images.
let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "Test")
I know how create a MSSticker from the image file, but after this I don't know how to proceed and make this newly created sticker appear on Messages app.

Stickers are loaded from stickers assets catalog .xcstickers.
This catalog is a resource file/folder, that means this is placed inside your bundle. All files inside your bundle are not writable and they have only read permissions. IMO what you need to do is:
You have to store your users custom images in any one of the sandboxed folders (Documents, Library and temp).
Read image from this folder and create MSSticker from it same way as you did. - let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "Test") and add. this sticker to array.
In your MSStickerBrowserViewController you will load stickers from array created in previous step.
Like this
override func numberOfStickers(in stickerBrowserView: MSStickerBrowserView) -> Int {
stickers.count
}
override func stickerBrowserView(_ stickerBrowserView: MSStickerBrowserView,
stickerAt index: Int) -> MSSticker {
stickers[index]
}

Related

Load image to uiimageview based on the selected target in Xcode

I'm trying to create two applications from same codebase. These application will have same functionality but different logos, app name etc. I have created two targets with different bundle Ids so now I get unique apps when running each target.In my app, I have a viewcontroller with an UIImageView.
Now I want to assign an image to UIImageView based on the running target. So I created two assets folders.
Target1 -> Assest1 -> logo.png
Target2 -> Assest2 -> logo.png
logo.png is different file with same name.
How can I assign the correct logo.png to uiimageview based on the running target? Your help is appreciated.
Ensure that your asset is in the correct target an then use the following method:
UIImage(named: "example", in: Bundle(for: YourClass.self), with: nil)
To obtain your bundle you could use your class to refer to your bundle:
Bundle(for: YourClass.self)

how can i let a user pick a local document?

I'm supposed to test PSPDFKit in a way that lets the user open a locally saved pdf file.
For this i require the files url(e.g. path, i guess). How can i let the user pick a local document?
Can anybody help me out?
I'm using storyboard and swift.
You can present a PDF document in PSPDFKit using the PDFViewController like so:
// Create the `Document`.
let fileURL = Bundle.main.url(forResource: "Document", withExtension: "pdf")!
let document = Document(url: fileURL)
// Create the PDF view controller.
let pdfController = PDFViewController(document: document)
// Present the PDF view controller within a `UINavigationController` to enable the toolbar.
present(UINavigationController(rootViewController: pdfController), animated: true)
For more details, take a look at the following guide here.
Also, to present a document that your end-user has selected, consider using a document picker or a file browser. Please refer to DocumentPickerSidebarExample.swift from Catalog and SwiftUI Document Browser for runnable example projects.
In the future, please reach out to our support portal at pspdfkit.com/support/request/ - we're happy to provide support there for our commercial SDK.

Handling two document type

I'm developping a mac application that allow to transcribe/subtitles video. I must deal with two kind of document type:
SRT file (read/write)
Video file (read only)
For now SRT is the only document type of my application. I open video with an Open a video... menu item (under File), I connected to the openVideo action of the First responder.
Here is the code of my VideoControlerView called when pressing Open a video... :
#IBAction func openVideo(sender: AnyObject) {
let dlg = NSOpenPanel()
dlg.runModal()
if let url = dlg.URL {
self.playerView.player = AVPlayer(URL: url)
}
}
I'm sure it is possible to benefit from the multi document type handling of document based application but I can't figure how. Any idea?
After questionning Apple Developer support about it, DocumentType is only designed for the editing document (SRT in my case).
The way I handle my asset (video file) is the proper way to go!

Take screenshot of host app using iOS share/action extensions?

I will like to know how to take a screenshot of the iOS host app with the use of a share/action extension.
My use case is as follows:
use the Safari browser to access a webpage (https such as gmail)
tap on the Share button and select the extension
the extension will take a screenshot of the current webpage
An working example for this use case is the Awesome Screenshot iOS app.
I had tried the following methods
reload the baseURI (loadRequest) on a UIWebView/WKWebkit (would not be able to access https contents such as Gmail). So not doing any reload (Awesome Screenshot is not doing a reload btw)
Used the ExtensionPreprocessingJS to obtain the DOM contents through the arguments.completionFunction function. I could not extract the document.body here although i could get the source etc. loadHTMLString with the baseURI will mess up the presentation layer.
Used html2canvas in the ExtensionPreprocessingJS to obtain an image and appended it to the host app's webpage as a child but do not know how to extract it. Also, the image got lost for some webpages such as Gmail.
Mobile Safari does not have the visibleContentsAsDataURL method.
I think a viable approach will be to use the html2canvas in the ExtensionPreprocessingJS but how do I save this image somehow?
Edit: So the below works in the Simulator but does not work on the device. I'm presently looking for a solution as well.
Here's a solution that I think the Awesome Screenshot app uses:
func captureScreen() -> UIImage
{
// Get the "screenshot" view.
let view = UIScreen.mainScreen().snapshotViewAfterScreenUpdates(false)
// Add the screenshot view as a subview of the ShareViewController's view.
self.view.addSubview(view);
// Now screenshot *this* view.
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, false, 0);
self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Finally, remove the subview.
view.removeFromSuperview()
return image
}

How to switch skins (or design themes) in iOS app?

I'd like to make my iPhone app to be able to switch between skins (or design theme, or look and feel, such as wooden, metal, earth color, men's, girls, etc...).
I'll prepare some sets of skins that contains images for buttons and backgrounds, sounds, and text color, and let the user decide which set of skin they want to use by the application settings.
What is the best practice to implement this?
The conditions are:
I'd like to use Interface Builder
I need to support iOS 3.1.3 and later
I want to make the sets of skins downloadable from the internet (I can't bundle all the skins in the app, as one set of skin requires lots of images and the app file size could become huge if I do so... I also don't want to hardcode any information about specific skins.)
If a custom skin does not contain one or some elements, (such as an image or sound file), I want it to use the missing element from the default set of skin.
I don't want to create Nib files for each skin. The Nib file for one screen should be the only one in the main bundle for easier maintenance.
I'm thinking about making a superclass of all the UIViewControllers in my app and override the part that it loads Nib file, and instead of loading from the main bundle, load the resources from the skin that is saved in the Document directory... but I don't know how to do it... The default behavior of the Nib-loading methods always loads resources from the main bundle and the information about resource file names are lost after reading... :(
Thanks in advance for your help.
Am not sure about best practice .. But, if your app is not big enough, then a well structured plist is your friend.
Initially, you could choose: Metal Theme. The following should hold:
You either have a Singleton ThemeManager, or just stick an NSDictionary to one of your Singletons if appropriate.
The point behind the ThemeManager is the mapping between the asset and the theme..
Some sample code (written directly on SOF .. Don't mind Syntax mistakes):
#define kThemeMap(__x__) [[ThemeManager sharedManager] assetForCurrentTheme:__x__]
...
-(void)doUselessStuff {
UIImage* backgroundImage = [UIImage imageNamed:kThemeMap(#"FirstViewBG")];
...
}
//in the ThemeManager:
//returns the appropriate name of the asset based on current theme
-(NSString*)assetForCurrentTheme:(NSString*)asset {
//_currentTheme is an NSDictionary initialized from a plist. Plist can be downloaded, too.
NSString* newAsset = [_currentTheme objectForKey:asset];
if(newAsset == nil) {
newAsset = [_defaultTheme objectForKey:asset];
}
return asset;
}
//Let us assume the user selects Metal Theme somewhere .. Still coding ThemeManager:
-(void)selectedNewTheme:(NSString*)newTheme {
//First, get the full path of the resource .. Either The main bundle, or documents directory or elsewhere..
NSString* fullPath = ...;
self.currentTheme = [NSDictionary dictionaryWithContentsOfFile:fullPath];
}
The plist files are just a dictionary with string to string mapping... something like this:
//Default.plist
#"FirstViewBG" : #"FirstViewBG_Default.png"
#"SecondViewBG" : #"SecondViewBG_Default.png"
#"WinSound" : #"WinSound_Default.aiff"
//Metal.plist
#"FirstViewBG" : #"FirstViewBG_Metal.png"
#"SecondViewBG" : #"SecondViewBG_Metal.png"
#"WinSound" : #"WinSound_Metal.aiff"
Alternatively, you can just save the postfix, if that is good enough for you.. But, it will require string manipulation, by slicing the extension -> adding the postfix -> adding the extension ..
Or maybe make it a prefix?
You can category on UIImage with the methored imageNamed:, use the custom imageNamed: instead of the default one.
In the custom methord, selected the image by theme.