How to add login Items by code to mountain lion osx - authentication

I want to add login items programmatically in Mountain Lion (10.8).
Until now I was able to add login items by editing this plist:
/Users/test/Library/Preferences/loginwindow.plist
and adding items (path,name,hide) to AutoLaunchedApplicationDictionary dictionary
in the OS doesn't work anymore. Items that are added to this dictionary are not launched on login. I see that the login items are saved in a file called: com.apple.loginitems.plist
but I don't understand how to add an item to this file. I tried to add the item to CustomListItems dictionary with parameters like name,path, hide but they were not launched on login.
Does anyone know how can I add from code login item?

I understand you want to start your program automatically when your user logs in.
In older versions of OS X, it was possible to add login items manually by editing loginwindow.plist. Apple deprecated this approach when they added LaunchAgent and LaunchDaemon functionality to the OS.
Since you are using Mountain Lion, the correct way to have a program launch is to create a launchagent for it. This is a .plist file that you can use to tell OS X to a) perform some action (e.g.: launch /some/program.app) when b) a specific event occurs (e.g.: logging in, logging out, etc)
You will find Apple's official document on creation of LaunchAgents over here.

This looks like a great tutorial on the modern way of doing things: The launch at login sandbox project
It starts with a paragraph buried in the App Sandbox design guide:
Creating a Login Item for Your App
To create a login item for your sandboxed app, use the SMLoginItemSetEnabled function (declared in ServiceManagement/SMLoginItem.h) as described in “Adding Login Items Using the Service Management Framework” in Daemons and Services Programming Guide.
(With App Sandbox, you cannot create a login item using functions in the LSSharedFileList.h header file. For example, you cannot use the function LSSharedFileListInsertItemURL. Nor can you manipulate the state of launch services, such as by using the function LSRegisterURL.)
And rolls from there...

Related

How do I notify users of new content available in tvOS apps from the home screen?

Push notifications have been left out of tvOS (understandably so) but the docs seem to contradict themselves in alerting users to the fact that there is something new available in your tvOS app.
Here it seems to say that you can add an app badge: https://developer.apple.com/library/prerelease/tvos/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/WhatAreRemoteNotif.html
Here it says they've been removed from UIKit: https://developer.apple.com/library/prerelease/tvos/releasenotes/General/tvOS90APIDiffs/Objective-C/UIKit.html
Removed UIApplication.applicationIconBadgeNumber
Assuming the badge approach is not supported in this release, does anyone know the best practice for alerting a user that there is new content in your app without the user taking an explicit action? ie focusing on the app and showing them something in TopShelf?
I encountered the same problem and dived into this. Probably your best way is to update the topshelf with latest items, which is my way to solve this for now. You can use network calls to update the topshelf with content from your backend.
This depends on the type of application. E.g. showing the latest top movies for a movies app.
You can trigger an update of the topshelf after your network call completed using the following code:
NSNotificationCenter.defaultCenter().postNotificationName(TVTopShelfItemsDidChangeNotification, object: nil)
Make sure to implement the TVTopShelfProvider which should be clear using the following documentation:
This protocol is adopted by the principal class of an app’s TV Services extension. Apps that implement this extension can provide dynamic content to the Top Shelf element rather than having the system use the static image submitted with the app. The topShelfStyle property specifies the interface style you want, and the topShelfItems property specifies the content items to display. Whenever you change the content provided by the extension, post a TVTopShelfItemsDidChangeNotification notification to prompt the system to reload your content.
Icon badges are removed for app icons, push notifications as well (except for silent push notifications).

How can I determine if my Cocoa Desktop application is on the list of apps to be opened at login?

I am developing a SandBoxed Cocoa Application. I have successfully implemented the Launch at login feature by using the Core Foundation function:
SMLoginItemSetEnabled
I have based the implementation on This tutorial
But now I need a way to determine if my app is set to be launched at login, so that I can show the button in the appropriate position upon launch. I would expect a similar Core Foundation function to find out if a bundle identifier is on the list of login items, but I didn't find it.
Another problem is that, by using this Core Foundation approach, although it is recommended by Apple, my app is still inconsistent with the "Open at Login" tick in my application dock menu.
You can do it using the functions in the LSSharedFileList.h header, which is in LaunchServices.framework, which is in CoreServices.framework. As far as I can tell, Apple hasn't documented this stuff except in the header comments, but that's probably enough. The basic outline is that you first create a LSSharedFileListRef using the function LSSharedFileListCreate for the list type kLSSharedFileListSessionLoginItems. Then copy a snapshot of the list (which is a CFArrayRef) using LSSharedFileListCopySnapshot. Then for any item in the array, you can get its URL using LSSharedFileListItemCopyResolvedURL. That last function requires Mac OS X 10.10 or later, while I think the others date back to 10.5.
By the way, the docs on SMLoginItemSetEnabled say that it's for setting an embedded helper app as a login item, but it sounds like you're talking about a freestanding app.
Apple's sandbox documentation says:
With App Sandbox, you cannot create a login item using functions in the LSSharedFileList.h header file. For example, you cannot use the function LSSharedFileListInsertItemURL.
But maybe you can still use the shared file list functions on a read-only basis.

