NSDistributedNotificationCenter'i kasutamine Python Objective-C bridge'ga: Difference between revisions
(15 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Autor: Raido Aarop, A31 <br /> | Autor: Raido Aarop, A31 <br /> | ||
[[User:Raarop|Raarop]] | [[User:Raarop|Raarop]] 14:58, 3 April 2013 (EEST) | ||
=Sissejuhatus= | =Sissejuhatus= | ||
See artikkel toob näite kuidas saata ja vastu võtta protsesside | See artikkel toob näite kuidas saata ja vastu võtta protsesside vahelisi teated Apple OSX platvormil. Näite eesmärk on teha seda pythoni keeles ilma kasutamata OSX native Objective-C keelt. | ||
==NSDistributedNotificationCenter klass== | ==NSDistributedNotificationCenter klass== | ||
Klassi kaudu on võimalik Apple OSX operatsioonisüsteemis saata ja vastu võtta teateid(notifications) erinevate taskide vahel. Klass kuulub OSX Foundationi frameworki. | Klassi kaudu on võimalik Apple OSX operatsioonisüsteemis saata ja vastu võtta teateid(notifications) erinevate taskide vahel. Klass kuulub OSX Foundationi frameworki.<br> | ||
Kasutame meetodeid: | |||
addObserver:selector:name:object: ja postNotificationName:object:userInfo: | |||
==Python== | ==Python== | ||
Python on levinud ja lihtne | Python on levinud ja lihtne programeersimiskeel, mis toetab mitmeid operatsioonisüsteeme ja platvorme, kaasaarvatud OSX. | ||
==Python Objective-C bridge== | ==Python Objective-C bridge== | ||
PyObjC bridge loob silla Pythoni ja Objective-C programmeerimiskeele vahel. Selles näites kasutame PyObjC teeki et kasutada NSDistributedNotificationCenter klassi Pythonis. | PyObjC bridge loob silla Pythoni ja Objective-C programmeerimiskeele vahel. Selles näites kasutame PyObjC teeki et kasutada NSDistributedNotificationCenter klassi Pythonis. | ||
PyObjC on testitud ja toetab Pythoni versioone 2.7, 3.2 ja 3.3. Python 2.6 on ka toetatud, kuigi ei ole nii tihedalt testitud. Samuti on tihedalt toetatud ja testitud OSX 10.8 ja toetatud kõik OSX-id alates 10.5-est i386, x86_64 ja ppc arhitektuuriga. | PyObjC on testitud ja toetab Pythoni versioone 2.7, 3.2 ja 3.3. Python 2.6 on ka toetatud, kuigi ei ole nii tihedalt testitud. Samuti on tihedalt toetatud ja testitud OSX 10.8 ja toetatud kõik OSX-id alates 10.5-est i386, x86_64 ja ppc arhitektuuriga. | ||
=PyObjC installeerimine= | =PyObjC installeerimine= | ||
Selleks et PyObjC instaleerida on vaja kombilaatorit. Kõige lihtsam on tõmmata tasuta [https://itunes.apple.com/us/app/xcode/id497799835?mt=12 Xcode Mac App Store'st] | Selleks et PyObjC instaleerida on vaja kombilaatorit. Kõige lihtsam on tõmmata tasuta [https://itunes.apple.com/us/app/xcode/id497799835?mt=12 Xcode Mac App Store'st] | ||
Line 27: | Line 30: | ||
Seletame lahti näite aadressilt [http://stackoverflow.com/questions/1933107/how-do-you-listen-to-notifications-from-itunes-on-a-mac-using-the-nsdistributed http://stackoverflow.com/questions/1933107/how-do-you-listen-to-notifications-from-itunes-on-a-mac-using-the-nsdistributed] | Seletame lahti näite aadressilt [http://stackoverflow.com/questions/1933107/how-do-you-listen-to-notifications-from-itunes-on-a-mac-using-the-nsdistributed http://stackoverflow.com/questions/1933107/how-do-you-listen-to-notifications-from-itunes-on-a-mac-using-the-nsdistributed] | ||
< | <source lang="python"> | ||
#!/usr/bin/python | #!/usr/bin/python | ||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||
Line 60: | Line 63: | ||
#Paneme käima NSRunLoop(Foundation) main loop-i | #Paneme käima NSRunLoop(Foundation) main loop-i | ||
AppHelper.runConsoleEventLoop() | AppHelper.runConsoleEventLoop() | ||
</ | </source> | ||
Salvestame selle koodi faili ja käivitame pythoni. | Salvestame selle koodi faili ja käivitame pythoni. | ||
<pre> | <pre> | ||
$ python minufail.py | $ python minufail.py | ||
</pre> | </pre> | ||
Kui oleme faili käivitanud ja iTunes'is mõne loo mängima pannud peaks | Kui oleme faili käivitanud ja iTunes'is mõne loo mängima pannud peaks olema näha sarnane konsooli väljund. | ||
<pre> | <pre> | ||
2013-04-03 09:48:24.475 Python[5691:f07] Listening for new tunes.... | 2013-04-03 09:48:24.475 Python[5691:f07] Listening for new tunes.... | ||
{u'Album': u'Euphoria - Single', u'Store URL': u'itms://itunes.com/album?p=499907070&i=499907132', u'Skip Date': 2013-02-18 07:35:39 +0000, u'Track Number': 1, u'Album Artist': u'Loreen', u'Playlist PersistentID': 4943482652531679104L, u'Location': u'file://localhost/Users/raidoaarop/Music/iTunes/iTunes%20Media/Music/Loreen/Euphoria%20-%20Single/01%20Euphoria%20(Single%20Version).m4a', u'Album Rating Computed': 1, u'Disc Number': 1, u'Total Time': 181786L, u'Library PersistentID': -656295795960417891L, u'Track Count': 3, u'Genre': u'Dance', u'Play Count': 12, u'Rating Computed': True, u'Name': u'Euphoria (Single Version)', u'Artist': u'Loreen', u'Disc Count': 1, u'Player State': u'Playing', u'Album Rating': 0, u'Artwork Count': 1, u'PersistentID': -2268284955121644048L, u'Play Date': 2013-03-26 14:38:19 +0000, u'Skip Count': 1, u'Year': 2012L} | {u'Album': u'Euphoria - Single', u'Store URL': u'itms://itunes.com/album?p=499907070&i=499907132', u'Skip Date': 2013-02-18 07:35:39 +0000, u'Track Number': 1, u'Album Artist': u'Loreen', u'Playlist PersistentID': 4943482652531679104L, u'Location': u'file://localhost/Users/raidoaarop/Music/iTunes/iTunes%20Media/Music/Loreen/Euphoria%20-%20Single/01%20Euphoria%20(Single%20Version).m4a', u'Album Rating Computed': 1, u'Disc Number': 1, u'Total Time': 181786L, u'Library PersistentID': -656295795960417891L, u'Track Count': 3, u'Genre': u'Dance', u'Play Count': 12, u'Rating Computed': True, u'Name': u'Euphoria (Single Version)', u'Artist': u'Loreen', u'Disc Count': 1, u'Player State': u'Playing', u'Album Rating': 0, u'Artwork Count': 1, u'PersistentID': -2268284955121644048L, u'Play Date': 2013-03-26 14:38:19 +0000, u'Skip Count': 1, u'Year': 2012L} | ||
</pre> | </pre> | ||
Kuna me ei lisanud meetodit NSRunLoop-i peatamiseks, siis tuleb lõpetamsieks protsess lihtalt killida. Vastasel juhul jookseb NSRunLoop lõpmatult. | |||
=Näide 2. Oma ''notificationi'' saatmine ja vastu võtmine= | =Näide 2. Oma ''notificationi'' saatmine ja vastu võtmine= | ||
==Vastvõttev skript== | |||
<source lang=python> | |||
#!/usr/bin/python | |||
# -*- coding: utf-8 -*- | |||
import Foundation #Impordime Foundation teegi | |||
from AppKit import * #AppKit teegid ipordime kõik objektid | |||
from PyObjCTools import AppHelper #PyObjCTools teegist impordime AppHelperi klassi | |||
class main(NSObject): #Minu main klass | |||
def init(self): #Init meetod, mis kutsutakse välja klassi loomisel | |||
#Loome uue NSDistributedNotificationCenter objekti | |||
notificationCenter = Foundation.NSDistributedNotificationCenter.defaultCenter() | |||
#Lisame NSDistributedNotificationCenter objektile listeneri my.logNotification nimelise teate jaoks, mis kutsub välja myLogNotification meetodi | |||
notificationCenter.addObserver_selector_name_object_(self, 'myLogNotification:', 'my.logNotification',None) | |||
#Lisame NSDistributedNotificationCenter objektile listeneri my.stopNotification nimelise teate jaoks, mis kutsub välja myStopNotification meetodi | |||
notificationCenter.addObserver_selector_name_object_(self, 'myStopNotification:', 'my.stopNotification',None) | |||
#Paneme käima NSRunLoop(Foundation) main loop-i | |||
AppHelper.runConsoleEventLoop() | |||
def myLogNotification_(self, notification): | |||
#Otsime notificationiga kaasa tulnud dictionary-st stringi mis vastab võtmele logStringKey ja logime selle | |||
if notification.userInfo().objectForKey_("logStringKey"): | |||
logString = notification.userInfo().objectForKey_("logStringKey") | |||
logString = logString.encode('utf8') | |||
NSLog("my.logNotification vastu võetud, logStringKey: %s",logString) | |||
else: | |||
NSLog("my.logNotification vastu võetud, aga logStringKey puudub!") | |||
def myStopNotification_(self, notification): | |||
NSLog("my.stopNotification vastu võetud, lõpetan töö!") | |||
#Kutsume välja meetodi, mis lõpetab NSRunLoop-i | |||
AppHelper.stopEventLoop() | |||
if __name__ == "__main__": | |||
#Loome main klassi objekti | |||
main = main.new() | |||
</source> | |||
==Saatev skript== | |||
<source lang="python"> | |||
#!/usr/bin/python | |||
# -*- coding: utf-8 -*- | |||
import Foundation #Impordime Foundation teegi | |||
from AppKit import * #AppKit teegid ipordime kõik objektid | |||
from PyObjCTools import AppHelper #PyObjCTools teegist impordime AppHelperi klassi | |||
logString = "Tere Maailm!" #String mida saata koos notificationiga, see string lisatakse userInfo dictionary | |||
dictionary = NSMutableDictionary.alloc().init() #userInfo dictionary, mis saadetakse koos notificationiga | |||
dictionary.setObject_forKey_(logString,"logStringKey") #lisame logString userInfo dictionary-sse | |||
#Saadame notificationi nimega my.logNotification ja koos dictionary-ga | |||
Foundation.NSDistributedNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('my.logNotification', None,dictionary) | |||
NSLog("my.logNotification, logStringKey: %s saadetud",logString) | |||
#Saadame notificationi nimega my.stopNotification ilma dictionary-ta | |||
Foundation.NSDistributedNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('my.stopNotification', None,None) | |||
NSLog("my.stopNotification saadetud") | |||
</source> | |||
==Konsool== | |||
Kõigepealt käivitame vastuvõtva skript ja siis saatva skripti. Konsooli väljundid võiksi olla järgmised: | |||
<pre> | |||
$ python minu_vastuvottev_skript.py | |||
2013-04-03 14:40:32.346 Python[10108:f07] my.logNotification vastu võetud, logStringKey: Tere Maailm! | |||
2013-04-03 14:40:32.347 Python[10108:f07] my.stopNotification vastu võetud, lõpetan töö! | |||
$ | |||
</pre> | |||
<pre> | |||
$ python minu_saatev_skript.py | |||
2013-04-03 14:40:32.344 Python[10109:f07] my.logNotification, logStringKey: Tere Maailm! saadetud | |||
2013-04-03 14:40:32.345 Python[10109:f07] my.stopNotification saadetud | |||
$ | |||
</pre> | |||
=Allikad= | =Allikad= | ||
[https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDistributedNotificationCenter_Class/Reference/Reference.html NSDistributedNotificationCenter Class Reference]<br> | [https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDistributedNotificationCenter_Class/Reference/Reference.html NSDistributedNotificationCenter Class Reference]<br> |
Latest revision as of 15:14, 25 April 2013
Autor: Raido Aarop, A31
Raarop 14:58, 3 April 2013 (EEST)
Sissejuhatus
See artikkel toob näite kuidas saata ja vastu võtta protsesside vahelisi teated Apple OSX platvormil. Näite eesmärk on teha seda pythoni keeles ilma kasutamata OSX native Objective-C keelt.
NSDistributedNotificationCenter klass
Klassi kaudu on võimalik Apple OSX operatsioonisüsteemis saata ja vastu võtta teateid(notifications) erinevate taskide vahel. Klass kuulub OSX Foundationi frameworki.
Kasutame meetodeid:
addObserver:selector:name:object: ja postNotificationName:object:userInfo:
Python
Python on levinud ja lihtne programeersimiskeel, mis toetab mitmeid operatsioonisüsteeme ja platvorme, kaasaarvatud OSX.
Python Objective-C bridge
PyObjC bridge loob silla Pythoni ja Objective-C programmeerimiskeele vahel. Selles näites kasutame PyObjC teeki et kasutada NSDistributedNotificationCenter klassi Pythonis. PyObjC on testitud ja toetab Pythoni versioone 2.7, 3.2 ja 3.3. Python 2.6 on ka toetatud, kuigi ei ole nii tihedalt testitud. Samuti on tihedalt toetatud ja testitud OSX 10.8 ja toetatud kõik OSX-id alates 10.5-est i386, x86_64 ja ppc arhitektuuriga.
PyObjC installeerimine
Selleks et PyObjC instaleerida on vaja kombilaatorit. Kõige lihtsam on tõmmata tasuta Xcode Mac App Store'st
Mõnel juhul on vaja installeerida Xcode lisa Command Line Tools. Main Menu -> Preferences -> Components
PyObjC on võimalik installeerida kasutades pythoni teegihaldureid easy_install-i või pip-i. On olemas käsitsi variant, selle kohta saab rohkem infot siit.
Selles artiklis kasutame easy_install-i, mis peaks olema kaasas OSX Pythoni vaikimisi versiooniga.
Et teha protsess kiiremaks teeme seda kahe käsuga.
$ sudo easy_install -U pyobjc-core $ sudo easy_install -U pyobjc-framework-Cocoa
Näide 1: iTunes'i notificationi vastu võtmine.
Seletame lahti näite aadressilt http://stackoverflow.com/questions/1933107/how-do-you-listen-to-notifications-from-itunes-on-a-mac-using-the-nsdistributed
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Foundation #Impordime Foundation teegi
from AppKit import * #AppKit teegid ipordime kõik objektid
from PyObjCTools import AppHelper #PyObjCTools teegist impordime AppHelperi klassi
#Kirjeldame klassi ja ühe meetodi notification vastu võtmiseks
class GetSongs(NSObject):
def getMySongs_(self, song):
#Prindime välja notificationiga saabunud dictonary(song) sisu, mis selle näite puhul sisaldab loo infot.
song_details = {}
ui = song.userInfo()
for x in ui:
song_details[x] = ui.objectForKey_(x)
print song_details
#Loome uue NSDistributedNotificationCenter objekti
nc = Foundation.NSDistributedNotificationCenter.defaultCenter()
#Loome oma klassi objekti
GetSongs = GetSongs.new()
#Lisame NSDistributedNotificationCenter objektile listeneri
#Listeneris defneerime klassi ja meetodi(GetSongs, 'getMySongs:') mida selle notification puhul välja kutsuda, samuti event-i nime(com.apple.iTunes.playerInfo) mida me ootame.
nc.addObserver_selector_name_object_(GetSongs, 'getMySongs:', 'com.apple.iTunes.playerInfo',None)
NSLog("Listening for new tunes....") #Foundation-i logimise meetod
#Paneme käima NSRunLoop(Foundation) main loop-i
AppHelper.runConsoleEventLoop()
Salvestame selle koodi faili ja käivitame pythoni.
$ python minufail.py
Kui oleme faili käivitanud ja iTunes'is mõne loo mängima pannud peaks olema näha sarnane konsooli väljund.
2013-04-03 09:48:24.475 Python[5691:f07] Listening for new tunes.... {u'Album': u'Euphoria - Single', u'Store URL': u'itms://itunes.com/album?p=499907070&i=499907132', u'Skip Date': 2013-02-18 07:35:39 +0000, u'Track Number': 1, u'Album Artist': u'Loreen', u'Playlist PersistentID': 4943482652531679104L, u'Location': u'file://localhost/Users/raidoaarop/Music/iTunes/iTunes%20Media/Music/Loreen/Euphoria%20-%20Single/01%20Euphoria%20(Single%20Version).m4a', u'Album Rating Computed': 1, u'Disc Number': 1, u'Total Time': 181786L, u'Library PersistentID': -656295795960417891L, u'Track Count': 3, u'Genre': u'Dance', u'Play Count': 12, u'Rating Computed': True, u'Name': u'Euphoria (Single Version)', u'Artist': u'Loreen', u'Disc Count': 1, u'Player State': u'Playing', u'Album Rating': 0, u'Artwork Count': 1, u'PersistentID': -2268284955121644048L, u'Play Date': 2013-03-26 14:38:19 +0000, u'Skip Count': 1, u'Year': 2012L}
Kuna me ei lisanud meetodit NSRunLoop-i peatamiseks, siis tuleb lõpetamsieks protsess lihtalt killida. Vastasel juhul jookseb NSRunLoop lõpmatult.
Näide 2. Oma notificationi saatmine ja vastu võtmine
Vastvõttev skript
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Foundation #Impordime Foundation teegi
from AppKit import * #AppKit teegid ipordime kõik objektid
from PyObjCTools import AppHelper #PyObjCTools teegist impordime AppHelperi klassi
class main(NSObject): #Minu main klass
def init(self): #Init meetod, mis kutsutakse välja klassi loomisel
#Loome uue NSDistributedNotificationCenter objekti
notificationCenter = Foundation.NSDistributedNotificationCenter.defaultCenter()
#Lisame NSDistributedNotificationCenter objektile listeneri my.logNotification nimelise teate jaoks, mis kutsub välja myLogNotification meetodi
notificationCenter.addObserver_selector_name_object_(self, 'myLogNotification:', 'my.logNotification',None)
#Lisame NSDistributedNotificationCenter objektile listeneri my.stopNotification nimelise teate jaoks, mis kutsub välja myStopNotification meetodi
notificationCenter.addObserver_selector_name_object_(self, 'myStopNotification:', 'my.stopNotification',None)
#Paneme käima NSRunLoop(Foundation) main loop-i
AppHelper.runConsoleEventLoop()
def myLogNotification_(self, notification):
#Otsime notificationiga kaasa tulnud dictionary-st stringi mis vastab võtmele logStringKey ja logime selle
if notification.userInfo().objectForKey_("logStringKey"):
logString = notification.userInfo().objectForKey_("logStringKey")
logString = logString.encode('utf8')
NSLog("my.logNotification vastu võetud, logStringKey: %s",logString)
else:
NSLog("my.logNotification vastu võetud, aga logStringKey puudub!")
def myStopNotification_(self, notification):
NSLog("my.stopNotification vastu võetud, lõpetan töö!")
#Kutsume välja meetodi, mis lõpetab NSRunLoop-i
AppHelper.stopEventLoop()
if __name__ == "__main__":
#Loome main klassi objekti
main = main.new()
Saatev skript
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Foundation #Impordime Foundation teegi
from AppKit import * #AppKit teegid ipordime kõik objektid
from PyObjCTools import AppHelper #PyObjCTools teegist impordime AppHelperi klassi
logString = "Tere Maailm!" #String mida saata koos notificationiga, see string lisatakse userInfo dictionary
dictionary = NSMutableDictionary.alloc().init() #userInfo dictionary, mis saadetakse koos notificationiga
dictionary.setObject_forKey_(logString,"logStringKey") #lisame logString userInfo dictionary-sse
#Saadame notificationi nimega my.logNotification ja koos dictionary-ga
Foundation.NSDistributedNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('my.logNotification', None,dictionary)
NSLog("my.logNotification, logStringKey: %s saadetud",logString)
#Saadame notificationi nimega my.stopNotification ilma dictionary-ta
Foundation.NSDistributedNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('my.stopNotification', None,None)
NSLog("my.stopNotification saadetud")
Konsool
Kõigepealt käivitame vastuvõtva skript ja siis saatva skripti. Konsooli väljundid võiksi olla järgmised:
$ python minu_vastuvottev_skript.py 2013-04-03 14:40:32.346 Python[10108:f07] my.logNotification vastu võetud, logStringKey: Tere Maailm! 2013-04-03 14:40:32.347 Python[10108:f07] my.stopNotification vastu võetud, lõpetan töö! $
$ python minu_saatev_skript.py 2013-04-03 14:40:32.344 Python[10109:f07] my.logNotification, logStringKey: Tere Maailm! saadetud 2013-04-03 14:40:32.345 Python[10109:f07] my.stopNotification saadetud $
Allikad
NSDistributedNotificationCenter Class Reference
Python
Pyobjc
Näide 1