Confused with IOS Deep linking

I'll just want to ask if someone here know the step by step process of creating a deep link for an IOS app? I've tried to read some articles but it did not give me absolute answers. Thank you :)
Deep linking is basically just setting up url to your app so that other apps can launch it with information. The can launch to certain parts of the app if you set it up so that your app reacts to certain urls. So there are a few things that you have to do. For this example I will use two apps. If you are trying to integrate with an existing app you just have to find out what their url schemes are. So for this example I will use 'Messages' as one app and 'Schedule' as another.
First: in the 'Messages' app we will need to setup the schemes our Schedule app to call.
So open up your first app we need to add schemes so other apps can open it. Go to your info.plist click the little + and type URL types hit the triangle to expand and hit the + type URL Schemes and within that one add an item and put your apps name in it. Also add URL identifier along with $(PRODUCT_BUNDLE_IDENTIFIER) as the value. `
Then we just have to add the apps that we can open so hit the top level + again and add LSApplicationQueriesSchemes This whitlists the apps so we can evaluate weather or not they are installed on the device.
Now we can jump over to the other app and create a way to call this. For this example lets make it happen when we press a button.
IBAction launchMessagesApp() {
let url = NSURL(string: "Messages://") where UIApplication.sharedApplication().canOpenURL(url) {
self.launchAppWithURL(url, name: "Messages")
}
The canOpenURL(url) checks to see if the application is on the device. If you wanted to you could launch the app store to your app if that retuned false. then launchAppWithURL actually launches it. That is the basic setup you may also want to have multiple things happen so you may have multiple url schemes that launch the same app but take it to different parts of the app. In the app delegate of the app in the function
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
print(url)
//Any customizations for the app here
}
You can do anything you can imagine.
Have you checked out Turnpike? It's an open source tool for enabling deep linking in iOS apps. http://urxtech.github.io/#GettingStarted
If you want to create a deeplink you might need to do some server code to detect the user device/browser and do some actions based on this.
I've created a tool that simplify this process, you can check it here:
http://www.uppurl.com/
It's mainly a short link tool that checks for user device and give him the right url based on his devices. With this tool you don't need to write any server code and it also takes care of different devices, operating systems and browsers.

Provide an OSX Service Without Launching the App?

I have successfully implemented a "faceless service" (background-only app with .service extension) and get it to work (see this question), based on Apple's documentation and other tutorials on the web.
Now, I want to advertise a service from an existing, single-window GUI app that I have.
I have setup the Info.plist file of my app to advertise the service, and it gets installed when I build the app.
But when I invoke the service from the context menu in (say) TextEdit.app (my service colours the selected text based on a certain criterion), my app gets launched, main window and everything. To make things worse, I am right-clicking on a TextEdit window that is in a secondary monitor, so my app's main window appears for an instant in the secondary monitor, then quickly repositions into the main monitor (this might have something to do with my window-centering logic, but nevermind...).
I would like to provide the service (i.e., have the class that provides the service in my app
instantiated and execute its method in response to the request), without my app appearing on the Dock or showing its window and main menu.
Is this possible? Safari advertises "Search With Google", so it should be possible...
EDIT: Now that I think about it, "Search With Google" must launch Safari every time in order to work, so this remark does not apply.
Perhaps I can put some logic in -applicationWillFinishLaunching/-applicationDidFinishLaunching to determine if the app is being launched in response to a service, and skip creating the window(notice the lack of withOptions: in OSX)?
But still, that doesn't feel right.
It does have a lame version of withOptions: -- NSApplicationLaunchIsDefaultLaunchKey tells you if your application was launched to either:
open or print a file, to perform a Service action, if the app had saved state that will be restored, or if the app launch was in some other sense not a default launch
So in your applicationDidFinishLaunching you can see if that key is in the notification and set to NO. Unfortunately, the main way to tell that it is one of the possibilities other than the Service, you have to detect and record whether or not you also got an application:openFile:, etc.

Know if the user launched an app

Alright, this title might seem strange, but bear with me. I have an app which can be set on its preferences by the user to launch at login. That means I can expect sometimes the app will be launched by the user (clicking on the Dock/Finder, etc), but some other times the app will be launched automatically by the system, on login.
I would like to show a window when the app is launched by the user, but not when it is launched automatically (as I imagine that would be a pain for the user). How can I do that?
Although it may depend on how you intend to automate the launch of the app, you could use command line arguments to distinguish between system launch vs. user launch.
So, the command line launch might like like this:
MyApp -autoLaunch "Y"
To parse the command line args in a Cocoa app, you could use NSUserDefaults (Yes, you can!):
if( ![[NSUserDefaults standardUserDefaults] objectForKey:#"autoLaunch"] isEqualToString:"Y"] ) {
// do something for user initiated launch
}
I don't have an exact answer to your question. However, may I suggest that your app should show the window if the window was visible when the user last quit your app?
This may be more in-line with the Mac UI guidelines' suggestion on restoring apps and windows, and is within the user's expectations.
Also, a user who set your app to launch at login will probably understand to close the window and not have it restored the next time, or make the system also hide your app during login.